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-2025, 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 : #define NUMERIC_DEBUG
52 : */
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_opt_error(const NumericVar *var, bool *have_error);
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 163516 : numeric_in(PG_FUNCTION_ARGS)
627 : {
628 163516 : char *str = PG_GETARG_CSTRING(0);
629 : #ifdef NOT_USED
630 : Oid typelem = PG_GETARG_OID(1);
631 : #endif
632 163516 : int32 typmod = PG_GETARG_INT32(2);
633 163516 : Node *escontext = fcinfo->context;
634 : Numeric res;
635 : const char *cp;
636 : const char *numstart;
637 : int sign;
638 :
639 : /* Skip leading spaces */
640 163516 : cp = str;
641 187936 : while (*cp)
642 : {
643 187918 : if (!isspace((unsigned char) *cp))
644 163498 : break;
645 24420 : 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 163516 : numstart = cp;
654 163516 : sign = NUMERIC_POS;
655 :
656 163516 : if (*cp == '+')
657 48 : cp++;
658 163468 : else if (*cp == '-')
659 : {
660 4092 : sign = NUMERIC_NEG;
661 4092 : 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 163516 : 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 1796 : if (pg_strncasecmp(numstart, "NaN", 3) == 0)
678 : {
679 606 : res = make_result(&const_nan);
680 606 : cp = numstart + 3;
681 : }
682 1190 : else if (pg_strncasecmp(cp, "Infinity", 8) == 0)
683 : {
684 492 : res = make_result(sign == NUMERIC_POS ? &const_pinf : &const_ninf);
685 492 : cp += 8;
686 : }
687 698 : else if (pg_strncasecmp(cp, "inf", 3) == 0)
688 : {
689 588 : res = make_result(sign == NUMERIC_POS ? &const_pinf : &const_ninf);
690 588 : cp += 3;
691 : }
692 : else
693 110 : 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 1728 : while (*cp)
703 : {
704 42 : if (!isspace((unsigned char) *cp))
705 0 : goto invalid_syntax;
706 42 : cp++;
707 : }
708 :
709 1686 : 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 : bool have_error;
721 :
722 161720 : init_var(&value);
723 :
724 : /*
725 : * Determine the number's base by looking for a non-decimal prefix
726 : * indicator ("0x", "0o", or "0b").
727 : */
728 161720 : if (cp[0] == '0')
729 : {
730 49628 : switch (cp[1])
731 : {
732 72 : case 'x':
733 : case 'X':
734 72 : base = 16;
735 72 : break;
736 42 : case 'o':
737 : case 'O':
738 42 : base = 8;
739 42 : break;
740 42 : case 'b':
741 : case 'B':
742 42 : base = 2;
743 42 : break;
744 49472 : default:
745 49472 : base = 10;
746 : }
747 : }
748 : else
749 112092 : base = 10;
750 :
751 : /* Parse the rest of the number and apply the sign */
752 161720 : if (base == 10)
753 : {
754 161564 : if (!set_var_from_str(str, cp, &value, &cp, escontext))
755 42 : PG_RETURN_NULL();
756 161516 : value.sign = sign;
757 : }
758 : else
759 : {
760 156 : if (!set_var_from_non_decimal_integer_str(str, cp + 2, sign, base,
761 : &value, &cp, escontext))
762 0 : PG_RETURN_NULL();
763 : }
764 :
765 : /*
766 : * Should be nothing left but spaces. As above, throw any typmod error
767 : * after finishing syntax check.
768 : */
769 161732 : while (*cp)
770 : {
771 150 : if (!isspace((unsigned char) *cp))
772 72 : goto invalid_syntax;
773 78 : cp++;
774 : }
775 :
776 161582 : if (!apply_typmod(&value, typmod, escontext))
777 24 : PG_RETURN_NULL();
778 :
779 161558 : res = make_result_opt_error(&value, &have_error);
780 :
781 161558 : if (have_error)
782 18 : ereturn(escontext, (Datum) 0,
783 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
784 : errmsg("value overflows numeric format")));
785 :
786 161540 : free_var(&value);
787 : }
788 :
789 163226 : PG_RETURN_NUMERIC(res);
790 :
791 182 : invalid_syntax:
792 182 : ereturn(escontext, (Datum) 0,
793 : (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
794 : errmsg("invalid input syntax for type %s: \"%s\"",
795 : "numeric", str)));
796 : }
797 :
798 :
799 : /*
800 : * numeric_out() -
801 : *
802 : * Output function for numeric data type
803 : */
804 : Datum
805 851658 : numeric_out(PG_FUNCTION_ARGS)
806 : {
807 851658 : Numeric num = PG_GETARG_NUMERIC(0);
808 : NumericVar x;
809 : char *str;
810 :
811 : /*
812 : * Handle NaN and infinities
813 : */
814 851658 : if (NUMERIC_IS_SPECIAL(num))
815 : {
816 3612 : if (NUMERIC_IS_PINF(num))
817 1040 : PG_RETURN_CSTRING(pstrdup("Infinity"));
818 2572 : else if (NUMERIC_IS_NINF(num))
819 658 : PG_RETURN_CSTRING(pstrdup("-Infinity"));
820 : else
821 1914 : PG_RETURN_CSTRING(pstrdup("NaN"));
822 : }
823 :
824 : /*
825 : * Get the number in the variable format.
826 : */
827 848046 : init_var_from_num(num, &x);
828 :
829 848046 : str = get_str_from_var(&x);
830 :
831 848046 : PG_RETURN_CSTRING(str);
832 : }
833 :
834 : /*
835 : * numeric_is_nan() -
836 : *
837 : * Is Numeric value a NaN?
838 : */
839 : bool
840 7554 : numeric_is_nan(Numeric num)
841 : {
842 7554 : return NUMERIC_IS_NAN(num);
843 : }
844 :
845 : /*
846 : * numeric_is_inf() -
847 : *
848 : * Is Numeric value an infinity?
849 : */
850 : bool
851 312 : numeric_is_inf(Numeric num)
852 : {
853 312 : return NUMERIC_IS_INF(num);
854 : }
855 :
856 : /*
857 : * numeric_is_integral() -
858 : *
859 : * Is Numeric value integral?
860 : */
861 : static bool
862 66 : numeric_is_integral(Numeric num)
863 : {
864 : NumericVar arg;
865 :
866 : /* Reject NaN, but infinities are considered integral */
867 66 : if (NUMERIC_IS_SPECIAL(num))
868 : {
869 30 : if (NUMERIC_IS_NAN(num))
870 0 : return false;
871 30 : return true;
872 : }
873 :
874 : /* Integral if there are no digits to the right of the decimal point */
875 36 : init_var_from_num(num, &arg);
876 :
877 36 : return (arg.ndigits == 0 || arg.ndigits <= arg.weight + 1);
878 : }
879 :
880 : /*
881 : * make_numeric_typmod() -
882 : *
883 : * Pack numeric precision and scale values into a typmod. The upper 16 bits
884 : * are used for the precision (though actually not all these bits are needed,
885 : * since the maximum allowed precision is 1000). The lower 16 bits are for
886 : * the scale, but since the scale is constrained to the range [-1000, 1000],
887 : * we use just the lower 11 of those 16 bits, and leave the remaining 5 bits
888 : * unset, for possible future use.
889 : *
890 : * For purely historical reasons VARHDRSZ is then added to the result, thus
891 : * the unused space in the upper 16 bits is not all as freely available as it
892 : * might seem. (We can't let the result overflow to a negative int32, as
893 : * other parts of the system would interpret that as not-a-valid-typmod.)
894 : */
895 : static inline int32
896 1894 : make_numeric_typmod(int precision, int scale)
897 : {
898 1894 : return ((precision << 16) | (scale & 0x7ff)) + VARHDRSZ;
899 : }
900 :
901 : /*
902 : * Because of the offset, valid numeric typmods are at least VARHDRSZ
903 : */
904 : static inline bool
905 186614 : is_valid_numeric_typmod(int32 typmod)
906 : {
907 186614 : return typmod >= (int32) VARHDRSZ;
908 : }
909 :
910 : /*
911 : * numeric_typmod_precision() -
912 : *
913 : * Extract the precision from a numeric typmod --- see make_numeric_typmod().
914 : */
915 : static inline int
916 48618 : numeric_typmod_precision(int32 typmod)
917 : {
918 48618 : return ((typmod - VARHDRSZ) >> 16) & 0xffff;
919 : }
920 :
921 : /*
922 : * numeric_typmod_scale() -
923 : *
924 : * Extract the scale from a numeric typmod --- see make_numeric_typmod().
925 : *
926 : * Note that the scale may be negative, so we must do sign extension when
927 : * unpacking it. We do this using the bit hack (x^1024)-1024, which sign
928 : * extends an 11-bit two's complement number x.
929 : */
930 : static inline int
931 41524 : numeric_typmod_scale(int32 typmod)
932 : {
933 41524 : return (((typmod - VARHDRSZ) & 0x7ff) ^ 1024) - 1024;
934 : }
935 :
936 : /*
937 : * numeric_maximum_size() -
938 : *
939 : * Maximum size of a numeric with given typmod, or -1 if unlimited/unknown.
940 : */
941 : int32
942 7094 : numeric_maximum_size(int32 typmod)
943 : {
944 : int precision;
945 : int numeric_digits;
946 :
947 7094 : if (!is_valid_numeric_typmod(typmod))
948 0 : return -1;
949 :
950 : /* precision (ie, max # of digits) is in upper bits of typmod */
951 7094 : precision = numeric_typmod_precision(typmod);
952 :
953 : /*
954 : * This formula computes the maximum number of NumericDigits we could need
955 : * in order to store the specified number of decimal digits. Because the
956 : * weight is stored as a number of NumericDigits rather than a number of
957 : * decimal digits, it's possible that the first NumericDigit will contain
958 : * only a single decimal digit. Thus, the first two decimal digits can
959 : * require two NumericDigits to store, but it isn't until we reach
960 : * DEC_DIGITS + 2 decimal digits that we potentially need a third
961 : * NumericDigit.
962 : */
963 7094 : numeric_digits = (precision + 2 * (DEC_DIGITS - 1)) / DEC_DIGITS;
964 :
965 : /*
966 : * In most cases, the size of a numeric will be smaller than the value
967 : * computed below, because the varlena header will typically get toasted
968 : * down to a single byte before being stored on disk, and it may also be
969 : * possible to use a short numeric header. But our job here is to compute
970 : * the worst case.
971 : */
972 7094 : return NUMERIC_HDRSZ + (numeric_digits * sizeof(NumericDigit));
973 : }
974 :
975 : /*
976 : * numeric_out_sci() -
977 : *
978 : * Output function for numeric data type in scientific notation.
979 : */
980 : char *
981 246 : numeric_out_sci(Numeric num, int scale)
982 : {
983 : NumericVar x;
984 : char *str;
985 :
986 : /*
987 : * Handle NaN and infinities
988 : */
989 246 : if (NUMERIC_IS_SPECIAL(num))
990 : {
991 18 : if (NUMERIC_IS_PINF(num))
992 6 : return pstrdup("Infinity");
993 12 : else if (NUMERIC_IS_NINF(num))
994 6 : return pstrdup("-Infinity");
995 : else
996 6 : return pstrdup("NaN");
997 : }
998 :
999 228 : init_var_from_num(num, &x);
1000 :
1001 228 : str = get_str_from_var_sci(&x, scale);
1002 :
1003 228 : return str;
1004 : }
1005 :
1006 : /*
1007 : * numeric_normalize() -
1008 : *
1009 : * Output function for numeric data type, suppressing insignificant trailing
1010 : * zeroes and then any trailing decimal point. The intent of this is to
1011 : * produce strings that are equal if and only if the input numeric values
1012 : * compare equal.
1013 : */
1014 : char *
1015 36110 : numeric_normalize(Numeric num)
1016 : {
1017 : NumericVar x;
1018 : char *str;
1019 : int last;
1020 :
1021 : /*
1022 : * Handle NaN and infinities
1023 : */
1024 36110 : if (NUMERIC_IS_SPECIAL(num))
1025 : {
1026 0 : if (NUMERIC_IS_PINF(num))
1027 0 : return pstrdup("Infinity");
1028 0 : else if (NUMERIC_IS_NINF(num))
1029 0 : return pstrdup("-Infinity");
1030 : else
1031 0 : return pstrdup("NaN");
1032 : }
1033 :
1034 36110 : init_var_from_num(num, &x);
1035 :
1036 36110 : str = get_str_from_var(&x);
1037 :
1038 : /* If there's no decimal point, there's certainly nothing to remove. */
1039 36110 : if (strchr(str, '.') != NULL)
1040 : {
1041 : /*
1042 : * Back up over trailing fractional zeroes. Since there is a decimal
1043 : * point, this loop will terminate safely.
1044 : */
1045 42 : last = strlen(str) - 1;
1046 84 : while (str[last] == '0')
1047 42 : last--;
1048 :
1049 : /* We want to get rid of the decimal point too, if it's now last. */
1050 42 : if (str[last] == '.')
1051 42 : last--;
1052 :
1053 : /* Delete whatever we backed up over. */
1054 42 : str[last + 1] = '\0';
1055 : }
1056 :
1057 36110 : return str;
1058 : }
1059 :
1060 : /*
1061 : * numeric_recv - converts external binary format to numeric
1062 : *
1063 : * External format is a sequence of int16's:
1064 : * ndigits, weight, sign, dscale, NumericDigits.
1065 : */
1066 : Datum
1067 102 : numeric_recv(PG_FUNCTION_ARGS)
1068 : {
1069 102 : StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
1070 :
1071 : #ifdef NOT_USED
1072 : Oid typelem = PG_GETARG_OID(1);
1073 : #endif
1074 102 : int32 typmod = PG_GETARG_INT32(2);
1075 : NumericVar value;
1076 : Numeric res;
1077 : int len,
1078 : i;
1079 :
1080 102 : init_var(&value);
1081 :
1082 102 : len = (uint16) pq_getmsgint(buf, sizeof(uint16));
1083 :
1084 102 : alloc_var(&value, len);
1085 :
1086 102 : value.weight = (int16) pq_getmsgint(buf, sizeof(int16));
1087 : /* we allow any int16 for weight --- OK? */
1088 :
1089 102 : value.sign = (uint16) pq_getmsgint(buf, sizeof(uint16));
1090 102 : if (!(value.sign == NUMERIC_POS ||
1091 0 : value.sign == NUMERIC_NEG ||
1092 0 : value.sign == NUMERIC_NAN ||
1093 0 : value.sign == NUMERIC_PINF ||
1094 0 : value.sign == NUMERIC_NINF))
1095 0 : ereport(ERROR,
1096 : (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1097 : errmsg("invalid sign in external \"numeric\" value")));
1098 :
1099 102 : value.dscale = (uint16) pq_getmsgint(buf, sizeof(uint16));
1100 102 : if ((value.dscale & NUMERIC_DSCALE_MASK) != value.dscale)
1101 0 : ereport(ERROR,
1102 : (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1103 : errmsg("invalid scale in external \"numeric\" value")));
1104 :
1105 274 : for (i = 0; i < len; i++)
1106 : {
1107 172 : NumericDigit d = pq_getmsgint(buf, sizeof(NumericDigit));
1108 :
1109 172 : if (d < 0 || d >= NBASE)
1110 0 : ereport(ERROR,
1111 : (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1112 : errmsg("invalid digit in external \"numeric\" value")));
1113 172 : value.digits[i] = d;
1114 : }
1115 :
1116 : /*
1117 : * If the given dscale would hide any digits, truncate those digits away.
1118 : * We could alternatively throw an error, but that would take a bunch of
1119 : * extra code (about as much as trunc_var involves), and it might cause
1120 : * client compatibility issues. Be careful not to apply trunc_var to
1121 : * special values, as it could do the wrong thing; we don't need it
1122 : * anyway, since make_result will ignore all but the sign field.
1123 : *
1124 : * After doing that, be sure to check the typmod restriction.
1125 : */
1126 102 : if (value.sign == NUMERIC_POS ||
1127 0 : value.sign == NUMERIC_NEG)
1128 : {
1129 102 : trunc_var(&value, value.dscale);
1130 :
1131 102 : (void) apply_typmod(&value, typmod, NULL);
1132 :
1133 102 : res = make_result(&value);
1134 : }
1135 : else
1136 : {
1137 : /* apply_typmod_special wants us to make the Numeric first */
1138 0 : res = make_result(&value);
1139 :
1140 0 : (void) apply_typmod_special(res, typmod, NULL);
1141 : }
1142 :
1143 102 : free_var(&value);
1144 :
1145 102 : PG_RETURN_NUMERIC(res);
1146 : }
1147 :
1148 : /*
1149 : * numeric_send - converts numeric to binary format
1150 : */
1151 : Datum
1152 70 : numeric_send(PG_FUNCTION_ARGS)
1153 : {
1154 70 : Numeric num = PG_GETARG_NUMERIC(0);
1155 : NumericVar x;
1156 : StringInfoData buf;
1157 : int i;
1158 :
1159 70 : init_var_from_num(num, &x);
1160 :
1161 70 : pq_begintypsend(&buf);
1162 :
1163 70 : pq_sendint16(&buf, x.ndigits);
1164 70 : pq_sendint16(&buf, x.weight);
1165 70 : pq_sendint16(&buf, x.sign);
1166 70 : pq_sendint16(&buf, x.dscale);
1167 194 : for (i = 0; i < x.ndigits; i++)
1168 124 : pq_sendint16(&buf, x.digits[i]);
1169 :
1170 70 : PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
1171 : }
1172 :
1173 :
1174 : /*
1175 : * numeric_support()
1176 : *
1177 : * Planner support function for the numeric() length coercion function.
1178 : *
1179 : * Flatten calls that solely represent increases in allowable precision.
1180 : * Scale changes mutate every datum, so they are unoptimizable. Some values,
1181 : * e.g. 1E-1001, can only fit into an unconstrained numeric, so a change from
1182 : * an unconstrained numeric to any constrained numeric is also unoptimizable.
1183 : */
1184 : Datum
1185 516 : numeric_support(PG_FUNCTION_ARGS)
1186 : {
1187 516 : Node *rawreq = (Node *) PG_GETARG_POINTER(0);
1188 516 : Node *ret = NULL;
1189 :
1190 516 : if (IsA(rawreq, SupportRequestSimplify))
1191 : {
1192 228 : SupportRequestSimplify *req = (SupportRequestSimplify *) rawreq;
1193 228 : FuncExpr *expr = req->fcall;
1194 : Node *typmod;
1195 :
1196 : Assert(list_length(expr->args) >= 2);
1197 :
1198 228 : typmod = (Node *) lsecond(expr->args);
1199 :
1200 228 : if (IsA(typmod, Const) && !((Const *) typmod)->constisnull)
1201 : {
1202 228 : Node *source = (Node *) linitial(expr->args);
1203 228 : int32 old_typmod = exprTypmod(source);
1204 228 : int32 new_typmod = DatumGetInt32(((Const *) typmod)->constvalue);
1205 228 : int32 old_scale = numeric_typmod_scale(old_typmod);
1206 228 : int32 new_scale = numeric_typmod_scale(new_typmod);
1207 228 : int32 old_precision = numeric_typmod_precision(old_typmod);
1208 228 : int32 new_precision = numeric_typmod_precision(new_typmod);
1209 :
1210 : /*
1211 : * If new_typmod is invalid, the destination is unconstrained;
1212 : * that's always OK. If old_typmod is valid, the source is
1213 : * constrained, and we're OK if the scale is unchanged and the
1214 : * precision is not decreasing. See further notes in function
1215 : * header comment.
1216 : */
1217 456 : if (!is_valid_numeric_typmod(new_typmod) ||
1218 240 : (is_valid_numeric_typmod(old_typmod) &&
1219 6 : new_scale == old_scale && new_precision >= old_precision))
1220 6 : ret = relabel_to_typmod(source, new_typmod);
1221 : }
1222 : }
1223 :
1224 516 : PG_RETURN_POINTER(ret);
1225 : }
1226 :
1227 : /*
1228 : * numeric() -
1229 : *
1230 : * This is a special function called by the Postgres database system
1231 : * before a value is stored in a tuple's attribute. The precision and
1232 : * scale of the attribute have to be applied on the value.
1233 : */
1234 : Datum
1235 11730 : numeric (PG_FUNCTION_ARGS)
1236 : {
1237 11730 : Numeric num = PG_GETARG_NUMERIC(0);
1238 11730 : int32 typmod = PG_GETARG_INT32(1);
1239 : Numeric new;
1240 : int precision;
1241 : int scale;
1242 : int ddigits;
1243 : int maxdigits;
1244 : int dscale;
1245 : NumericVar var;
1246 :
1247 : /*
1248 : * Handle NaN and infinities: if apply_typmod_special doesn't complain,
1249 : * just return a copy of the input.
1250 : */
1251 11730 : if (NUMERIC_IS_SPECIAL(num))
1252 : {
1253 210 : (void) apply_typmod_special(num, typmod, NULL);
1254 192 : PG_RETURN_NUMERIC(duplicate_numeric(num));
1255 : }
1256 :
1257 : /*
1258 : * If the value isn't a valid type modifier, simply return a copy of the
1259 : * input value
1260 : */
1261 11520 : if (!is_valid_numeric_typmod(typmod))
1262 0 : PG_RETURN_NUMERIC(duplicate_numeric(num));
1263 :
1264 : /*
1265 : * Get the precision and scale out of the typmod value
1266 : */
1267 11520 : precision = numeric_typmod_precision(typmod);
1268 11520 : scale = numeric_typmod_scale(typmod);
1269 11520 : maxdigits = precision - scale;
1270 :
1271 : /* The target display scale is non-negative */
1272 11520 : dscale = Max(scale, 0);
1273 :
1274 : /*
1275 : * If the number is certainly in bounds and due to the target scale no
1276 : * rounding could be necessary, just make a copy of the input and modify
1277 : * its scale fields, unless the larger scale forces us to abandon the
1278 : * short representation. (Note we assume the existing dscale is
1279 : * honest...)
1280 : */
1281 11520 : ddigits = (NUMERIC_WEIGHT(num) + 1) * DEC_DIGITS;
1282 11520 : if (ddigits <= maxdigits && scale >= NUMERIC_DSCALE(num)
1283 7134 : && (NUMERIC_CAN_BE_SHORT(dscale, NUMERIC_WEIGHT(num))
1284 0 : || !NUMERIC_IS_SHORT(num)))
1285 : {
1286 7134 : new = duplicate_numeric(num);
1287 7134 : if (NUMERIC_IS_SHORT(num))
1288 7134 : new->choice.n_short.n_header =
1289 7134 : (num->choice.n_short.n_header & ~NUMERIC_SHORT_DSCALE_MASK)
1290 7134 : | (dscale << NUMERIC_SHORT_DSCALE_SHIFT);
1291 : else
1292 0 : new->choice.n_long.n_sign_dscale = NUMERIC_SIGN(new) |
1293 0 : ((uint16) dscale & NUMERIC_DSCALE_MASK);
1294 7134 : PG_RETURN_NUMERIC(new);
1295 : }
1296 :
1297 : /*
1298 : * We really need to fiddle with things - unpack the number into a
1299 : * variable and let apply_typmod() do it.
1300 : */
1301 4386 : init_var(&var);
1302 :
1303 4386 : set_var_from_num(num, &var);
1304 4386 : (void) apply_typmod(&var, typmod, NULL);
1305 4326 : new = make_result(&var);
1306 :
1307 4326 : free_var(&var);
1308 :
1309 4326 : PG_RETURN_NUMERIC(new);
1310 : }
1311 :
1312 : Datum
1313 1936 : numerictypmodin(PG_FUNCTION_ARGS)
1314 : {
1315 1936 : ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
1316 : int32 *tl;
1317 : int n;
1318 : int32 typmod;
1319 :
1320 1936 : tl = ArrayGetIntegerTypmods(ta, &n);
1321 :
1322 1936 : if (n == 2)
1323 : {
1324 1916 : if (tl[0] < 1 || tl[0] > NUMERIC_MAX_PRECISION)
1325 18 : ereport(ERROR,
1326 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1327 : errmsg("NUMERIC precision %d must be between 1 and %d",
1328 : tl[0], NUMERIC_MAX_PRECISION)));
1329 1898 : if (tl[1] < NUMERIC_MIN_SCALE || tl[1] > NUMERIC_MAX_SCALE)
1330 12 : ereport(ERROR,
1331 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1332 : errmsg("NUMERIC scale %d must be between %d and %d",
1333 : tl[1], NUMERIC_MIN_SCALE, NUMERIC_MAX_SCALE)));
1334 1886 : typmod = make_numeric_typmod(tl[0], tl[1]);
1335 : }
1336 20 : else if (n == 1)
1337 : {
1338 8 : if (tl[0] < 1 || tl[0] > NUMERIC_MAX_PRECISION)
1339 0 : ereport(ERROR,
1340 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1341 : errmsg("NUMERIC precision %d must be between 1 and %d",
1342 : tl[0], NUMERIC_MAX_PRECISION)));
1343 : /* scale defaults to zero */
1344 8 : typmod = make_numeric_typmod(tl[0], 0);
1345 : }
1346 : else
1347 : {
1348 12 : ereport(ERROR,
1349 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1350 : errmsg("invalid NUMERIC type modifier")));
1351 : typmod = 0; /* keep compiler quiet */
1352 : }
1353 :
1354 1894 : PG_RETURN_INT32(typmod);
1355 : }
1356 :
1357 : Datum
1358 376 : numerictypmodout(PG_FUNCTION_ARGS)
1359 : {
1360 376 : int32 typmod = PG_GETARG_INT32(0);
1361 376 : char *res = (char *) palloc(64);
1362 :
1363 376 : if (is_valid_numeric_typmod(typmod))
1364 376 : snprintf(res, 64, "(%d,%d)",
1365 : numeric_typmod_precision(typmod),
1366 : numeric_typmod_scale(typmod));
1367 : else
1368 0 : *res = '\0';
1369 :
1370 376 : PG_RETURN_CSTRING(res);
1371 : }
1372 :
1373 :
1374 : /* ----------------------------------------------------------------------
1375 : *
1376 : * Sign manipulation, rounding and the like
1377 : *
1378 : * ----------------------------------------------------------------------
1379 : */
1380 :
1381 : Datum
1382 19506 : numeric_abs(PG_FUNCTION_ARGS)
1383 : {
1384 19506 : Numeric num = PG_GETARG_NUMERIC(0);
1385 : Numeric res;
1386 :
1387 : /*
1388 : * Do it the easy way directly on the packed format
1389 : */
1390 19506 : res = duplicate_numeric(num);
1391 :
1392 19506 : if (NUMERIC_IS_SHORT(num))
1393 19440 : res->choice.n_short.n_header =
1394 19440 : num->choice.n_short.n_header & ~NUMERIC_SHORT_SIGN_MASK;
1395 66 : else if (NUMERIC_IS_SPECIAL(num))
1396 : {
1397 : /* This changes -Inf to Inf, and doesn't affect NaN */
1398 18 : res->choice.n_short.n_header =
1399 18 : num->choice.n_short.n_header & ~NUMERIC_INF_SIGN_MASK;
1400 : }
1401 : else
1402 48 : res->choice.n_long.n_sign_dscale = NUMERIC_POS | NUMERIC_DSCALE(num);
1403 :
1404 19506 : PG_RETURN_NUMERIC(res);
1405 : }
1406 :
1407 :
1408 : Datum
1409 884 : numeric_uminus(PG_FUNCTION_ARGS)
1410 : {
1411 884 : Numeric num = PG_GETARG_NUMERIC(0);
1412 : Numeric res;
1413 :
1414 : /*
1415 : * Do it the easy way directly on the packed format
1416 : */
1417 884 : res = duplicate_numeric(num);
1418 :
1419 884 : if (NUMERIC_IS_SPECIAL(num))
1420 : {
1421 : /* Flip the sign, if it's Inf or -Inf */
1422 126 : if (!NUMERIC_IS_NAN(num))
1423 84 : res->choice.n_short.n_header =
1424 84 : num->choice.n_short.n_header ^ NUMERIC_INF_SIGN_MASK;
1425 : }
1426 :
1427 : /*
1428 : * The packed format is known to be totally zero digit trimmed always. So
1429 : * once we've eliminated specials, we can identify a zero by the fact that
1430 : * there are no digits at all. Do nothing to a zero.
1431 : */
1432 758 : else if (NUMERIC_NDIGITS(num) != 0)
1433 : {
1434 : /* Else, flip the sign */
1435 644 : if (NUMERIC_IS_SHORT(num))
1436 644 : res->choice.n_short.n_header =
1437 644 : num->choice.n_short.n_header ^ NUMERIC_SHORT_SIGN_MASK;
1438 0 : else if (NUMERIC_SIGN(num) == NUMERIC_POS)
1439 0 : res->choice.n_long.n_sign_dscale =
1440 0 : NUMERIC_NEG | NUMERIC_DSCALE(num);
1441 : else
1442 0 : res->choice.n_long.n_sign_dscale =
1443 0 : NUMERIC_POS | NUMERIC_DSCALE(num);
1444 : }
1445 :
1446 884 : PG_RETURN_NUMERIC(res);
1447 : }
1448 :
1449 :
1450 : Datum
1451 498 : numeric_uplus(PG_FUNCTION_ARGS)
1452 : {
1453 498 : Numeric num = PG_GETARG_NUMERIC(0);
1454 :
1455 498 : PG_RETURN_NUMERIC(duplicate_numeric(num));
1456 : }
1457 :
1458 :
1459 : /*
1460 : * numeric_sign_internal() -
1461 : *
1462 : * Returns -1 if the argument is less than 0, 0 if the argument is equal
1463 : * to 0, and 1 if the argument is greater than zero. Caller must have
1464 : * taken care of the NaN case, but we can handle infinities here.
1465 : */
1466 : static int
1467 3570 : numeric_sign_internal(Numeric num)
1468 : {
1469 3570 : if (NUMERIC_IS_SPECIAL(num))
1470 : {
1471 : Assert(!NUMERIC_IS_NAN(num));
1472 : /* Must be Inf or -Inf */
1473 312 : if (NUMERIC_IS_PINF(num))
1474 186 : return 1;
1475 : else
1476 126 : return -1;
1477 : }
1478 :
1479 : /*
1480 : * The packed format is known to be totally zero digit trimmed always. So
1481 : * once we've eliminated specials, we can identify a zero by the fact that
1482 : * there are no digits at all.
1483 : */
1484 3258 : else if (NUMERIC_NDIGITS(num) == 0)
1485 228 : return 0;
1486 3030 : else if (NUMERIC_SIGN(num) == NUMERIC_NEG)
1487 732 : return -1;
1488 : else
1489 2298 : return 1;
1490 : }
1491 :
1492 : /*
1493 : * numeric_sign() -
1494 : *
1495 : * returns -1 if the argument is less than 0, 0 if the argument is equal
1496 : * to 0, and 1 if the argument is greater than zero.
1497 : */
1498 : Datum
1499 48 : numeric_sign(PG_FUNCTION_ARGS)
1500 : {
1501 48 : Numeric num = PG_GETARG_NUMERIC(0);
1502 :
1503 : /*
1504 : * Handle NaN (infinities can be handled normally)
1505 : */
1506 48 : if (NUMERIC_IS_NAN(num))
1507 6 : PG_RETURN_NUMERIC(make_result(&const_nan));
1508 :
1509 42 : switch (numeric_sign_internal(num))
1510 : {
1511 6 : case 0:
1512 6 : PG_RETURN_NUMERIC(make_result(&const_zero));
1513 18 : case 1:
1514 18 : PG_RETURN_NUMERIC(make_result(&const_one));
1515 18 : case -1:
1516 18 : PG_RETURN_NUMERIC(make_result(&const_minus_one));
1517 : }
1518 :
1519 : Assert(false);
1520 0 : return (Datum) 0;
1521 : }
1522 :
1523 :
1524 : /*
1525 : * numeric_round() -
1526 : *
1527 : * Round a value to have 'scale' digits after the decimal point.
1528 : * We allow negative 'scale', implying rounding before the decimal
1529 : * point --- Oracle interprets rounding that way.
1530 : */
1531 : Datum
1532 7808 : numeric_round(PG_FUNCTION_ARGS)
1533 : {
1534 7808 : Numeric num = PG_GETARG_NUMERIC(0);
1535 7808 : int32 scale = PG_GETARG_INT32(1);
1536 : Numeric res;
1537 : NumericVar arg;
1538 :
1539 : /*
1540 : * Handle NaN and infinities
1541 : */
1542 7808 : if (NUMERIC_IS_SPECIAL(num))
1543 96 : PG_RETURN_NUMERIC(duplicate_numeric(num));
1544 :
1545 : /*
1546 : * Limit the scale value to avoid possible overflow in calculations.
1547 : *
1548 : * These limits are based on the maximum number of digits a Numeric value
1549 : * can have before and after the decimal point, but we must allow for one
1550 : * extra digit before the decimal point, in case the most significant
1551 : * digit rounds up; we must check if that causes Numeric overflow.
1552 : */
1553 7712 : scale = Max(scale, -(NUMERIC_WEIGHT_MAX + 1) * DEC_DIGITS - 1);
1554 7712 : scale = Min(scale, NUMERIC_DSCALE_MAX);
1555 :
1556 : /*
1557 : * Unpack the argument and round it at the proper digit position
1558 : */
1559 7712 : init_var(&arg);
1560 7712 : set_var_from_num(num, &arg);
1561 :
1562 7712 : round_var(&arg, scale);
1563 :
1564 : /* We don't allow negative output dscale */
1565 7712 : if (scale < 0)
1566 216 : arg.dscale = 0;
1567 :
1568 : /*
1569 : * Return the rounded result
1570 : */
1571 7712 : res = make_result(&arg);
1572 :
1573 7706 : free_var(&arg);
1574 7706 : PG_RETURN_NUMERIC(res);
1575 : }
1576 :
1577 :
1578 : /*
1579 : * numeric_trunc() -
1580 : *
1581 : * Truncate a value to have 'scale' digits after the decimal point.
1582 : * We allow negative 'scale', implying a truncation before the decimal
1583 : * point --- Oracle interprets truncation that way.
1584 : */
1585 : Datum
1586 626 : numeric_trunc(PG_FUNCTION_ARGS)
1587 : {
1588 626 : Numeric num = PG_GETARG_NUMERIC(0);
1589 626 : int32 scale = PG_GETARG_INT32(1);
1590 : Numeric res;
1591 : NumericVar arg;
1592 :
1593 : /*
1594 : * Handle NaN and infinities
1595 : */
1596 626 : if (NUMERIC_IS_SPECIAL(num))
1597 36 : PG_RETURN_NUMERIC(duplicate_numeric(num));
1598 :
1599 : /*
1600 : * Limit the scale value to avoid possible overflow in calculations.
1601 : *
1602 : * These limits are based on the maximum number of digits a Numeric value
1603 : * can have before and after the decimal point.
1604 : */
1605 590 : scale = Max(scale, -(NUMERIC_WEIGHT_MAX + 1) * DEC_DIGITS);
1606 590 : scale = Min(scale, NUMERIC_DSCALE_MAX);
1607 :
1608 : /*
1609 : * Unpack the argument and truncate it at the proper digit position
1610 : */
1611 590 : init_var(&arg);
1612 590 : set_var_from_num(num, &arg);
1613 :
1614 590 : trunc_var(&arg, scale);
1615 :
1616 : /* We don't allow negative output dscale */
1617 590 : if (scale < 0)
1618 24 : arg.dscale = 0;
1619 :
1620 : /*
1621 : * Return the truncated result
1622 : */
1623 590 : res = make_result(&arg);
1624 :
1625 590 : free_var(&arg);
1626 590 : PG_RETURN_NUMERIC(res);
1627 : }
1628 :
1629 :
1630 : /*
1631 : * numeric_ceil() -
1632 : *
1633 : * Return the smallest integer greater than or equal to the argument
1634 : */
1635 : Datum
1636 222 : numeric_ceil(PG_FUNCTION_ARGS)
1637 : {
1638 222 : Numeric num = PG_GETARG_NUMERIC(0);
1639 : Numeric res;
1640 : NumericVar result;
1641 :
1642 : /*
1643 : * Handle NaN and infinities
1644 : */
1645 222 : if (NUMERIC_IS_SPECIAL(num))
1646 18 : PG_RETURN_NUMERIC(duplicate_numeric(num));
1647 :
1648 204 : init_var_from_num(num, &result);
1649 204 : ceil_var(&result, &result);
1650 :
1651 204 : res = make_result(&result);
1652 204 : free_var(&result);
1653 :
1654 204 : PG_RETURN_NUMERIC(res);
1655 : }
1656 :
1657 :
1658 : /*
1659 : * numeric_floor() -
1660 : *
1661 : * Return the largest integer equal to or less than the argument
1662 : */
1663 : Datum
1664 126 : numeric_floor(PG_FUNCTION_ARGS)
1665 : {
1666 126 : Numeric num = PG_GETARG_NUMERIC(0);
1667 : Numeric res;
1668 : NumericVar result;
1669 :
1670 : /*
1671 : * Handle NaN and infinities
1672 : */
1673 126 : if (NUMERIC_IS_SPECIAL(num))
1674 18 : PG_RETURN_NUMERIC(duplicate_numeric(num));
1675 :
1676 108 : init_var_from_num(num, &result);
1677 108 : floor_var(&result, &result);
1678 :
1679 108 : res = make_result(&result);
1680 108 : free_var(&result);
1681 :
1682 108 : PG_RETURN_NUMERIC(res);
1683 : }
1684 :
1685 :
1686 : /*
1687 : * generate_series_numeric() -
1688 : *
1689 : * Generate series of numeric.
1690 : */
1691 : Datum
1692 120384 : generate_series_numeric(PG_FUNCTION_ARGS)
1693 : {
1694 120384 : return generate_series_step_numeric(fcinfo);
1695 : }
1696 :
1697 : Datum
1698 120834 : generate_series_step_numeric(PG_FUNCTION_ARGS)
1699 : {
1700 : generate_series_numeric_fctx *fctx;
1701 : FuncCallContext *funcctx;
1702 : MemoryContext oldcontext;
1703 :
1704 120834 : if (SRF_IS_FIRSTCALL())
1705 : {
1706 174 : Numeric start_num = PG_GETARG_NUMERIC(0);
1707 174 : Numeric stop_num = PG_GETARG_NUMERIC(1);
1708 174 : NumericVar steploc = const_one;
1709 :
1710 : /* Reject NaN and infinities in start and stop values */
1711 174 : if (NUMERIC_IS_SPECIAL(start_num))
1712 : {
1713 12 : if (NUMERIC_IS_NAN(start_num))
1714 6 : ereport(ERROR,
1715 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1716 : errmsg("start value cannot be NaN")));
1717 : else
1718 6 : ereport(ERROR,
1719 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1720 : errmsg("start value cannot be infinity")));
1721 : }
1722 162 : if (NUMERIC_IS_SPECIAL(stop_num))
1723 : {
1724 12 : if (NUMERIC_IS_NAN(stop_num))
1725 6 : ereport(ERROR,
1726 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1727 : errmsg("stop value cannot be NaN")));
1728 : else
1729 6 : ereport(ERROR,
1730 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1731 : errmsg("stop value cannot be infinity")));
1732 : }
1733 :
1734 : /* see if we were given an explicit step size */
1735 150 : if (PG_NARGS() == 3)
1736 : {
1737 72 : Numeric step_num = PG_GETARG_NUMERIC(2);
1738 :
1739 72 : if (NUMERIC_IS_SPECIAL(step_num))
1740 : {
1741 12 : if (NUMERIC_IS_NAN(step_num))
1742 6 : ereport(ERROR,
1743 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1744 : errmsg("step size cannot be NaN")));
1745 : else
1746 6 : ereport(ERROR,
1747 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1748 : errmsg("step size cannot be infinity")));
1749 : }
1750 :
1751 60 : init_var_from_num(step_num, &steploc);
1752 :
1753 60 : if (cmp_var(&steploc, &const_zero) == 0)
1754 6 : ereport(ERROR,
1755 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1756 : errmsg("step size cannot equal zero")));
1757 : }
1758 :
1759 : /* create a function context for cross-call persistence */
1760 132 : funcctx = SRF_FIRSTCALL_INIT();
1761 :
1762 : /*
1763 : * Switch to memory context appropriate for multiple function calls.
1764 : */
1765 132 : oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
1766 :
1767 : /* allocate memory for user context */
1768 : fctx = (generate_series_numeric_fctx *)
1769 132 : palloc(sizeof(generate_series_numeric_fctx));
1770 :
1771 : /*
1772 : * Use fctx to keep state from call to call. Seed current with the
1773 : * original start value. We must copy the start_num and stop_num
1774 : * values rather than pointing to them, since we may have detoasted
1775 : * them in the per-call context.
1776 : */
1777 132 : init_var(&fctx->current);
1778 132 : init_var(&fctx->stop);
1779 132 : init_var(&fctx->step);
1780 :
1781 132 : set_var_from_num(start_num, &fctx->current);
1782 132 : set_var_from_num(stop_num, &fctx->stop);
1783 132 : set_var_from_var(&steploc, &fctx->step);
1784 :
1785 132 : funcctx->user_fctx = fctx;
1786 132 : MemoryContextSwitchTo(oldcontext);
1787 : }
1788 :
1789 : /* stuff done on every call of the function */
1790 120792 : funcctx = SRF_PERCALL_SETUP();
1791 :
1792 : /*
1793 : * Get the saved state and use current state as the result of this
1794 : * iteration.
1795 : */
1796 120792 : fctx = funcctx->user_fctx;
1797 :
1798 241404 : if ((fctx->step.sign == NUMERIC_POS &&
1799 120612 : cmp_var(&fctx->current, &fctx->stop) <= 0) ||
1800 480 : (fctx->step.sign == NUMERIC_NEG &&
1801 180 : cmp_var(&fctx->current, &fctx->stop) >= 0))
1802 : {
1803 120660 : Numeric result = make_result(&fctx->current);
1804 :
1805 : /* switch to memory context appropriate for iteration calculation */
1806 120660 : oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
1807 :
1808 : /* increment current in preparation for next iteration */
1809 120660 : add_var(&fctx->current, &fctx->step, &fctx->current);
1810 120660 : MemoryContextSwitchTo(oldcontext);
1811 :
1812 : /* do when there is more left to send */
1813 120660 : SRF_RETURN_NEXT(funcctx, NumericGetDatum(result));
1814 : }
1815 : else
1816 : /* do when there is no more left */
1817 132 : SRF_RETURN_DONE(funcctx);
1818 : }
1819 :
1820 : /*
1821 : * Planner support function for generate_series(numeric, numeric [, numeric])
1822 : */
1823 : Datum
1824 486 : generate_series_numeric_support(PG_FUNCTION_ARGS)
1825 : {
1826 486 : Node *rawreq = (Node *) PG_GETARG_POINTER(0);
1827 486 : Node *ret = NULL;
1828 :
1829 486 : if (IsA(rawreq, SupportRequestRows))
1830 : {
1831 : /* Try to estimate the number of rows returned */
1832 156 : SupportRequestRows *req = (SupportRequestRows *) rawreq;
1833 :
1834 156 : if (is_funcclause(req->node)) /* be paranoid */
1835 : {
1836 156 : List *args = ((FuncExpr *) req->node)->args;
1837 : Node *arg1,
1838 : *arg2,
1839 : *arg3;
1840 :
1841 : /* We can use estimated argument values here */
1842 156 : arg1 = estimate_expression_value(req->root, linitial(args));
1843 156 : arg2 = estimate_expression_value(req->root, lsecond(args));
1844 156 : if (list_length(args) >= 3)
1845 102 : arg3 = estimate_expression_value(req->root, lthird(args));
1846 : else
1847 54 : arg3 = NULL;
1848 :
1849 : /*
1850 : * If any argument is constant NULL, we can safely assume that
1851 : * zero rows are returned. Otherwise, if they're all non-NULL
1852 : * constants, we can calculate the number of rows that will be
1853 : * returned.
1854 : */
1855 156 : if ((IsA(arg1, Const) &&
1856 150 : ((Const *) arg1)->constisnull) ||
1857 156 : (IsA(arg2, Const) &&
1858 156 : ((Const *) arg2)->constisnull) ||
1859 102 : (arg3 != NULL && IsA(arg3, Const) &&
1860 96 : ((Const *) arg3)->constisnull))
1861 : {
1862 0 : req->rows = 0;
1863 0 : ret = (Node *) req;
1864 : }
1865 156 : else if (IsA(arg1, Const) &&
1866 150 : IsA(arg2, Const) &&
1867 102 : (arg3 == NULL || IsA(arg3, Const)))
1868 : {
1869 : Numeric start_num;
1870 : Numeric stop_num;
1871 138 : NumericVar step = const_one;
1872 :
1873 : /*
1874 : * If any argument is NaN or infinity, generate_series() will
1875 : * error out, so we needn't produce an estimate.
1876 : */
1877 138 : start_num = DatumGetNumeric(((Const *) arg1)->constvalue);
1878 138 : stop_num = DatumGetNumeric(((Const *) arg2)->constvalue);
1879 :
1880 138 : if (NUMERIC_IS_SPECIAL(start_num) ||
1881 120 : NUMERIC_IS_SPECIAL(stop_num))
1882 48 : PG_RETURN_POINTER(NULL);
1883 :
1884 108 : if (arg3)
1885 : {
1886 : Numeric step_num;
1887 :
1888 66 : step_num = DatumGetNumeric(((Const *) arg3)->constvalue);
1889 :
1890 66 : if (NUMERIC_IS_SPECIAL(step_num))
1891 18 : PG_RETURN_POINTER(NULL);
1892 :
1893 48 : init_var_from_num(step_num, &step);
1894 : }
1895 :
1896 : /*
1897 : * The number of rows that will be returned is given by
1898 : * floor((stop - start) / step) + 1, if the sign of step
1899 : * matches the sign of stop - start. Otherwise, no rows will
1900 : * be returned.
1901 : */
1902 90 : if (cmp_var(&step, &const_zero) != 0)
1903 : {
1904 : NumericVar start;
1905 : NumericVar stop;
1906 : NumericVar res;
1907 :
1908 78 : init_var_from_num(start_num, &start);
1909 78 : init_var_from_num(stop_num, &stop);
1910 :
1911 78 : init_var(&res);
1912 78 : sub_var(&stop, &start, &res);
1913 :
1914 78 : if (step.sign != res.sign)
1915 : {
1916 : /* no rows will be returned */
1917 6 : req->rows = 0;
1918 6 : ret = (Node *) req;
1919 : }
1920 : else
1921 : {
1922 72 : if (arg3)
1923 30 : div_var(&res, &step, &res, 0, false, false);
1924 : else
1925 42 : trunc_var(&res, 0); /* step = 1 */
1926 :
1927 72 : req->rows = numericvar_to_double_no_overflow(&res) + 1;
1928 72 : ret = (Node *) req;
1929 : }
1930 :
1931 78 : free_var(&res);
1932 : }
1933 : }
1934 : }
1935 : }
1936 :
1937 438 : PG_RETURN_POINTER(ret);
1938 : }
1939 :
1940 :
1941 : /*
1942 : * Implements the numeric version of the width_bucket() function
1943 : * defined by SQL2003. See also width_bucket_float8().
1944 : *
1945 : * 'bound1' and 'bound2' are the lower and upper bounds of the
1946 : * histogram's range, respectively. 'count' is the number of buckets
1947 : * in the histogram. width_bucket() returns an integer indicating the
1948 : * bucket number that 'operand' belongs to in an equiwidth histogram
1949 : * with the specified characteristics. An operand smaller than the
1950 : * lower bound is assigned to bucket 0. An operand greater than or equal
1951 : * to the upper bound is assigned to an additional bucket (with number
1952 : * count+1). We don't allow the histogram bounds to be NaN or +/- infinity,
1953 : * but we do allow those values for the operand (taking NaN to be larger
1954 : * than any other value, as we do in comparisons).
1955 : */
1956 : Datum
1957 786 : width_bucket_numeric(PG_FUNCTION_ARGS)
1958 : {
1959 786 : Numeric operand = PG_GETARG_NUMERIC(0);
1960 786 : Numeric bound1 = PG_GETARG_NUMERIC(1);
1961 786 : Numeric bound2 = PG_GETARG_NUMERIC(2);
1962 786 : int32 count = PG_GETARG_INT32(3);
1963 : NumericVar count_var;
1964 : NumericVar result_var;
1965 : int32 result;
1966 :
1967 786 : if (count <= 0)
1968 12 : ereport(ERROR,
1969 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
1970 : errmsg("count must be greater than zero")));
1971 :
1972 774 : if (NUMERIC_IS_SPECIAL(bound1) || NUMERIC_IS_SPECIAL(bound2))
1973 : {
1974 24 : if (NUMERIC_IS_NAN(bound1) || NUMERIC_IS_NAN(bound2))
1975 6 : ereport(ERROR,
1976 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
1977 : errmsg("lower and upper bounds cannot be NaN")));
1978 :
1979 18 : if (NUMERIC_IS_INF(bound1) || NUMERIC_IS_INF(bound2))
1980 18 : ereport(ERROR,
1981 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
1982 : errmsg("lower and upper bounds must be finite")));
1983 : }
1984 :
1985 750 : init_var(&result_var);
1986 750 : init_var(&count_var);
1987 :
1988 : /* Convert 'count' to a numeric, for ease of use later */
1989 750 : int64_to_numericvar((int64) count, &count_var);
1990 :
1991 750 : switch (cmp_numerics(bound1, bound2))
1992 : {
1993 6 : case 0:
1994 6 : ereport(ERROR,
1995 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
1996 : errmsg("lower bound cannot equal upper bound")));
1997 : break;
1998 :
1999 : /* bound1 < bound2 */
2000 552 : case -1:
2001 552 : if (cmp_numerics(operand, bound1) < 0)
2002 114 : set_var_from_var(&const_zero, &result_var);
2003 438 : else if (cmp_numerics(operand, bound2) >= 0)
2004 114 : add_var(&count_var, &const_one, &result_var);
2005 : else
2006 324 : compute_bucket(operand, bound1, bound2, &count_var,
2007 : &result_var);
2008 552 : break;
2009 :
2010 : /* bound1 > bound2 */
2011 192 : case 1:
2012 192 : if (cmp_numerics(operand, bound1) > 0)
2013 12 : set_var_from_var(&const_zero, &result_var);
2014 180 : else if (cmp_numerics(operand, bound2) <= 0)
2015 24 : add_var(&count_var, &const_one, &result_var);
2016 : else
2017 156 : compute_bucket(operand, bound1, bound2, &count_var,
2018 : &result_var);
2019 192 : break;
2020 : }
2021 :
2022 : /* if result exceeds the range of a legal int4, we ereport here */
2023 744 : if (!numericvar_to_int32(&result_var, &result))
2024 0 : ereport(ERROR,
2025 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
2026 : errmsg("integer out of range")));
2027 :
2028 744 : free_var(&count_var);
2029 744 : free_var(&result_var);
2030 :
2031 744 : PG_RETURN_INT32(result);
2032 : }
2033 :
2034 : /*
2035 : * 'operand' is inside the bucket range, so determine the correct
2036 : * bucket for it to go in. The calculations performed by this function
2037 : * are derived directly from the SQL2003 spec. Note however that we
2038 : * multiply by count before dividing, to avoid unnecessary roundoff error.
2039 : */
2040 : static void
2041 480 : compute_bucket(Numeric operand, Numeric bound1, Numeric bound2,
2042 : const NumericVar *count_var, NumericVar *result_var)
2043 : {
2044 : NumericVar bound1_var;
2045 : NumericVar bound2_var;
2046 : NumericVar operand_var;
2047 :
2048 480 : init_var_from_num(bound1, &bound1_var);
2049 480 : init_var_from_num(bound2, &bound2_var);
2050 480 : init_var_from_num(operand, &operand_var);
2051 :
2052 : /*
2053 : * Per spec, bound1 is inclusive and bound2 is exclusive, and so we have
2054 : * bound1 <= operand < bound2 or bound1 >= operand > bound2. Either way,
2055 : * the result is ((operand - bound1) * count) / (bound2 - bound1) + 1,
2056 : * where the quotient is computed using floor division (i.e., division to
2057 : * zero decimal places with truncation), which guarantees that the result
2058 : * is in the range [1, count]. Reversing the bounds doesn't affect the
2059 : * computation, because the signs cancel out when dividing.
2060 : */
2061 480 : sub_var(&operand_var, &bound1_var, &operand_var);
2062 480 : sub_var(&bound2_var, &bound1_var, &bound2_var);
2063 :
2064 480 : mul_var(&operand_var, count_var, &operand_var,
2065 480 : operand_var.dscale + count_var->dscale);
2066 480 : div_var(&operand_var, &bound2_var, result_var, 0, false, true);
2067 480 : add_var(result_var, &const_one, result_var);
2068 :
2069 480 : free_var(&bound1_var);
2070 480 : free_var(&bound2_var);
2071 480 : free_var(&operand_var);
2072 480 : }
2073 :
2074 : /* ----------------------------------------------------------------------
2075 : *
2076 : * Comparison functions
2077 : *
2078 : * Note: btree indexes need these routines not to leak memory; therefore,
2079 : * be careful to free working copies of toasted datums. Most places don't
2080 : * need to be so careful.
2081 : *
2082 : * Sort support:
2083 : *
2084 : * We implement the sortsupport strategy routine in order to get the benefit of
2085 : * abbreviation. The ordinary numeric comparison can be quite slow as a result
2086 : * of palloc/pfree cycles (due to detoasting packed values for alignment);
2087 : * while this could be worked on itself, the abbreviation strategy gives more
2088 : * speedup in many common cases.
2089 : *
2090 : * The abbreviated format is an int64. The representation is negated relative
2091 : * to the original value, because we use the largest negative value for NaN,
2092 : * which sorts higher than other values. We convert the absolute value of the
2093 : * numeric to a 63-bit positive value, and then negate it if the original
2094 : * number was positive.
2095 : *
2096 : * We abort the abbreviation process if the abbreviation cardinality is below
2097 : * 0.01% of the row count (1 per 10k non-null rows). The actual break-even
2098 : * point is somewhat below that, perhaps 1 per 30k (at 1 per 100k there's a
2099 : * very small penalty), but we don't want to build up too many abbreviated
2100 : * values before first testing for abort, so we take the slightly pessimistic
2101 : * number. We make no attempt to estimate the cardinality of the real values,
2102 : * since it plays no part in the cost model here (if the abbreviation is equal,
2103 : * the cost of comparing equal and unequal underlying values is comparable).
2104 : * We discontinue even checking for abort (saving us the hashing overhead) if
2105 : * the estimated cardinality gets to 100k; that would be enough to support many
2106 : * billions of rows while doing no worse than breaking even.
2107 : *
2108 : * ----------------------------------------------------------------------
2109 : */
2110 :
2111 : /*
2112 : * Sort support strategy routine.
2113 : */
2114 : Datum
2115 1118 : numeric_sortsupport(PG_FUNCTION_ARGS)
2116 : {
2117 1118 : SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
2118 :
2119 1118 : ssup->comparator = numeric_fast_cmp;
2120 :
2121 1118 : if (ssup->abbreviate)
2122 : {
2123 : NumericSortSupport *nss;
2124 262 : MemoryContext oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
2125 :
2126 262 : nss = palloc(sizeof(NumericSortSupport));
2127 :
2128 : /*
2129 : * palloc a buffer for handling unaligned packed values in addition to
2130 : * the support struct
2131 : */
2132 262 : nss->buf = palloc(VARATT_SHORT_MAX + VARHDRSZ + 1);
2133 :
2134 262 : nss->input_count = 0;
2135 262 : nss->estimating = true;
2136 262 : initHyperLogLog(&nss->abbr_card, 10);
2137 :
2138 262 : ssup->ssup_extra = nss;
2139 :
2140 262 : ssup->abbrev_full_comparator = ssup->comparator;
2141 262 : ssup->comparator = numeric_cmp_abbrev;
2142 262 : ssup->abbrev_converter = numeric_abbrev_convert;
2143 262 : ssup->abbrev_abort = numeric_abbrev_abort;
2144 :
2145 262 : MemoryContextSwitchTo(oldcontext);
2146 : }
2147 :
2148 1118 : PG_RETURN_VOID();
2149 : }
2150 :
2151 : /*
2152 : * Abbreviate a numeric datum, handling NaNs and detoasting
2153 : * (must not leak memory!)
2154 : */
2155 : static Datum
2156 19168 : numeric_abbrev_convert(Datum original_datum, SortSupport ssup)
2157 : {
2158 19168 : NumericSortSupport *nss = ssup->ssup_extra;
2159 19168 : void *original_varatt = PG_DETOAST_DATUM_PACKED(original_datum);
2160 : Numeric value;
2161 : Datum result;
2162 :
2163 19168 : nss->input_count += 1;
2164 :
2165 : /*
2166 : * This is to handle packed datums without needing a palloc/pfree cycle;
2167 : * we keep and reuse a buffer large enough to handle any short datum.
2168 : */
2169 19168 : if (VARATT_IS_SHORT(original_varatt))
2170 : {
2171 1026 : void *buf = nss->buf;
2172 1026 : Size sz = VARSIZE_SHORT(original_varatt) - VARHDRSZ_SHORT;
2173 :
2174 : Assert(sz <= VARATT_SHORT_MAX - VARHDRSZ_SHORT);
2175 :
2176 1026 : SET_VARSIZE(buf, VARHDRSZ + sz);
2177 1026 : memcpy(VARDATA(buf), VARDATA_SHORT(original_varatt), sz);
2178 :
2179 1026 : value = (Numeric) buf;
2180 : }
2181 : else
2182 18142 : value = (Numeric) original_varatt;
2183 :
2184 19168 : if (NUMERIC_IS_SPECIAL(value))
2185 : {
2186 150 : if (NUMERIC_IS_PINF(value))
2187 48 : result = NUMERIC_ABBREV_PINF;
2188 102 : else if (NUMERIC_IS_NINF(value))
2189 48 : result = NUMERIC_ABBREV_NINF;
2190 : else
2191 54 : result = NUMERIC_ABBREV_NAN;
2192 : }
2193 : else
2194 : {
2195 : NumericVar var;
2196 :
2197 19018 : init_var_from_num(value, &var);
2198 :
2199 19018 : result = numeric_abbrev_convert_var(&var, nss);
2200 : }
2201 :
2202 : /* should happen only for external/compressed toasts */
2203 19168 : if ((Pointer) original_varatt != DatumGetPointer(original_datum))
2204 0 : pfree(original_varatt);
2205 :
2206 19168 : return result;
2207 : }
2208 :
2209 : /*
2210 : * Consider whether to abort abbreviation.
2211 : *
2212 : * We pay no attention to the cardinality of the non-abbreviated data. There is
2213 : * no reason to do so: unlike text, we have no fast check for equal values, so
2214 : * we pay the full overhead whenever the abbreviations are equal regardless of
2215 : * whether the underlying values are also equal.
2216 : */
2217 : static bool
2218 144 : numeric_abbrev_abort(int memtupcount, SortSupport ssup)
2219 : {
2220 144 : NumericSortSupport *nss = ssup->ssup_extra;
2221 : double abbr_card;
2222 :
2223 144 : if (memtupcount < 10000 || nss->input_count < 10000 || !nss->estimating)
2224 144 : return false;
2225 :
2226 0 : abbr_card = estimateHyperLogLog(&nss->abbr_card);
2227 :
2228 : /*
2229 : * If we have >100k distinct values, then even if we were sorting many
2230 : * billion rows we'd likely still break even, and the penalty of undoing
2231 : * that many rows of abbrevs would probably not be worth it. Stop even
2232 : * counting at that point.
2233 : */
2234 0 : if (abbr_card > 100000.0)
2235 : {
2236 0 : if (trace_sort)
2237 0 : elog(LOG,
2238 : "numeric_abbrev: estimation ends at cardinality %f"
2239 : " after " INT64_FORMAT " values (%d rows)",
2240 : abbr_card, nss->input_count, memtupcount);
2241 0 : nss->estimating = false;
2242 0 : return false;
2243 : }
2244 :
2245 : /*
2246 : * Target minimum cardinality is 1 per ~10k of non-null inputs. (The
2247 : * break even point is somewhere between one per 100k rows, where
2248 : * abbreviation has a very slight penalty, and 1 per 10k where it wins by
2249 : * a measurable percentage.) We use the relatively pessimistic 10k
2250 : * threshold, and add a 0.5 row fudge factor, because it allows us to
2251 : * abort earlier on genuinely pathological data where we've had exactly
2252 : * one abbreviated value in the first 10k (non-null) rows.
2253 : */
2254 0 : if (abbr_card < nss->input_count / 10000.0 + 0.5)
2255 : {
2256 0 : if (trace_sort)
2257 0 : elog(LOG,
2258 : "numeric_abbrev: aborting abbreviation at cardinality %f"
2259 : " below threshold %f after " INT64_FORMAT " values (%d rows)",
2260 : abbr_card, nss->input_count / 10000.0 + 0.5,
2261 : nss->input_count, memtupcount);
2262 0 : return true;
2263 : }
2264 :
2265 0 : if (trace_sort)
2266 0 : elog(LOG,
2267 : "numeric_abbrev: cardinality %f"
2268 : " after " INT64_FORMAT " values (%d rows)",
2269 : abbr_card, nss->input_count, memtupcount);
2270 :
2271 0 : return false;
2272 : }
2273 :
2274 : /*
2275 : * Non-fmgr interface to the comparison routine to allow sortsupport to elide
2276 : * the fmgr call. The saving here is small given how slow numeric comparisons
2277 : * are, but it is a required part of the sort support API when abbreviations
2278 : * are performed.
2279 : *
2280 : * Two palloc/pfree cycles could be saved here by using persistent buffers for
2281 : * aligning short-varlena inputs, but this has not so far been considered to
2282 : * be worth the effort.
2283 : */
2284 : static int
2285 17779098 : numeric_fast_cmp(Datum x, Datum y, SortSupport ssup)
2286 : {
2287 17779098 : Numeric nx = DatumGetNumeric(x);
2288 17779098 : Numeric ny = DatumGetNumeric(y);
2289 : int result;
2290 :
2291 17779098 : result = cmp_numerics(nx, ny);
2292 :
2293 17779098 : if ((Pointer) nx != DatumGetPointer(x))
2294 5656170 : pfree(nx);
2295 17779098 : if ((Pointer) ny != DatumGetPointer(y))
2296 5656164 : pfree(ny);
2297 :
2298 17779098 : return result;
2299 : }
2300 :
2301 : /*
2302 : * Compare abbreviations of values. (Abbreviations may be equal where the true
2303 : * values differ, but if the abbreviations differ, they must reflect the
2304 : * ordering of the true values.)
2305 : */
2306 : static int
2307 187846 : numeric_cmp_abbrev(Datum x, Datum y, SortSupport ssup)
2308 : {
2309 : /*
2310 : * NOTE WELL: this is intentionally backwards, because the abbreviation is
2311 : * negated relative to the original value, to handle NaN/infinity cases.
2312 : */
2313 187846 : if (DatumGetNumericAbbrev(x) < DatumGetNumericAbbrev(y))
2314 98322 : return 1;
2315 89524 : if (DatumGetNumericAbbrev(x) > DatumGetNumericAbbrev(y))
2316 89302 : return -1;
2317 222 : return 0;
2318 : }
2319 :
2320 : /*
2321 : * Abbreviate a NumericVar into the 64-bit sortsupport size.
2322 : *
2323 : * The 31-bit value is constructed as:
2324 : *
2325 : * 0 + 7bits digit weight + 24 bits digit value
2326 : *
2327 : * where the digit weight is in single decimal digits, not digit words, and
2328 : * stored in excess-44 representation[1]. The 24-bit digit value is the 7 most
2329 : * significant decimal digits of the value converted to binary. Values whose
2330 : * weights would fall outside the representable range are rounded off to zero
2331 : * (which is also used to represent actual zeros) or to 0x7FFFFFFF (which
2332 : * otherwise cannot occur). Abbreviation therefore fails to gain any advantage
2333 : * where values are outside the range 10^-44 to 10^83, which is not considered
2334 : * to be a serious limitation, or when values are of the same magnitude and
2335 : * equal in the first 7 decimal digits, which is considered to be an
2336 : * unavoidable limitation given the available bits. (Stealing three more bits
2337 : * to compare another digit would narrow the range of representable weights by
2338 : * a factor of 8, which starts to look like a real limiting factor.)
2339 : *
2340 : * (The value 44 for the excess is essentially arbitrary)
2341 : *
2342 : * The 63-bit value is constructed as:
2343 : *
2344 : * 0 + 7bits weight + 4 x 14-bit packed digit words
2345 : *
2346 : * The weight in this case is again stored in excess-44, but this time it is
2347 : * the original weight in digit words (i.e. powers of 10000). The first four
2348 : * digit words of the value (if present; trailing zeros are assumed as needed)
2349 : * are packed into 14 bits each to form the rest of the value. Again,
2350 : * out-of-range values are rounded off to 0 or 0x7FFFFFFFFFFFFFFF. The
2351 : * representable range in this case is 10^-176 to 10^332, which is considered
2352 : * to be good enough for all practical purposes, and comparison of 4 words
2353 : * means that at least 13 decimal digits are compared, which is considered to
2354 : * be a reasonable compromise between effectiveness and efficiency in computing
2355 : * the abbreviation.
2356 : *
2357 : * (The value 44 for the excess is even more arbitrary here, it was chosen just
2358 : * to match the value used in the 31-bit case)
2359 : *
2360 : * [1] - Excess-k representation means that the value is offset by adding 'k'
2361 : * and then treated as unsigned, so the smallest representable value is stored
2362 : * with all bits zero. This allows simple comparisons to work on the composite
2363 : * value.
2364 : */
2365 : static Datum
2366 19018 : numeric_abbrev_convert_var(const NumericVar *var, NumericSortSupport *nss)
2367 : {
2368 19018 : int ndigits = var->ndigits;
2369 19018 : int weight = var->weight;
2370 : int64 result;
2371 :
2372 19018 : if (ndigits == 0 || weight < -44)
2373 : {
2374 52 : result = 0;
2375 : }
2376 18966 : else if (weight > 83)
2377 : {
2378 12 : result = PG_INT64_MAX;
2379 : }
2380 : else
2381 : {
2382 18954 : result = ((int64) (weight + 44) << 56);
2383 :
2384 18954 : switch (ndigits)
2385 : {
2386 0 : default:
2387 0 : result |= ((int64) var->digits[3]);
2388 : /* FALLTHROUGH */
2389 6206 : case 3:
2390 6206 : result |= ((int64) var->digits[2]) << 14;
2391 : /* FALLTHROUGH */
2392 18332 : case 2:
2393 18332 : result |= ((int64) var->digits[1]) << 28;
2394 : /* FALLTHROUGH */
2395 18954 : case 1:
2396 18954 : result |= ((int64) var->digits[0]) << 42;
2397 18954 : break;
2398 : }
2399 : }
2400 :
2401 : /* the abbrev is negated relative to the original */
2402 19018 : if (var->sign == NUMERIC_POS)
2403 18920 : result = -result;
2404 :
2405 19018 : if (nss->estimating)
2406 : {
2407 19018 : uint32 tmp = ((uint32) result
2408 19018 : ^ (uint32) ((uint64) result >> 32));
2409 :
2410 19018 : addHyperLogLog(&nss->abbr_card, DatumGetUInt32(hash_uint32(tmp)));
2411 : }
2412 :
2413 19018 : return NumericAbbrevGetDatum(result);
2414 : }
2415 :
2416 :
2417 : /*
2418 : * Ordinary (non-sortsupport) comparisons follow.
2419 : */
2420 :
2421 : Datum
2422 750622 : numeric_cmp(PG_FUNCTION_ARGS)
2423 : {
2424 750622 : Numeric num1 = PG_GETARG_NUMERIC(0);
2425 750622 : Numeric num2 = PG_GETARG_NUMERIC(1);
2426 : int result;
2427 :
2428 750622 : result = cmp_numerics(num1, num2);
2429 :
2430 750622 : PG_FREE_IF_COPY(num1, 0);
2431 750622 : PG_FREE_IF_COPY(num2, 1);
2432 :
2433 750622 : PG_RETURN_INT32(result);
2434 : }
2435 :
2436 :
2437 : Datum
2438 650394 : numeric_eq(PG_FUNCTION_ARGS)
2439 : {
2440 650394 : Numeric num1 = PG_GETARG_NUMERIC(0);
2441 650394 : Numeric num2 = PG_GETARG_NUMERIC(1);
2442 : bool result;
2443 :
2444 650394 : result = cmp_numerics(num1, num2) == 0;
2445 :
2446 650394 : PG_FREE_IF_COPY(num1, 0);
2447 650394 : PG_FREE_IF_COPY(num2, 1);
2448 :
2449 650394 : PG_RETURN_BOOL(result);
2450 : }
2451 :
2452 : Datum
2453 5376 : numeric_ne(PG_FUNCTION_ARGS)
2454 : {
2455 5376 : Numeric num1 = PG_GETARG_NUMERIC(0);
2456 5376 : Numeric num2 = PG_GETARG_NUMERIC(1);
2457 : bool result;
2458 :
2459 5376 : result = cmp_numerics(num1, num2) != 0;
2460 :
2461 5376 : PG_FREE_IF_COPY(num1, 0);
2462 5376 : PG_FREE_IF_COPY(num2, 1);
2463 :
2464 5376 : PG_RETURN_BOOL(result);
2465 : }
2466 :
2467 : Datum
2468 55694 : numeric_gt(PG_FUNCTION_ARGS)
2469 : {
2470 55694 : Numeric num1 = PG_GETARG_NUMERIC(0);
2471 55694 : Numeric num2 = PG_GETARG_NUMERIC(1);
2472 : bool result;
2473 :
2474 55694 : result = cmp_numerics(num1, num2) > 0;
2475 :
2476 55694 : PG_FREE_IF_COPY(num1, 0);
2477 55694 : PG_FREE_IF_COPY(num2, 1);
2478 :
2479 55694 : PG_RETURN_BOOL(result);
2480 : }
2481 :
2482 : Datum
2483 15024 : numeric_ge(PG_FUNCTION_ARGS)
2484 : {
2485 15024 : Numeric num1 = PG_GETARG_NUMERIC(0);
2486 15024 : Numeric num2 = PG_GETARG_NUMERIC(1);
2487 : bool result;
2488 :
2489 15024 : result = cmp_numerics(num1, num2) >= 0;
2490 :
2491 15024 : PG_FREE_IF_COPY(num1, 0);
2492 15024 : PG_FREE_IF_COPY(num2, 1);
2493 :
2494 15024 : PG_RETURN_BOOL(result);
2495 : }
2496 :
2497 : Datum
2498 59268 : numeric_lt(PG_FUNCTION_ARGS)
2499 : {
2500 59268 : Numeric num1 = PG_GETARG_NUMERIC(0);
2501 59268 : Numeric num2 = PG_GETARG_NUMERIC(1);
2502 : bool result;
2503 :
2504 59268 : result = cmp_numerics(num1, num2) < 0;
2505 :
2506 59268 : PG_FREE_IF_COPY(num1, 0);
2507 59268 : PG_FREE_IF_COPY(num2, 1);
2508 :
2509 59268 : PG_RETURN_BOOL(result);
2510 : }
2511 :
2512 : Datum
2513 16888 : numeric_le(PG_FUNCTION_ARGS)
2514 : {
2515 16888 : Numeric num1 = PG_GETARG_NUMERIC(0);
2516 16888 : Numeric num2 = PG_GETARG_NUMERIC(1);
2517 : bool result;
2518 :
2519 16888 : result = cmp_numerics(num1, num2) <= 0;
2520 :
2521 16888 : PG_FREE_IF_COPY(num1, 0);
2522 16888 : PG_FREE_IF_COPY(num2, 1);
2523 :
2524 16888 : PG_RETURN_BOOL(result);
2525 : }
2526 :
2527 : static int
2528 19353904 : cmp_numerics(Numeric num1, Numeric num2)
2529 : {
2530 : int result;
2531 :
2532 : /*
2533 : * We consider all NANs to be equal and larger than any non-NAN (including
2534 : * Infinity). This is somewhat arbitrary; the important thing is to have
2535 : * a consistent sort order.
2536 : */
2537 19353904 : if (NUMERIC_IS_SPECIAL(num1))
2538 : {
2539 5922 : if (NUMERIC_IS_NAN(num1))
2540 : {
2541 5832 : if (NUMERIC_IS_NAN(num2))
2542 584 : result = 0; /* NAN = NAN */
2543 : else
2544 5248 : result = 1; /* NAN > non-NAN */
2545 : }
2546 90 : else if (NUMERIC_IS_PINF(num1))
2547 : {
2548 72 : if (NUMERIC_IS_NAN(num2))
2549 0 : result = -1; /* PINF < NAN */
2550 72 : else if (NUMERIC_IS_PINF(num2))
2551 6 : result = 0; /* PINF = PINF */
2552 : else
2553 66 : result = 1; /* PINF > anything else */
2554 : }
2555 : else /* num1 must be NINF */
2556 : {
2557 18 : if (NUMERIC_IS_NINF(num2))
2558 6 : result = 0; /* NINF = NINF */
2559 : else
2560 12 : result = -1; /* NINF < anything else */
2561 : }
2562 : }
2563 19347982 : else if (NUMERIC_IS_SPECIAL(num2))
2564 : {
2565 11142 : if (NUMERIC_IS_NINF(num2))
2566 12 : result = 1; /* normal > NINF */
2567 : else
2568 11130 : result = -1; /* normal < NAN or PINF */
2569 : }
2570 : else
2571 : {
2572 38674708 : result = cmp_var_common(NUMERIC_DIGITS(num1), NUMERIC_NDIGITS(num1),
2573 19337142 : NUMERIC_WEIGHT(num1), NUMERIC_SIGN(num1),
2574 19336840 : NUMERIC_DIGITS(num2), NUMERIC_NDIGITS(num2),
2575 19337566 : NUMERIC_WEIGHT(num2), NUMERIC_SIGN(num2));
2576 : }
2577 :
2578 19353904 : return result;
2579 : }
2580 :
2581 : /*
2582 : * in_range support function for numeric.
2583 : */
2584 : Datum
2585 1152 : in_range_numeric_numeric(PG_FUNCTION_ARGS)
2586 : {
2587 1152 : Numeric val = PG_GETARG_NUMERIC(0);
2588 1152 : Numeric base = PG_GETARG_NUMERIC(1);
2589 1152 : Numeric offset = PG_GETARG_NUMERIC(2);
2590 1152 : bool sub = PG_GETARG_BOOL(3);
2591 1152 : bool less = PG_GETARG_BOOL(4);
2592 : bool result;
2593 :
2594 : /*
2595 : * Reject negative (including -Inf) or NaN offset. Negative is per spec,
2596 : * and NaN is because appropriate semantics for that seem non-obvious.
2597 : */
2598 1152 : if (NUMERIC_IS_NAN(offset) ||
2599 1146 : NUMERIC_IS_NINF(offset) ||
2600 1146 : NUMERIC_SIGN(offset) == NUMERIC_NEG)
2601 6 : ereport(ERROR,
2602 : (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
2603 : errmsg("invalid preceding or following size in window function")));
2604 :
2605 : /*
2606 : * Deal with cases where val and/or base is NaN, following the rule that
2607 : * NaN sorts after non-NaN (cf cmp_numerics). The offset cannot affect
2608 : * the conclusion.
2609 : */
2610 1146 : if (NUMERIC_IS_NAN(val))
2611 : {
2612 186 : if (NUMERIC_IS_NAN(base))
2613 60 : result = true; /* NAN = NAN */
2614 : else
2615 126 : result = !less; /* NAN > non-NAN */
2616 : }
2617 960 : else if (NUMERIC_IS_NAN(base))
2618 : {
2619 126 : result = less; /* non-NAN < NAN */
2620 : }
2621 :
2622 : /*
2623 : * Deal with infinite offset (necessarily +Inf, at this point).
2624 : */
2625 834 : else if (NUMERIC_IS_SPECIAL(offset))
2626 : {
2627 : Assert(NUMERIC_IS_PINF(offset));
2628 420 : if (sub ? NUMERIC_IS_PINF(base) : NUMERIC_IS_NINF(base))
2629 : {
2630 : /*
2631 : * base +/- offset would produce NaN, so return true for any val
2632 : * (see in_range_float8_float8() for reasoning).
2633 : */
2634 174 : result = true;
2635 : }
2636 246 : else if (sub)
2637 : {
2638 : /* base - offset must be -inf */
2639 150 : if (less)
2640 54 : result = NUMERIC_IS_NINF(val); /* only -inf is <= sum */
2641 : else
2642 96 : result = true; /* any val is >= sum */
2643 : }
2644 : else
2645 : {
2646 : /* base + offset must be +inf */
2647 96 : if (less)
2648 0 : result = true; /* any val is <= sum */
2649 : else
2650 96 : result = NUMERIC_IS_PINF(val); /* only +inf is >= sum */
2651 : }
2652 : }
2653 :
2654 : /*
2655 : * Deal with cases where val and/or base is infinite. The offset, being
2656 : * now known finite, cannot affect the conclusion.
2657 : */
2658 414 : else if (NUMERIC_IS_SPECIAL(val))
2659 : {
2660 78 : if (NUMERIC_IS_PINF(val))
2661 : {
2662 36 : if (NUMERIC_IS_PINF(base))
2663 24 : result = true; /* PINF = PINF */
2664 : else
2665 12 : result = !less; /* PINF > any other non-NAN */
2666 : }
2667 : else /* val must be NINF */
2668 : {
2669 42 : if (NUMERIC_IS_NINF(base))
2670 30 : result = true; /* NINF = NINF */
2671 : else
2672 12 : result = less; /* NINF < anything else */
2673 : }
2674 : }
2675 336 : else if (NUMERIC_IS_SPECIAL(base))
2676 : {
2677 24 : if (NUMERIC_IS_NINF(base))
2678 12 : result = !less; /* normal > NINF */
2679 : else
2680 12 : result = less; /* normal < PINF */
2681 : }
2682 : else
2683 : {
2684 : /*
2685 : * Otherwise go ahead and compute base +/- offset. While it's
2686 : * possible for this to overflow the numeric format, it's unlikely
2687 : * enough that we don't take measures to prevent it.
2688 : */
2689 : NumericVar valv;
2690 : NumericVar basev;
2691 : NumericVar offsetv;
2692 : NumericVar sum;
2693 :
2694 312 : init_var_from_num(val, &valv);
2695 312 : init_var_from_num(base, &basev);
2696 312 : init_var_from_num(offset, &offsetv);
2697 312 : init_var(&sum);
2698 :
2699 312 : if (sub)
2700 156 : sub_var(&basev, &offsetv, &sum);
2701 : else
2702 156 : add_var(&basev, &offsetv, &sum);
2703 :
2704 312 : if (less)
2705 156 : result = (cmp_var(&valv, &sum) <= 0);
2706 : else
2707 156 : result = (cmp_var(&valv, &sum) >= 0);
2708 :
2709 312 : free_var(&sum);
2710 : }
2711 :
2712 1146 : PG_FREE_IF_COPY(val, 0);
2713 1146 : PG_FREE_IF_COPY(base, 1);
2714 1146 : PG_FREE_IF_COPY(offset, 2);
2715 :
2716 1146 : PG_RETURN_BOOL(result);
2717 : }
2718 :
2719 : Datum
2720 607536 : hash_numeric(PG_FUNCTION_ARGS)
2721 : {
2722 607536 : Numeric key = PG_GETARG_NUMERIC(0);
2723 : Datum digit_hash;
2724 : Datum result;
2725 : int weight;
2726 : int start_offset;
2727 : int end_offset;
2728 : int i;
2729 : int hash_len;
2730 : NumericDigit *digits;
2731 :
2732 : /* If it's NaN or infinity, don't try to hash the rest of the fields */
2733 607536 : if (NUMERIC_IS_SPECIAL(key))
2734 0 : PG_RETURN_UINT32(0);
2735 :
2736 607536 : weight = NUMERIC_WEIGHT(key);
2737 607536 : start_offset = 0;
2738 607536 : end_offset = 0;
2739 :
2740 : /*
2741 : * Omit any leading or trailing zeros from the input to the hash. The
2742 : * numeric implementation *should* guarantee that leading and trailing
2743 : * zeros are suppressed, but we're paranoid. Note that we measure the
2744 : * starting and ending offsets in units of NumericDigits, not bytes.
2745 : */
2746 607536 : digits = NUMERIC_DIGITS(key);
2747 607536 : for (i = 0; i < NUMERIC_NDIGITS(key); i++)
2748 : {
2749 605876 : if (digits[i] != (NumericDigit) 0)
2750 605876 : break;
2751 :
2752 0 : start_offset++;
2753 :
2754 : /*
2755 : * The weight is effectively the # of digits before the decimal point,
2756 : * so decrement it for each leading zero we skip.
2757 : */
2758 0 : weight--;
2759 : }
2760 :
2761 : /*
2762 : * If there are no non-zero digits, then the value of the number is zero,
2763 : * regardless of any other fields.
2764 : */
2765 607536 : if (NUMERIC_NDIGITS(key) == start_offset)
2766 1660 : PG_RETURN_UINT32(-1);
2767 :
2768 605876 : for (i = NUMERIC_NDIGITS(key) - 1; i >= 0; i--)
2769 : {
2770 605876 : if (digits[i] != (NumericDigit) 0)
2771 605876 : break;
2772 :
2773 0 : end_offset++;
2774 : }
2775 :
2776 : /* If we get here, there should be at least one non-zero digit */
2777 : Assert(start_offset + end_offset < NUMERIC_NDIGITS(key));
2778 :
2779 : /*
2780 : * Note that we don't hash on the Numeric's scale, since two numerics can
2781 : * compare equal but have different scales. We also don't hash on the
2782 : * sign, although we could: since a sign difference implies inequality,
2783 : * this shouldn't affect correctness.
2784 : */
2785 605876 : hash_len = NUMERIC_NDIGITS(key) - start_offset - end_offset;
2786 605876 : digit_hash = hash_any((unsigned char *) (NUMERIC_DIGITS(key) + start_offset),
2787 : hash_len * sizeof(NumericDigit));
2788 :
2789 : /* Mix in the weight, via XOR */
2790 605876 : result = digit_hash ^ weight;
2791 :
2792 605876 : PG_RETURN_DATUM(result);
2793 : }
2794 :
2795 : /*
2796 : * Returns 64-bit value by hashing a value to a 64-bit value, with a seed.
2797 : * Otherwise, similar to hash_numeric.
2798 : */
2799 : Datum
2800 84 : hash_numeric_extended(PG_FUNCTION_ARGS)
2801 : {
2802 84 : Numeric key = PG_GETARG_NUMERIC(0);
2803 84 : uint64 seed = PG_GETARG_INT64(1);
2804 : Datum digit_hash;
2805 : Datum result;
2806 : int weight;
2807 : int start_offset;
2808 : int end_offset;
2809 : int i;
2810 : int hash_len;
2811 : NumericDigit *digits;
2812 :
2813 : /* If it's NaN or infinity, don't try to hash the rest of the fields */
2814 84 : if (NUMERIC_IS_SPECIAL(key))
2815 0 : PG_RETURN_UINT64(seed);
2816 :
2817 84 : weight = NUMERIC_WEIGHT(key);
2818 84 : start_offset = 0;
2819 84 : end_offset = 0;
2820 :
2821 84 : digits = NUMERIC_DIGITS(key);
2822 84 : for (i = 0; i < NUMERIC_NDIGITS(key); i++)
2823 : {
2824 72 : if (digits[i] != (NumericDigit) 0)
2825 72 : break;
2826 :
2827 0 : start_offset++;
2828 :
2829 0 : weight--;
2830 : }
2831 :
2832 84 : if (NUMERIC_NDIGITS(key) == start_offset)
2833 12 : PG_RETURN_UINT64(seed - 1);
2834 :
2835 72 : for (i = NUMERIC_NDIGITS(key) - 1; i >= 0; i--)
2836 : {
2837 72 : if (digits[i] != (NumericDigit) 0)
2838 72 : break;
2839 :
2840 0 : end_offset++;
2841 : }
2842 :
2843 : Assert(start_offset + end_offset < NUMERIC_NDIGITS(key));
2844 :
2845 72 : hash_len = NUMERIC_NDIGITS(key) - start_offset - end_offset;
2846 72 : digit_hash = hash_any_extended((unsigned char *) (NUMERIC_DIGITS(key)
2847 72 : + start_offset),
2848 : hash_len * sizeof(NumericDigit),
2849 : seed);
2850 :
2851 72 : result = UInt64GetDatum(DatumGetUInt64(digit_hash) ^ weight);
2852 :
2853 72 : PG_RETURN_DATUM(result);
2854 : }
2855 :
2856 :
2857 : /* ----------------------------------------------------------------------
2858 : *
2859 : * Basic arithmetic functions
2860 : *
2861 : * ----------------------------------------------------------------------
2862 : */
2863 :
2864 :
2865 : /*
2866 : * numeric_add() -
2867 : *
2868 : * Add two numerics
2869 : */
2870 : Datum
2871 252184 : numeric_add(PG_FUNCTION_ARGS)
2872 : {
2873 252184 : Numeric num1 = PG_GETARG_NUMERIC(0);
2874 252184 : Numeric num2 = PG_GETARG_NUMERIC(1);
2875 : Numeric res;
2876 :
2877 252184 : res = numeric_add_opt_error(num1, num2, NULL);
2878 :
2879 252184 : PG_RETURN_NUMERIC(res);
2880 : }
2881 :
2882 : /*
2883 : * numeric_add_opt_error() -
2884 : *
2885 : * Internal version of numeric_add(). If "*have_error" flag is provided,
2886 : * on error it's set to true, NULL returned. This is helpful when caller
2887 : * need to handle errors by itself.
2888 : */
2889 : Numeric
2890 253222 : numeric_add_opt_error(Numeric num1, Numeric num2, bool *have_error)
2891 : {
2892 : NumericVar arg1;
2893 : NumericVar arg2;
2894 : NumericVar result;
2895 : Numeric res;
2896 :
2897 : /*
2898 : * Handle NaN and infinities
2899 : */
2900 253222 : if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
2901 : {
2902 198 : if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2903 78 : return make_result(&const_nan);
2904 120 : if (NUMERIC_IS_PINF(num1))
2905 : {
2906 36 : if (NUMERIC_IS_NINF(num2))
2907 6 : return make_result(&const_nan); /* Inf + -Inf */
2908 : else
2909 30 : return make_result(&const_pinf);
2910 : }
2911 84 : if (NUMERIC_IS_NINF(num1))
2912 : {
2913 36 : if (NUMERIC_IS_PINF(num2))
2914 6 : return make_result(&const_nan); /* -Inf + Inf */
2915 : else
2916 30 : return make_result(&const_ninf);
2917 : }
2918 : /* by here, num1 must be finite, so num2 is not */
2919 48 : if (NUMERIC_IS_PINF(num2))
2920 24 : return make_result(&const_pinf);
2921 : Assert(NUMERIC_IS_NINF(num2));
2922 24 : return make_result(&const_ninf);
2923 : }
2924 :
2925 : /*
2926 : * Unpack the values, let add_var() compute the result and return it.
2927 : */
2928 253024 : init_var_from_num(num1, &arg1);
2929 253024 : init_var_from_num(num2, &arg2);
2930 :
2931 253024 : init_var(&result);
2932 253024 : add_var(&arg1, &arg2, &result);
2933 :
2934 253024 : res = make_result_opt_error(&result, have_error);
2935 :
2936 253024 : free_var(&result);
2937 :
2938 253024 : return res;
2939 : }
2940 :
2941 :
2942 : /*
2943 : * numeric_sub() -
2944 : *
2945 : * Subtract one numeric from another
2946 : */
2947 : Datum
2948 75728 : numeric_sub(PG_FUNCTION_ARGS)
2949 : {
2950 75728 : Numeric num1 = PG_GETARG_NUMERIC(0);
2951 75728 : Numeric num2 = PG_GETARG_NUMERIC(1);
2952 : Numeric res;
2953 :
2954 75728 : res = numeric_sub_opt_error(num1, num2, NULL);
2955 :
2956 75728 : PG_RETURN_NUMERIC(res);
2957 : }
2958 :
2959 :
2960 : /*
2961 : * numeric_sub_opt_error() -
2962 : *
2963 : * Internal version of numeric_sub(). If "*have_error" flag is provided,
2964 : * on error it's set to true, NULL returned. This is helpful when caller
2965 : * need to handle errors by itself.
2966 : */
2967 : Numeric
2968 75878 : numeric_sub_opt_error(Numeric num1, Numeric num2, bool *have_error)
2969 : {
2970 : NumericVar arg1;
2971 : NumericVar arg2;
2972 : NumericVar result;
2973 : Numeric res;
2974 :
2975 : /*
2976 : * Handle NaN and infinities
2977 : */
2978 75878 : if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
2979 : {
2980 198 : if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2981 78 : return make_result(&const_nan);
2982 120 : if (NUMERIC_IS_PINF(num1))
2983 : {
2984 36 : if (NUMERIC_IS_PINF(num2))
2985 6 : return make_result(&const_nan); /* Inf - Inf */
2986 : else
2987 30 : return make_result(&const_pinf);
2988 : }
2989 84 : if (NUMERIC_IS_NINF(num1))
2990 : {
2991 36 : if (NUMERIC_IS_NINF(num2))
2992 6 : return make_result(&const_nan); /* -Inf - -Inf */
2993 : else
2994 30 : return make_result(&const_ninf);
2995 : }
2996 : /* by here, num1 must be finite, so num2 is not */
2997 48 : if (NUMERIC_IS_PINF(num2))
2998 24 : return make_result(&const_ninf);
2999 : Assert(NUMERIC_IS_NINF(num2));
3000 24 : return make_result(&const_pinf);
3001 : }
3002 :
3003 : /*
3004 : * Unpack the values, let sub_var() compute the result and return it.
3005 : */
3006 75680 : init_var_from_num(num1, &arg1);
3007 75680 : init_var_from_num(num2, &arg2);
3008 :
3009 75680 : init_var(&result);
3010 75680 : sub_var(&arg1, &arg2, &result);
3011 :
3012 75680 : res = make_result_opt_error(&result, have_error);
3013 :
3014 75680 : free_var(&result);
3015 :
3016 75680 : return res;
3017 : }
3018 :
3019 :
3020 : /*
3021 : * numeric_mul() -
3022 : *
3023 : * Calculate the product of two numerics
3024 : */
3025 : Datum
3026 489710 : numeric_mul(PG_FUNCTION_ARGS)
3027 : {
3028 489710 : Numeric num1 = PG_GETARG_NUMERIC(0);
3029 489710 : Numeric num2 = PG_GETARG_NUMERIC(1);
3030 : Numeric res;
3031 :
3032 489710 : res = numeric_mul_opt_error(num1, num2, NULL);
3033 :
3034 489710 : PG_RETURN_NUMERIC(res);
3035 : }
3036 :
3037 :
3038 : /*
3039 : * numeric_mul_opt_error() -
3040 : *
3041 : * Internal version of numeric_mul(). If "*have_error" flag is provided,
3042 : * on error it's set to true, NULL returned. This is helpful when caller
3043 : * need to handle errors by itself.
3044 : */
3045 : Numeric
3046 489746 : numeric_mul_opt_error(Numeric num1, Numeric num2, bool *have_error)
3047 : {
3048 : NumericVar arg1;
3049 : NumericVar arg2;
3050 : NumericVar result;
3051 : Numeric res;
3052 :
3053 : /*
3054 : * Handle NaN and infinities
3055 : */
3056 489746 : if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
3057 : {
3058 198 : if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
3059 78 : return make_result(&const_nan);
3060 120 : if (NUMERIC_IS_PINF(num1))
3061 : {
3062 36 : switch (numeric_sign_internal(num2))
3063 : {
3064 6 : case 0:
3065 6 : return make_result(&const_nan); /* Inf * 0 */
3066 18 : case 1:
3067 18 : return make_result(&const_pinf);
3068 12 : case -1:
3069 12 : return make_result(&const_ninf);
3070 : }
3071 : Assert(false);
3072 : }
3073 84 : if (NUMERIC_IS_NINF(num1))
3074 : {
3075 36 : switch (numeric_sign_internal(num2))
3076 : {
3077 6 : case 0:
3078 6 : return make_result(&const_nan); /* -Inf * 0 */
3079 18 : case 1:
3080 18 : return make_result(&const_ninf);
3081 12 : case -1:
3082 12 : return make_result(&const_pinf);
3083 : }
3084 : Assert(false);
3085 : }
3086 : /* by here, num1 must be finite, so num2 is not */
3087 48 : if (NUMERIC_IS_PINF(num2))
3088 : {
3089 24 : switch (numeric_sign_internal(num1))
3090 : {
3091 6 : case 0:
3092 6 : return make_result(&const_nan); /* 0 * Inf */
3093 12 : case 1:
3094 12 : return make_result(&const_pinf);
3095 6 : case -1:
3096 6 : return make_result(&const_ninf);
3097 : }
3098 : Assert(false);
3099 : }
3100 : Assert(NUMERIC_IS_NINF(num2));
3101 24 : switch (numeric_sign_internal(num1))
3102 : {
3103 6 : case 0:
3104 6 : return make_result(&const_nan); /* 0 * -Inf */
3105 12 : case 1:
3106 12 : return make_result(&const_ninf);
3107 6 : case -1:
3108 6 : return make_result(&const_pinf);
3109 : }
3110 : Assert(false);
3111 : }
3112 :
3113 : /*
3114 : * Unpack the values, let mul_var() compute the result and return it.
3115 : * Unlike add_var() and sub_var(), mul_var() will round its result. In the
3116 : * case of numeric_mul(), which is invoked for the * operator on numerics,
3117 : * we request exact representation for the product (rscale = sum(dscale of
3118 : * arg1, dscale of arg2)). If the exact result has more digits after the
3119 : * decimal point than can be stored in a numeric, we round it. Rounding
3120 : * after computing the exact result ensures that the final result is
3121 : * correctly rounded (rounding in mul_var() using a truncated product
3122 : * would not guarantee this).
3123 : */
3124 489548 : init_var_from_num(num1, &arg1);
3125 489548 : init_var_from_num(num2, &arg2);
3126 :
3127 489548 : init_var(&result);
3128 489548 : mul_var(&arg1, &arg2, &result, arg1.dscale + arg2.dscale);
3129 :
3130 489548 : if (result.dscale > NUMERIC_DSCALE_MAX)
3131 6 : round_var(&result, NUMERIC_DSCALE_MAX);
3132 :
3133 489548 : res = make_result_opt_error(&result, have_error);
3134 :
3135 489548 : free_var(&result);
3136 :
3137 489548 : return res;
3138 : }
3139 :
3140 :
3141 : /*
3142 : * numeric_div() -
3143 : *
3144 : * Divide one numeric into another
3145 : */
3146 : Datum
3147 148258 : numeric_div(PG_FUNCTION_ARGS)
3148 : {
3149 148258 : Numeric num1 = PG_GETARG_NUMERIC(0);
3150 148258 : Numeric num2 = PG_GETARG_NUMERIC(1);
3151 : Numeric res;
3152 :
3153 148258 : res = numeric_div_opt_error(num1, num2, NULL);
3154 :
3155 148226 : PG_RETURN_NUMERIC(res);
3156 : }
3157 :
3158 :
3159 : /*
3160 : * numeric_div_opt_error() -
3161 : *
3162 : * Internal version of numeric_div(). If "*have_error" flag is provided,
3163 : * on error it's set to true, NULL returned. This is helpful when caller
3164 : * need to handle errors by itself.
3165 : */
3166 : Numeric
3167 149098 : numeric_div_opt_error(Numeric num1, Numeric num2, bool *have_error)
3168 : {
3169 : NumericVar arg1;
3170 : NumericVar arg2;
3171 : NumericVar result;
3172 : Numeric res;
3173 : int rscale;
3174 :
3175 149098 : if (have_error)
3176 48 : *have_error = false;
3177 :
3178 : /*
3179 : * Handle NaN and infinities
3180 : */
3181 149098 : if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
3182 : {
3183 198 : if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
3184 78 : return make_result(&const_nan);
3185 120 : if (NUMERIC_IS_PINF(num1))
3186 : {
3187 36 : if (NUMERIC_IS_SPECIAL(num2))
3188 12 : return make_result(&const_nan); /* Inf / [-]Inf */
3189 24 : switch (numeric_sign_internal(num2))
3190 : {
3191 6 : case 0:
3192 6 : if (have_error)
3193 : {
3194 0 : *have_error = true;
3195 0 : return NULL;
3196 : }
3197 6 : ereport(ERROR,
3198 : (errcode(ERRCODE_DIVISION_BY_ZERO),
3199 : errmsg("division by zero")));
3200 : break;
3201 12 : case 1:
3202 12 : return make_result(&const_pinf);
3203 6 : case -1:
3204 6 : return make_result(&const_ninf);
3205 : }
3206 : Assert(false);
3207 : }
3208 84 : if (NUMERIC_IS_NINF(num1))
3209 : {
3210 36 : if (NUMERIC_IS_SPECIAL(num2))
3211 12 : return make_result(&const_nan); /* -Inf / [-]Inf */
3212 24 : switch (numeric_sign_internal(num2))
3213 : {
3214 6 : case 0:
3215 6 : if (have_error)
3216 : {
3217 0 : *have_error = true;
3218 0 : return NULL;
3219 : }
3220 6 : ereport(ERROR,
3221 : (errcode(ERRCODE_DIVISION_BY_ZERO),
3222 : errmsg("division by zero")));
3223 : break;
3224 12 : case 1:
3225 12 : return make_result(&const_ninf);
3226 6 : case -1:
3227 6 : return make_result(&const_pinf);
3228 : }
3229 : Assert(false);
3230 : }
3231 : /* by here, num1 must be finite, so num2 is not */
3232 :
3233 : /*
3234 : * POSIX would have us return zero or minus zero if num1 is zero, and
3235 : * otherwise throw an underflow error. But the numeric type doesn't
3236 : * really do underflow, so let's just return zero.
3237 : */
3238 48 : return make_result(&const_zero);
3239 : }
3240 :
3241 : /*
3242 : * Unpack the arguments
3243 : */
3244 148900 : init_var_from_num(num1, &arg1);
3245 148900 : init_var_from_num(num2, &arg2);
3246 :
3247 148900 : init_var(&result);
3248 :
3249 : /*
3250 : * Select scale for division result
3251 : */
3252 148900 : rscale = select_div_scale(&arg1, &arg2);
3253 :
3254 : /*
3255 : * If "have_error" is provided, check for division by zero here
3256 : */
3257 148900 : if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
3258 : {
3259 12 : *have_error = true;
3260 12 : return NULL;
3261 : }
3262 :
3263 : /*
3264 : * Do the divide and return the result
3265 : */
3266 148888 : div_var(&arg1, &arg2, &result, rscale, true, true);
3267 :
3268 148850 : res = make_result_opt_error(&result, have_error);
3269 :
3270 148850 : free_var(&result);
3271 :
3272 148850 : return res;
3273 : }
3274 :
3275 :
3276 : /*
3277 : * numeric_div_trunc() -
3278 : *
3279 : * Divide one numeric into another, truncating the result to an integer
3280 : */
3281 : Datum
3282 1218 : numeric_div_trunc(PG_FUNCTION_ARGS)
3283 : {
3284 1218 : Numeric num1 = PG_GETARG_NUMERIC(0);
3285 1218 : Numeric num2 = PG_GETARG_NUMERIC(1);
3286 : NumericVar arg1;
3287 : NumericVar arg2;
3288 : NumericVar result;
3289 : Numeric res;
3290 :
3291 : /*
3292 : * Handle NaN and infinities
3293 : */
3294 1218 : if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
3295 : {
3296 198 : if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
3297 78 : PG_RETURN_NUMERIC(make_result(&const_nan));
3298 120 : if (NUMERIC_IS_PINF(num1))
3299 : {
3300 36 : if (NUMERIC_IS_SPECIAL(num2))
3301 12 : PG_RETURN_NUMERIC(make_result(&const_nan)); /* Inf / [-]Inf */
3302 24 : switch (numeric_sign_internal(num2))
3303 : {
3304 6 : case 0:
3305 6 : ereport(ERROR,
3306 : (errcode(ERRCODE_DIVISION_BY_ZERO),
3307 : errmsg("division by zero")));
3308 : break;
3309 12 : case 1:
3310 12 : PG_RETURN_NUMERIC(make_result(&const_pinf));
3311 6 : case -1:
3312 6 : PG_RETURN_NUMERIC(make_result(&const_ninf));
3313 : }
3314 : Assert(false);
3315 : }
3316 84 : if (NUMERIC_IS_NINF(num1))
3317 : {
3318 36 : if (NUMERIC_IS_SPECIAL(num2))
3319 12 : PG_RETURN_NUMERIC(make_result(&const_nan)); /* -Inf / [-]Inf */
3320 24 : switch (numeric_sign_internal(num2))
3321 : {
3322 6 : case 0:
3323 6 : ereport(ERROR,
3324 : (errcode(ERRCODE_DIVISION_BY_ZERO),
3325 : errmsg("division by zero")));
3326 : break;
3327 12 : case 1:
3328 12 : PG_RETURN_NUMERIC(make_result(&const_ninf));
3329 6 : case -1:
3330 6 : PG_RETURN_NUMERIC(make_result(&const_pinf));
3331 : }
3332 : Assert(false);
3333 : }
3334 : /* by here, num1 must be finite, so num2 is not */
3335 :
3336 : /*
3337 : * POSIX would have us return zero or minus zero if num1 is zero, and
3338 : * otherwise throw an underflow error. But the numeric type doesn't
3339 : * really do underflow, so let's just return zero.
3340 : */
3341 48 : PG_RETURN_NUMERIC(make_result(&const_zero));
3342 : }
3343 :
3344 : /*
3345 : * Unpack the arguments
3346 : */
3347 1020 : init_var_from_num(num1, &arg1);
3348 1020 : init_var_from_num(num2, &arg2);
3349 :
3350 1020 : init_var(&result);
3351 :
3352 : /*
3353 : * Do the divide and return the result
3354 : */
3355 1020 : div_var(&arg1, &arg2, &result, 0, false, true);
3356 :
3357 1014 : res = make_result(&result);
3358 :
3359 1014 : free_var(&result);
3360 :
3361 1014 : PG_RETURN_NUMERIC(res);
3362 : }
3363 :
3364 :
3365 : /*
3366 : * numeric_mod() -
3367 : *
3368 : * Calculate the modulo of two numerics
3369 : */
3370 : Datum
3371 413366 : numeric_mod(PG_FUNCTION_ARGS)
3372 : {
3373 413366 : Numeric num1 = PG_GETARG_NUMERIC(0);
3374 413366 : Numeric num2 = PG_GETARG_NUMERIC(1);
3375 : Numeric res;
3376 :
3377 413366 : res = numeric_mod_opt_error(num1, num2, NULL);
3378 :
3379 413348 : PG_RETURN_NUMERIC(res);
3380 : }
3381 :
3382 :
3383 : /*
3384 : * numeric_mod_opt_error() -
3385 : *
3386 : * Internal version of numeric_mod(). If "*have_error" flag is provided,
3387 : * on error it's set to true, NULL returned. This is helpful when caller
3388 : * need to handle errors by itself.
3389 : */
3390 : Numeric
3391 413378 : numeric_mod_opt_error(Numeric num1, Numeric num2, bool *have_error)
3392 : {
3393 : Numeric res;
3394 : NumericVar arg1;
3395 : NumericVar arg2;
3396 : NumericVar result;
3397 :
3398 413378 : if (have_error)
3399 0 : *have_error = false;
3400 :
3401 : /*
3402 : * Handle NaN and infinities. We follow POSIX fmod() on this, except that
3403 : * POSIX treats x-is-infinite and y-is-zero identically, raising EDOM and
3404 : * returning NaN. We choose to throw error only for y-is-zero.
3405 : */
3406 413378 : if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
3407 : {
3408 198 : if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
3409 78 : return make_result(&const_nan);
3410 120 : if (NUMERIC_IS_INF(num1))
3411 : {
3412 72 : if (numeric_sign_internal(num2) == 0)
3413 : {
3414 12 : if (have_error)
3415 : {
3416 0 : *have_error = true;
3417 0 : return NULL;
3418 : }
3419 12 : ereport(ERROR,
3420 : (errcode(ERRCODE_DIVISION_BY_ZERO),
3421 : errmsg("division by zero")));
3422 : }
3423 : /* Inf % any nonzero = NaN */
3424 60 : return make_result(&const_nan);
3425 : }
3426 : /* num2 must be [-]Inf; result is num1 regardless of sign of num2 */
3427 48 : return duplicate_numeric(num1);
3428 : }
3429 :
3430 413180 : init_var_from_num(num1, &arg1);
3431 413180 : init_var_from_num(num2, &arg2);
3432 :
3433 413180 : init_var(&result);
3434 :
3435 : /*
3436 : * If "have_error" is provided, check for division by zero here
3437 : */
3438 413180 : if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
3439 : {
3440 0 : *have_error = true;
3441 0 : return NULL;
3442 : }
3443 :
3444 413180 : mod_var(&arg1, &arg2, &result);
3445 :
3446 413168 : res = make_result_opt_error(&result, NULL);
3447 :
3448 413168 : free_var(&result);
3449 :
3450 413168 : return res;
3451 : }
3452 :
3453 :
3454 : /*
3455 : * numeric_inc() -
3456 : *
3457 : * Increment a number by one
3458 : */
3459 : Datum
3460 48 : numeric_inc(PG_FUNCTION_ARGS)
3461 : {
3462 48 : Numeric num = PG_GETARG_NUMERIC(0);
3463 : NumericVar arg;
3464 : Numeric res;
3465 :
3466 : /*
3467 : * Handle NaN and infinities
3468 : */
3469 48 : if (NUMERIC_IS_SPECIAL(num))
3470 18 : PG_RETURN_NUMERIC(duplicate_numeric(num));
3471 :
3472 : /*
3473 : * Compute the result and return it
3474 : */
3475 30 : init_var_from_num(num, &arg);
3476 :
3477 30 : add_var(&arg, &const_one, &arg);
3478 :
3479 30 : res = make_result(&arg);
3480 :
3481 30 : free_var(&arg);
3482 :
3483 30 : PG_RETURN_NUMERIC(res);
3484 : }
3485 :
3486 :
3487 : /*
3488 : * numeric_smaller() -
3489 : *
3490 : * Return the smaller of two numbers
3491 : */
3492 : Datum
3493 798 : numeric_smaller(PG_FUNCTION_ARGS)
3494 : {
3495 798 : Numeric num1 = PG_GETARG_NUMERIC(0);
3496 798 : Numeric num2 = PG_GETARG_NUMERIC(1);
3497 :
3498 : /*
3499 : * Use cmp_numerics so that this will agree with the comparison operators,
3500 : * particularly as regards comparisons involving NaN.
3501 : */
3502 798 : if (cmp_numerics(num1, num2) < 0)
3503 646 : PG_RETURN_NUMERIC(num1);
3504 : else
3505 152 : PG_RETURN_NUMERIC(num2);
3506 : }
3507 :
3508 :
3509 : /*
3510 : * numeric_larger() -
3511 : *
3512 : * Return the larger of two numbers
3513 : */
3514 : Datum
3515 18630 : numeric_larger(PG_FUNCTION_ARGS)
3516 : {
3517 18630 : Numeric num1 = PG_GETARG_NUMERIC(0);
3518 18630 : Numeric num2 = PG_GETARG_NUMERIC(1);
3519 :
3520 : /*
3521 : * Use cmp_numerics so that this will agree with the comparison operators,
3522 : * particularly as regards comparisons involving NaN.
3523 : */
3524 18630 : if (cmp_numerics(num1, num2) > 0)
3525 17890 : PG_RETURN_NUMERIC(num1);
3526 : else
3527 740 : PG_RETURN_NUMERIC(num2);
3528 : }
3529 :
3530 :
3531 : /* ----------------------------------------------------------------------
3532 : *
3533 : * Advanced math functions
3534 : *
3535 : * ----------------------------------------------------------------------
3536 : */
3537 :
3538 : /*
3539 : * numeric_gcd() -
3540 : *
3541 : * Calculate the greatest common divisor of two numerics
3542 : */
3543 : Datum
3544 216 : numeric_gcd(PG_FUNCTION_ARGS)
3545 : {
3546 216 : Numeric num1 = PG_GETARG_NUMERIC(0);
3547 216 : Numeric num2 = PG_GETARG_NUMERIC(1);
3548 : NumericVar arg1;
3549 : NumericVar arg2;
3550 : NumericVar result;
3551 : Numeric res;
3552 :
3553 : /*
3554 : * Handle NaN and infinities: we consider the result to be NaN in all such
3555 : * cases.
3556 : */
3557 216 : if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
3558 96 : PG_RETURN_NUMERIC(make_result(&const_nan));
3559 :
3560 : /*
3561 : * Unpack the arguments
3562 : */
3563 120 : init_var_from_num(num1, &arg1);
3564 120 : init_var_from_num(num2, &arg2);
3565 :
3566 120 : init_var(&result);
3567 :
3568 : /*
3569 : * Find the GCD and return the result
3570 : */
3571 120 : gcd_var(&arg1, &arg2, &result);
3572 :
3573 120 : res = make_result(&result);
3574 :
3575 120 : free_var(&result);
3576 :
3577 120 : PG_RETURN_NUMERIC(res);
3578 : }
3579 :
3580 :
3581 : /*
3582 : * numeric_lcm() -
3583 : *
3584 : * Calculate the least common multiple of two numerics
3585 : */
3586 : Datum
3587 246 : numeric_lcm(PG_FUNCTION_ARGS)
3588 : {
3589 246 : Numeric num1 = PG_GETARG_NUMERIC(0);
3590 246 : Numeric num2 = PG_GETARG_NUMERIC(1);
3591 : NumericVar arg1;
3592 : NumericVar arg2;
3593 : NumericVar result;
3594 : Numeric res;
3595 :
3596 : /*
3597 : * Handle NaN and infinities: we consider the result to be NaN in all such
3598 : * cases.
3599 : */
3600 246 : if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
3601 96 : PG_RETURN_NUMERIC(make_result(&const_nan));
3602 :
3603 : /*
3604 : * Unpack the arguments
3605 : */
3606 150 : init_var_from_num(num1, &arg1);
3607 150 : init_var_from_num(num2, &arg2);
3608 :
3609 150 : init_var(&result);
3610 :
3611 : /*
3612 : * Compute the result using lcm(x, y) = abs(x / gcd(x, y) * y), returning
3613 : * zero if either input is zero.
3614 : *
3615 : * Note that the division is guaranteed to be exact, returning an integer
3616 : * result, so the LCM is an integral multiple of both x and y. A display
3617 : * scale of Min(x.dscale, y.dscale) would be sufficient to represent it,
3618 : * but as with other numeric functions, we choose to return a result whose
3619 : * display scale is no smaller than either input.
3620 : */
3621 150 : if (arg1.ndigits == 0 || arg2.ndigits == 0)
3622 48 : set_var_from_var(&const_zero, &result);
3623 : else
3624 : {
3625 102 : gcd_var(&arg1, &arg2, &result);
3626 102 : div_var(&arg1, &result, &result, 0, false, true);
3627 102 : mul_var(&arg2, &result, &result, arg2.dscale);
3628 102 : result.sign = NUMERIC_POS;
3629 : }
3630 :
3631 150 : result.dscale = Max(arg1.dscale, arg2.dscale);
3632 :
3633 150 : res = make_result(&result);
3634 :
3635 144 : free_var(&result);
3636 :
3637 144 : PG_RETURN_NUMERIC(res);
3638 : }
3639 :
3640 :
3641 : /*
3642 : * numeric_fac()
3643 : *
3644 : * Compute factorial
3645 : */
3646 : Datum
3647 42 : numeric_fac(PG_FUNCTION_ARGS)
3648 : {
3649 42 : int64 num = PG_GETARG_INT64(0);
3650 : Numeric res;
3651 : NumericVar fact;
3652 : NumericVar result;
3653 :
3654 42 : if (num < 0)
3655 6 : ereport(ERROR,
3656 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
3657 : errmsg("factorial of a negative number is undefined")));
3658 36 : if (num <= 1)
3659 : {
3660 6 : res = make_result(&const_one);
3661 6 : PG_RETURN_NUMERIC(res);
3662 : }
3663 : /* Fail immediately if the result would overflow */
3664 30 : if (num > 32177)
3665 6 : ereport(ERROR,
3666 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
3667 : errmsg("value overflows numeric format")));
3668 :
3669 24 : init_var(&fact);
3670 24 : init_var(&result);
3671 :
3672 24 : int64_to_numericvar(num, &result);
3673 :
3674 294 : for (num = num - 1; num > 1; num--)
3675 : {
3676 : /* this loop can take awhile, so allow it to be interrupted */
3677 270 : CHECK_FOR_INTERRUPTS();
3678 :
3679 270 : int64_to_numericvar(num, &fact);
3680 :
3681 270 : mul_var(&result, &fact, &result, 0);
3682 : }
3683 :
3684 24 : res = make_result(&result);
3685 :
3686 24 : free_var(&fact);
3687 24 : free_var(&result);
3688 :
3689 24 : PG_RETURN_NUMERIC(res);
3690 : }
3691 :
3692 :
3693 : /*
3694 : * numeric_sqrt() -
3695 : *
3696 : * Compute the square root of a numeric.
3697 : */
3698 : Datum
3699 150 : numeric_sqrt(PG_FUNCTION_ARGS)
3700 : {
3701 150 : Numeric num = PG_GETARG_NUMERIC(0);
3702 : Numeric res;
3703 : NumericVar arg;
3704 : NumericVar result;
3705 : int sweight;
3706 : int rscale;
3707 :
3708 : /*
3709 : * Handle NaN and infinities
3710 : */
3711 150 : if (NUMERIC_IS_SPECIAL(num))
3712 : {
3713 : /* error should match that in sqrt_var() */
3714 18 : if (NUMERIC_IS_NINF(num))
3715 6 : ereport(ERROR,
3716 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
3717 : errmsg("cannot take square root of a negative number")));
3718 : /* For NAN or PINF, just duplicate the input */
3719 12 : PG_RETURN_NUMERIC(duplicate_numeric(num));
3720 : }
3721 :
3722 : /*
3723 : * Unpack the argument and determine the result scale. We choose a scale
3724 : * to give at least NUMERIC_MIN_SIG_DIGITS significant digits; but in any
3725 : * case not less than the input's dscale.
3726 : */
3727 132 : init_var_from_num(num, &arg);
3728 :
3729 132 : init_var(&result);
3730 :
3731 : /*
3732 : * Assume the input was normalized, so arg.weight is accurate. The result
3733 : * then has at least sweight = floor(arg.weight * DEC_DIGITS / 2 + 1)
3734 : * digits before the decimal point. When DEC_DIGITS is even, we can save
3735 : * a few cycles, since the division is exact and there is no need to round
3736 : * towards negative infinity.
3737 : */
3738 : #if DEC_DIGITS == ((DEC_DIGITS / 2) * 2)
3739 132 : sweight = arg.weight * DEC_DIGITS / 2 + 1;
3740 : #else
3741 : if (arg.weight >= 0)
3742 : sweight = arg.weight * DEC_DIGITS / 2 + 1;
3743 : else
3744 : sweight = 1 - (1 - arg.weight * DEC_DIGITS) / 2;
3745 : #endif
3746 :
3747 132 : rscale = NUMERIC_MIN_SIG_DIGITS - sweight;
3748 132 : rscale = Max(rscale, arg.dscale);
3749 132 : rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
3750 132 : rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
3751 :
3752 : /*
3753 : * Let sqrt_var() do the calculation and return the result.
3754 : */
3755 132 : sqrt_var(&arg, &result, rscale);
3756 :
3757 126 : res = make_result(&result);
3758 :
3759 126 : free_var(&result);
3760 :
3761 126 : PG_RETURN_NUMERIC(res);
3762 : }
3763 :
3764 :
3765 : /*
3766 : * numeric_exp() -
3767 : *
3768 : * Raise e to the power of x
3769 : */
3770 : Datum
3771 78 : numeric_exp(PG_FUNCTION_ARGS)
3772 : {
3773 78 : Numeric num = PG_GETARG_NUMERIC(0);
3774 : Numeric res;
3775 : NumericVar arg;
3776 : NumericVar result;
3777 : int rscale;
3778 : double val;
3779 :
3780 : /*
3781 : * Handle NaN and infinities
3782 : */
3783 78 : if (NUMERIC_IS_SPECIAL(num))
3784 : {
3785 : /* Per POSIX, exp(-Inf) is zero */
3786 18 : if (NUMERIC_IS_NINF(num))
3787 6 : PG_RETURN_NUMERIC(make_result(&const_zero));
3788 : /* For NAN or PINF, just duplicate the input */
3789 12 : PG_RETURN_NUMERIC(duplicate_numeric(num));
3790 : }
3791 :
3792 : /*
3793 : * Unpack the argument and determine the result scale. We choose a scale
3794 : * to give at least NUMERIC_MIN_SIG_DIGITS significant digits; but in any
3795 : * case not less than the input's dscale.
3796 : */
3797 60 : init_var_from_num(num, &arg);
3798 :
3799 60 : init_var(&result);
3800 :
3801 : /* convert input to float8, ignoring overflow */
3802 60 : val = numericvar_to_double_no_overflow(&arg);
3803 :
3804 : /*
3805 : * log10(result) = num * log10(e), so this is approximately the decimal
3806 : * weight of the result:
3807 : */
3808 60 : val *= 0.434294481903252;
3809 :
3810 : /* limit to something that won't cause integer overflow */
3811 60 : val = Max(val, -NUMERIC_MAX_RESULT_SCALE);
3812 60 : val = Min(val, NUMERIC_MAX_RESULT_SCALE);
3813 :
3814 60 : rscale = NUMERIC_MIN_SIG_DIGITS - (int) val;
3815 60 : rscale = Max(rscale, arg.dscale);
3816 60 : rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
3817 60 : rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
3818 :
3819 : /*
3820 : * Let exp_var() do the calculation and return the result.
3821 : */
3822 60 : exp_var(&arg, &result, rscale);
3823 :
3824 60 : res = make_result(&result);
3825 :
3826 60 : free_var(&result);
3827 :
3828 60 : PG_RETURN_NUMERIC(res);
3829 : }
3830 :
3831 :
3832 : /*
3833 : * numeric_ln() -
3834 : *
3835 : * Compute the natural logarithm of x
3836 : */
3837 : Datum
3838 198 : numeric_ln(PG_FUNCTION_ARGS)
3839 : {
3840 198 : Numeric num = PG_GETARG_NUMERIC(0);
3841 : Numeric res;
3842 : NumericVar arg;
3843 : NumericVar result;
3844 : int ln_dweight;
3845 : int rscale;
3846 :
3847 : /*
3848 : * Handle NaN and infinities
3849 : */
3850 198 : if (NUMERIC_IS_SPECIAL(num))
3851 : {
3852 18 : if (NUMERIC_IS_NINF(num))
3853 6 : ereport(ERROR,
3854 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
3855 : errmsg("cannot take logarithm of a negative number")));
3856 : /* For NAN or PINF, just duplicate the input */
3857 12 : PG_RETURN_NUMERIC(duplicate_numeric(num));
3858 : }
3859 :
3860 180 : init_var_from_num(num, &arg);
3861 180 : init_var(&result);
3862 :
3863 : /* Estimated dweight of logarithm */
3864 180 : ln_dweight = estimate_ln_dweight(&arg);
3865 :
3866 180 : rscale = NUMERIC_MIN_SIG_DIGITS - ln_dweight;
3867 180 : rscale = Max(rscale, arg.dscale);
3868 180 : rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
3869 180 : rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
3870 :
3871 180 : ln_var(&arg, &result, rscale);
3872 :
3873 156 : res = make_result(&result);
3874 :
3875 156 : free_var(&result);
3876 :
3877 156 : PG_RETURN_NUMERIC(res);
3878 : }
3879 :
3880 :
3881 : /*
3882 : * numeric_log() -
3883 : *
3884 : * Compute the logarithm of x in a given base
3885 : */
3886 : Datum
3887 342 : numeric_log(PG_FUNCTION_ARGS)
3888 : {
3889 342 : Numeric num1 = PG_GETARG_NUMERIC(0);
3890 342 : Numeric num2 = PG_GETARG_NUMERIC(1);
3891 : Numeric res;
3892 : NumericVar arg1;
3893 : NumericVar arg2;
3894 : NumericVar result;
3895 :
3896 : /*
3897 : * Handle NaN and infinities
3898 : */
3899 342 : if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
3900 : {
3901 : int sign1,
3902 : sign2;
3903 :
3904 126 : if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
3905 54 : PG_RETURN_NUMERIC(make_result(&const_nan));
3906 : /* fail on negative inputs including -Inf, as log_var would */
3907 72 : sign1 = numeric_sign_internal(num1);
3908 72 : sign2 = numeric_sign_internal(num2);
3909 72 : if (sign1 < 0 || sign2 < 0)
3910 24 : ereport(ERROR,
3911 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
3912 : errmsg("cannot take logarithm of a negative number")));
3913 : /* fail on zero inputs, as log_var would */
3914 48 : if (sign1 == 0 || sign2 == 0)
3915 6 : ereport(ERROR,
3916 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
3917 : errmsg("cannot take logarithm of zero")));
3918 42 : if (NUMERIC_IS_PINF(num1))
3919 : {
3920 : /* log(Inf, Inf) reduces to Inf/Inf, so it's NaN */
3921 18 : if (NUMERIC_IS_PINF(num2))
3922 6 : PG_RETURN_NUMERIC(make_result(&const_nan));
3923 : /* log(Inf, finite-positive) is zero (we don't throw underflow) */
3924 12 : PG_RETURN_NUMERIC(make_result(&const_zero));
3925 : }
3926 : Assert(NUMERIC_IS_PINF(num2));
3927 : /* log(finite-positive, Inf) is Inf */
3928 24 : PG_RETURN_NUMERIC(make_result(&const_pinf));
3929 : }
3930 :
3931 : /*
3932 : * Initialize things
3933 : */
3934 216 : init_var_from_num(num1, &arg1);
3935 216 : init_var_from_num(num2, &arg2);
3936 216 : init_var(&result);
3937 :
3938 : /*
3939 : * Call log_var() to compute and return the result; note it handles scale
3940 : * selection itself.
3941 : */
3942 216 : log_var(&arg1, &arg2, &result);
3943 :
3944 156 : res = make_result(&result);
3945 :
3946 156 : free_var(&result);
3947 :
3948 156 : PG_RETURN_NUMERIC(res);
3949 : }
3950 :
3951 :
3952 : /*
3953 : * numeric_power() -
3954 : *
3955 : * Raise x to the power of y
3956 : */
3957 : Datum
3958 1644 : numeric_power(PG_FUNCTION_ARGS)
3959 : {
3960 1644 : Numeric num1 = PG_GETARG_NUMERIC(0);
3961 1644 : Numeric num2 = PG_GETARG_NUMERIC(1);
3962 : Numeric res;
3963 : NumericVar arg1;
3964 : NumericVar arg2;
3965 : NumericVar result;
3966 : int sign1,
3967 : sign2;
3968 :
3969 : /*
3970 : * Handle NaN and infinities
3971 : */
3972 1644 : if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
3973 : {
3974 : /*
3975 : * We follow the POSIX spec for pow(3), which says that NaN ^ 0 = 1,
3976 : * and 1 ^ NaN = 1, while all other cases with NaN inputs yield NaN
3977 : * (with no error).
3978 : */
3979 234 : if (NUMERIC_IS_NAN(num1))
3980 : {
3981 54 : if (!NUMERIC_IS_SPECIAL(num2))
3982 : {
3983 36 : init_var_from_num(num2, &arg2);
3984 36 : if (cmp_var(&arg2, &const_zero) == 0)
3985 12 : PG_RETURN_NUMERIC(make_result(&const_one));
3986 : }
3987 42 : PG_RETURN_NUMERIC(make_result(&const_nan));
3988 : }
3989 180 : if (NUMERIC_IS_NAN(num2))
3990 : {
3991 42 : if (!NUMERIC_IS_SPECIAL(num1))
3992 : {
3993 36 : init_var_from_num(num1, &arg1);
3994 36 : if (cmp_var(&arg1, &const_one) == 0)
3995 12 : PG_RETURN_NUMERIC(make_result(&const_one));
3996 : }
3997 30 : PG_RETURN_NUMERIC(make_result(&const_nan));
3998 : }
3999 : /* At least one input is infinite, but error rules still apply */
4000 138 : sign1 = numeric_sign_internal(num1);
4001 138 : sign2 = numeric_sign_internal(num2);
4002 138 : if (sign1 == 0 && sign2 < 0)
4003 6 : ereport(ERROR,
4004 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
4005 : errmsg("zero raised to a negative power is undefined")));
4006 132 : if (sign1 < 0 && !numeric_is_integral(num2))
4007 6 : ereport(ERROR,
4008 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
4009 : errmsg("a negative number raised to a non-integer power yields a complex result")));
4010 :
4011 : /*
4012 : * POSIX gives this series of rules for pow(3) with infinite inputs:
4013 : *
4014 : * For any value of y, if x is +1, 1.0 shall be returned.
4015 : */
4016 126 : if (!NUMERIC_IS_SPECIAL(num1))
4017 : {
4018 42 : init_var_from_num(num1, &arg1);
4019 42 : if (cmp_var(&arg1, &const_one) == 0)
4020 6 : PG_RETURN_NUMERIC(make_result(&const_one));
4021 : }
4022 :
4023 : /*
4024 : * For any value of x, if y is [-]0, 1.0 shall be returned.
4025 : */
4026 120 : if (sign2 == 0)
4027 12 : PG_RETURN_NUMERIC(make_result(&const_one));
4028 :
4029 : /*
4030 : * For any odd integer value of y > 0, if x is [-]0, [-]0 shall be
4031 : * returned. For y > 0 and not an odd integer, if x is [-]0, +0 shall
4032 : * be returned. (Since we don't deal in minus zero, we need not
4033 : * distinguish these two cases.)
4034 : */
4035 108 : if (sign1 == 0 && sign2 > 0)
4036 6 : PG_RETURN_NUMERIC(make_result(&const_zero));
4037 :
4038 : /*
4039 : * If x is -1, and y is [-]Inf, 1.0 shall be returned.
4040 : *
4041 : * For |x| < 1, if y is -Inf, +Inf shall be returned.
4042 : *
4043 : * For |x| > 1, if y is -Inf, +0 shall be returned.
4044 : *
4045 : * For |x| < 1, if y is +Inf, +0 shall be returned.
4046 : *
4047 : * For |x| > 1, if y is +Inf, +Inf shall be returned.
4048 : */
4049 102 : if (NUMERIC_IS_INF(num2))
4050 : {
4051 : bool abs_x_gt_one;
4052 :
4053 54 : if (NUMERIC_IS_SPECIAL(num1))
4054 24 : abs_x_gt_one = true; /* x is either Inf or -Inf */
4055 : else
4056 : {
4057 30 : init_var_from_num(num1, &arg1);
4058 30 : if (cmp_var(&arg1, &const_minus_one) == 0)
4059 6 : PG_RETURN_NUMERIC(make_result(&const_one));
4060 24 : arg1.sign = NUMERIC_POS; /* now arg1 = abs(x) */
4061 24 : abs_x_gt_one = (cmp_var(&arg1, &const_one) > 0);
4062 : }
4063 48 : if (abs_x_gt_one == (sign2 > 0))
4064 30 : PG_RETURN_NUMERIC(make_result(&const_pinf));
4065 : else
4066 18 : PG_RETURN_NUMERIC(make_result(&const_zero));
4067 : }
4068 :
4069 : /*
4070 : * For y < 0, if x is +Inf, +0 shall be returned.
4071 : *
4072 : * For y > 0, if x is +Inf, +Inf shall be returned.
4073 : */
4074 48 : if (NUMERIC_IS_PINF(num1))
4075 : {
4076 24 : if (sign2 > 0)
4077 18 : PG_RETURN_NUMERIC(make_result(&const_pinf));
4078 : else
4079 6 : PG_RETURN_NUMERIC(make_result(&const_zero));
4080 : }
4081 :
4082 : Assert(NUMERIC_IS_NINF(num1));
4083 :
4084 : /*
4085 : * For y an odd integer < 0, if x is -Inf, -0 shall be returned. For
4086 : * y < 0 and not an odd integer, if x is -Inf, +0 shall be returned.
4087 : * (Again, we need not distinguish these two cases.)
4088 : */
4089 24 : if (sign2 < 0)
4090 12 : PG_RETURN_NUMERIC(make_result(&const_zero));
4091 :
4092 : /*
4093 : * For y an odd integer > 0, if x is -Inf, -Inf shall be returned. For
4094 : * y > 0 and not an odd integer, if x is -Inf, +Inf shall be returned.
4095 : */
4096 12 : init_var_from_num(num2, &arg2);
4097 12 : if (arg2.ndigits > 0 && arg2.ndigits == arg2.weight + 1 &&
4098 12 : (arg2.digits[arg2.ndigits - 1] & 1))
4099 6 : PG_RETURN_NUMERIC(make_result(&const_ninf));
4100 : else
4101 6 : PG_RETURN_NUMERIC(make_result(&const_pinf));
4102 : }
4103 :
4104 : /*
4105 : * The SQL spec requires that we emit a particular SQLSTATE error code for
4106 : * certain error conditions. Specifically, we don't return a
4107 : * divide-by-zero error code for 0 ^ -1. Raising a negative number to a
4108 : * non-integer power must produce the same error code, but that case is
4109 : * handled in power_var().
4110 : */
4111 1410 : sign1 = numeric_sign_internal(num1);
4112 1410 : sign2 = numeric_sign_internal(num2);
4113 :
4114 1410 : if (sign1 == 0 && sign2 < 0)
4115 12 : ereport(ERROR,
4116 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
4117 : errmsg("zero raised to a negative power is undefined")));
4118 :
4119 : /*
4120 : * Initialize things
4121 : */
4122 1398 : init_var(&result);
4123 1398 : init_var_from_num(num1, &arg1);
4124 1398 : init_var_from_num(num2, &arg2);
4125 :
4126 : /*
4127 : * Call power_var() to compute and return the result; note it handles
4128 : * scale selection itself.
4129 : */
4130 1398 : power_var(&arg1, &arg2, &result);
4131 :
4132 1368 : res = make_result(&result);
4133 :
4134 1368 : free_var(&result);
4135 :
4136 1368 : PG_RETURN_NUMERIC(res);
4137 : }
4138 :
4139 : /*
4140 : * numeric_scale() -
4141 : *
4142 : * Returns the scale, i.e. the count of decimal digits in the fractional part
4143 : */
4144 : Datum
4145 108 : numeric_scale(PG_FUNCTION_ARGS)
4146 : {
4147 108 : Numeric num = PG_GETARG_NUMERIC(0);
4148 :
4149 108 : if (NUMERIC_IS_SPECIAL(num))
4150 18 : PG_RETURN_NULL();
4151 :
4152 90 : PG_RETURN_INT32(NUMERIC_DSCALE(num));
4153 : }
4154 :
4155 : /*
4156 : * Calculate minimum scale for value.
4157 : */
4158 : static int
4159 372 : get_min_scale(NumericVar *var)
4160 : {
4161 : int min_scale;
4162 : int last_digit_pos;
4163 :
4164 : /*
4165 : * Ordinarily, the input value will be "stripped" so that the last
4166 : * NumericDigit is nonzero. But we don't want to get into an infinite
4167 : * loop if it isn't, so explicitly find the last nonzero digit.
4168 : */
4169 372 : last_digit_pos = var->ndigits - 1;
4170 372 : while (last_digit_pos >= 0 &&
4171 342 : var->digits[last_digit_pos] == 0)
4172 0 : last_digit_pos--;
4173 :
4174 372 : if (last_digit_pos >= 0)
4175 : {
4176 : /* compute min_scale assuming that last ndigit has no zeroes */
4177 342 : min_scale = (last_digit_pos - var->weight) * DEC_DIGITS;
4178 :
4179 : /*
4180 : * We could get a negative result if there are no digits after the
4181 : * decimal point. In this case the min_scale must be zero.
4182 : */
4183 342 : if (min_scale > 0)
4184 : {
4185 : /*
4186 : * Reduce min_scale if trailing digit(s) in last NumericDigit are
4187 : * zero.
4188 : */
4189 186 : NumericDigit last_digit = var->digits[last_digit_pos];
4190 :
4191 498 : while (last_digit % 10 == 0)
4192 : {
4193 312 : min_scale--;
4194 312 : last_digit /= 10;
4195 : }
4196 : }
4197 : else
4198 156 : min_scale = 0;
4199 : }
4200 : else
4201 30 : min_scale = 0; /* result if input is zero */
4202 :
4203 372 : return min_scale;
4204 : }
4205 :
4206 : /*
4207 : * Returns minimum scale required to represent supplied value without loss.
4208 : */
4209 : Datum
4210 72 : numeric_min_scale(PG_FUNCTION_ARGS)
4211 : {
4212 72 : Numeric num = PG_GETARG_NUMERIC(0);
4213 : NumericVar arg;
4214 : int min_scale;
4215 :
4216 72 : if (NUMERIC_IS_SPECIAL(num))
4217 12 : PG_RETURN_NULL();
4218 :
4219 60 : init_var_from_num(num, &arg);
4220 60 : min_scale = get_min_scale(&arg);
4221 60 : free_var(&arg);
4222 :
4223 60 : PG_RETURN_INT32(min_scale);
4224 : }
4225 :
4226 : /*
4227 : * Reduce scale of numeric value to represent supplied value without loss.
4228 : */
4229 : Datum
4230 324 : numeric_trim_scale(PG_FUNCTION_ARGS)
4231 : {
4232 324 : Numeric num = PG_GETARG_NUMERIC(0);
4233 : Numeric res;
4234 : NumericVar result;
4235 :
4236 324 : if (NUMERIC_IS_SPECIAL(num))
4237 12 : PG_RETURN_NUMERIC(duplicate_numeric(num));
4238 :
4239 312 : init_var_from_num(num, &result);
4240 312 : result.dscale = get_min_scale(&result);
4241 312 : res = make_result(&result);
4242 312 : free_var(&result);
4243 :
4244 312 : PG_RETURN_NUMERIC(res);
4245 : }
4246 :
4247 : /*
4248 : * Return a random numeric value in the range [rmin, rmax].
4249 : */
4250 : Numeric
4251 33462 : random_numeric(pg_prng_state *state, Numeric rmin, Numeric rmax)
4252 : {
4253 : NumericVar rmin_var;
4254 : NumericVar rmax_var;
4255 : NumericVar result;
4256 : Numeric res;
4257 :
4258 : /* Range bounds must not be NaN/infinity */
4259 33462 : if (NUMERIC_IS_SPECIAL(rmin))
4260 : {
4261 12 : if (NUMERIC_IS_NAN(rmin))
4262 6 : ereport(ERROR,
4263 : errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4264 : errmsg("lower bound cannot be NaN"));
4265 : else
4266 6 : ereport(ERROR,
4267 : errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4268 : errmsg("lower bound cannot be infinity"));
4269 : }
4270 33450 : if (NUMERIC_IS_SPECIAL(rmax))
4271 : {
4272 12 : if (NUMERIC_IS_NAN(rmax))
4273 6 : ereport(ERROR,
4274 : errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4275 : errmsg("upper bound cannot be NaN"));
4276 : else
4277 6 : ereport(ERROR,
4278 : errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4279 : errmsg("upper bound cannot be infinity"));
4280 : }
4281 :
4282 : /* Return a random value in the range [rmin, rmax] */
4283 33438 : init_var_from_num(rmin, &rmin_var);
4284 33438 : init_var_from_num(rmax, &rmax_var);
4285 :
4286 33438 : init_var(&result);
4287 :
4288 33438 : random_var(state, &rmin_var, &rmax_var, &result);
4289 :
4290 33432 : res = make_result(&result);
4291 :
4292 33432 : free_var(&result);
4293 :
4294 33432 : return res;
4295 : }
4296 :
4297 :
4298 : /* ----------------------------------------------------------------------
4299 : *
4300 : * Type conversion functions
4301 : *
4302 : * ----------------------------------------------------------------------
4303 : */
4304 :
4305 : Numeric
4306 1868506 : int64_to_numeric(int64 val)
4307 : {
4308 : Numeric res;
4309 : NumericVar result;
4310 :
4311 1868506 : init_var(&result);
4312 :
4313 1868506 : int64_to_numericvar(val, &result);
4314 :
4315 1868506 : res = make_result(&result);
4316 :
4317 1868506 : free_var(&result);
4318 :
4319 1868506 : return res;
4320 : }
4321 :
4322 : /*
4323 : * Convert val1/(10**log10val2) to numeric. This is much faster than normal
4324 : * numeric division.
4325 : */
4326 : Numeric
4327 29380 : int64_div_fast_to_numeric(int64 val1, int log10val2)
4328 : {
4329 : Numeric res;
4330 : NumericVar result;
4331 : int rscale;
4332 : int w;
4333 : int m;
4334 :
4335 29380 : init_var(&result);
4336 :
4337 : /* result scale */
4338 29380 : rscale = log10val2 < 0 ? 0 : log10val2;
4339 :
4340 : /* how much to decrease the weight by */
4341 29380 : w = log10val2 / DEC_DIGITS;
4342 : /* how much is left to divide by */
4343 29380 : m = log10val2 % DEC_DIGITS;
4344 29380 : if (m < 0)
4345 : {
4346 0 : m += DEC_DIGITS;
4347 0 : w--;
4348 : }
4349 :
4350 : /*
4351 : * If there is anything left to divide by (10^m with 0 < m < DEC_DIGITS),
4352 : * multiply the dividend by 10^(DEC_DIGITS - m), and shift the weight by
4353 : * one more.
4354 : */
4355 29380 : if (m > 0)
4356 : {
4357 : #if DEC_DIGITS == 4
4358 : static const int pow10[] = {1, 10, 100, 1000};
4359 : #elif DEC_DIGITS == 2
4360 : static const int pow10[] = {1, 10};
4361 : #elif DEC_DIGITS == 1
4362 : static const int pow10[] = {1};
4363 : #else
4364 : #error unsupported NBASE
4365 : #endif
4366 29380 : int64 factor = pow10[DEC_DIGITS - m];
4367 : int64 new_val1;
4368 :
4369 : StaticAssertDecl(lengthof(pow10) == DEC_DIGITS, "mismatch with DEC_DIGITS");
4370 :
4371 29380 : if (unlikely(pg_mul_s64_overflow(val1, factor, &new_val1)))
4372 : {
4373 : /* do the multiplication using 128-bit integers */
4374 : INT128 tmp;
4375 :
4376 12 : tmp = int64_to_int128(0);
4377 12 : int128_add_int64_mul_int64(&tmp, val1, factor);
4378 :
4379 12 : int128_to_numericvar(tmp, &result);
4380 : }
4381 : else
4382 29368 : int64_to_numericvar(new_val1, &result);
4383 :
4384 29380 : w++;
4385 : }
4386 : else
4387 0 : int64_to_numericvar(val1, &result);
4388 :
4389 29380 : result.weight -= w;
4390 29380 : result.dscale = rscale;
4391 :
4392 29380 : res = make_result(&result);
4393 :
4394 29380 : free_var(&result);
4395 :
4396 29380 : return res;
4397 : }
4398 :
4399 : Datum
4400 1554994 : int4_numeric(PG_FUNCTION_ARGS)
4401 : {
4402 1554994 : int32 val = PG_GETARG_INT32(0);
4403 :
4404 1554994 : PG_RETURN_NUMERIC(int64_to_numeric(val));
4405 : }
4406 :
4407 : int32
4408 7752 : numeric_int4_opt_error(Numeric num, bool *have_error)
4409 : {
4410 : NumericVar x;
4411 : int32 result;
4412 :
4413 7752 : if (have_error)
4414 1584 : *have_error = false;
4415 :
4416 7752 : if (NUMERIC_IS_SPECIAL(num))
4417 : {
4418 18 : if (have_error)
4419 : {
4420 0 : *have_error = true;
4421 0 : return 0;
4422 : }
4423 : else
4424 : {
4425 18 : if (NUMERIC_IS_NAN(num))
4426 6 : ereport(ERROR,
4427 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4428 : errmsg("cannot convert NaN to %s", "integer")));
4429 : else
4430 12 : ereport(ERROR,
4431 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4432 : errmsg("cannot convert infinity to %s", "integer")));
4433 : }
4434 : }
4435 :
4436 : /* Convert to variable format, then convert to int4 */
4437 7734 : init_var_from_num(num, &x);
4438 :
4439 7734 : if (!numericvar_to_int32(&x, &result))
4440 : {
4441 90 : if (have_error)
4442 : {
4443 78 : *have_error = true;
4444 78 : return 0;
4445 : }
4446 : else
4447 : {
4448 12 : ereport(ERROR,
4449 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4450 : errmsg("integer out of range")));
4451 : }
4452 : }
4453 :
4454 7644 : return result;
4455 : }
4456 :
4457 : Datum
4458 6168 : numeric_int4(PG_FUNCTION_ARGS)
4459 : {
4460 6168 : Numeric num = PG_GETARG_NUMERIC(0);
4461 :
4462 6168 : PG_RETURN_INT32(numeric_int4_opt_error(num, NULL));
4463 : }
4464 :
4465 : /*
4466 : * Given a NumericVar, convert it to an int32. If the NumericVar
4467 : * exceeds the range of an int32, false is returned, otherwise true is returned.
4468 : * The input NumericVar is *not* free'd.
4469 : */
4470 : static bool
4471 8478 : numericvar_to_int32(const NumericVar *var, int32 *result)
4472 : {
4473 : int64 val;
4474 :
4475 8478 : if (!numericvar_to_int64(var, &val))
4476 6 : return false;
4477 :
4478 8472 : if (unlikely(val < PG_INT32_MIN) || unlikely(val > PG_INT32_MAX))
4479 84 : return false;
4480 :
4481 : /* Down-convert to int4 */
4482 8388 : *result = (int32) val;
4483 :
4484 8388 : return true;
4485 : }
4486 :
4487 : Datum
4488 36850 : int8_numeric(PG_FUNCTION_ARGS)
4489 : {
4490 36850 : int64 val = PG_GETARG_INT64(0);
4491 :
4492 36850 : PG_RETURN_NUMERIC(int64_to_numeric(val));
4493 : }
4494 :
4495 : int64
4496 570 : numeric_int8_opt_error(Numeric num, bool *have_error)
4497 : {
4498 : NumericVar x;
4499 : int64 result;
4500 :
4501 570 : if (have_error)
4502 48 : *have_error = false;
4503 :
4504 570 : if (NUMERIC_IS_SPECIAL(num))
4505 : {
4506 18 : if (have_error)
4507 : {
4508 0 : *have_error = true;
4509 0 : return 0;
4510 : }
4511 : else
4512 : {
4513 18 : if (NUMERIC_IS_NAN(num))
4514 6 : ereport(ERROR,
4515 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4516 : errmsg("cannot convert NaN to %s", "bigint")));
4517 : else
4518 12 : ereport(ERROR,
4519 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4520 : errmsg("cannot convert infinity to %s", "bigint")));
4521 : }
4522 : }
4523 :
4524 : /* Convert to variable format, then convert to int8 */
4525 552 : init_var_from_num(num, &x);
4526 :
4527 552 : if (!numericvar_to_int64(&x, &result))
4528 : {
4529 60 : if (have_error)
4530 : {
4531 12 : *have_error = true;
4532 12 : return 0;
4533 : }
4534 : else
4535 : {
4536 48 : ereport(ERROR,
4537 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4538 : errmsg("bigint out of range")));
4539 : }
4540 : }
4541 :
4542 492 : return result;
4543 : }
4544 :
4545 : Datum
4546 522 : numeric_int8(PG_FUNCTION_ARGS)
4547 : {
4548 522 : Numeric num = PG_GETARG_NUMERIC(0);
4549 :
4550 522 : PG_RETURN_INT64(numeric_int8_opt_error(num, NULL));
4551 : }
4552 :
4553 :
4554 : Datum
4555 6 : int2_numeric(PG_FUNCTION_ARGS)
4556 : {
4557 6 : int16 val = PG_GETARG_INT16(0);
4558 :
4559 6 : PG_RETURN_NUMERIC(int64_to_numeric(val));
4560 : }
4561 :
4562 :
4563 : Datum
4564 102 : numeric_int2(PG_FUNCTION_ARGS)
4565 : {
4566 102 : Numeric num = PG_GETARG_NUMERIC(0);
4567 : NumericVar x;
4568 : int64 val;
4569 : int16 result;
4570 :
4571 102 : if (NUMERIC_IS_SPECIAL(num))
4572 : {
4573 18 : if (NUMERIC_IS_NAN(num))
4574 6 : ereport(ERROR,
4575 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4576 : errmsg("cannot convert NaN to %s", "smallint")));
4577 : else
4578 12 : ereport(ERROR,
4579 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4580 : errmsg("cannot convert infinity to %s", "smallint")));
4581 : }
4582 :
4583 : /* Convert to variable format and thence to int8 */
4584 84 : init_var_from_num(num, &x);
4585 :
4586 84 : if (!numericvar_to_int64(&x, &val))
4587 0 : ereport(ERROR,
4588 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4589 : errmsg("smallint out of range")));
4590 :
4591 84 : if (unlikely(val < PG_INT16_MIN) || unlikely(val > PG_INT16_MAX))
4592 12 : ereport(ERROR,
4593 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4594 : errmsg("smallint out of range")));
4595 :
4596 : /* Down-convert to int2 */
4597 72 : result = (int16) val;
4598 :
4599 72 : PG_RETURN_INT16(result);
4600 : }
4601 :
4602 :
4603 : Datum
4604 1074 : float8_numeric(PG_FUNCTION_ARGS)
4605 : {
4606 1074 : float8 val = PG_GETARG_FLOAT8(0);
4607 : Numeric res;
4608 : NumericVar result;
4609 : char buf[DBL_DIG + 100];
4610 : const char *endptr;
4611 :
4612 1074 : if (isnan(val))
4613 6 : PG_RETURN_NUMERIC(make_result(&const_nan));
4614 :
4615 1068 : if (isinf(val))
4616 : {
4617 12 : if (val < 0)
4618 6 : PG_RETURN_NUMERIC(make_result(&const_ninf));
4619 : else
4620 6 : PG_RETURN_NUMERIC(make_result(&const_pinf));
4621 : }
4622 :
4623 1056 : snprintf(buf, sizeof(buf), "%.*g", DBL_DIG, val);
4624 :
4625 1056 : init_var(&result);
4626 :
4627 : /* Assume we need not worry about leading/trailing spaces */
4628 1056 : (void) set_var_from_str(buf, buf, &result, &endptr, NULL);
4629 :
4630 1056 : res = make_result(&result);
4631 :
4632 1056 : free_var(&result);
4633 :
4634 1056 : PG_RETURN_NUMERIC(res);
4635 : }
4636 :
4637 :
4638 : Datum
4639 519988 : numeric_float8(PG_FUNCTION_ARGS)
4640 : {
4641 519988 : Numeric num = PG_GETARG_NUMERIC(0);
4642 : char *tmp;
4643 : Datum result;
4644 :
4645 519988 : if (NUMERIC_IS_SPECIAL(num))
4646 : {
4647 78 : if (NUMERIC_IS_PINF(num))
4648 24 : PG_RETURN_FLOAT8(get_float8_infinity());
4649 54 : else if (NUMERIC_IS_NINF(num))
4650 24 : PG_RETURN_FLOAT8(-get_float8_infinity());
4651 : else
4652 30 : PG_RETURN_FLOAT8(get_float8_nan());
4653 : }
4654 :
4655 519910 : tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
4656 : NumericGetDatum(num)));
4657 :
4658 519910 : result = DirectFunctionCall1(float8in, CStringGetDatum(tmp));
4659 :
4660 519910 : pfree(tmp);
4661 :
4662 519910 : PG_RETURN_DATUM(result);
4663 : }
4664 :
4665 :
4666 : /*
4667 : * Convert numeric to float8; if out of range, return +/- HUGE_VAL
4668 : *
4669 : * (internal helper function, not directly callable from SQL)
4670 : */
4671 : Datum
4672 28 : numeric_float8_no_overflow(PG_FUNCTION_ARGS)
4673 : {
4674 28 : Numeric num = PG_GETARG_NUMERIC(0);
4675 : double val;
4676 :
4677 28 : if (NUMERIC_IS_SPECIAL(num))
4678 : {
4679 0 : if (NUMERIC_IS_PINF(num))
4680 0 : val = HUGE_VAL;
4681 0 : else if (NUMERIC_IS_NINF(num))
4682 0 : val = -HUGE_VAL;
4683 : else
4684 0 : val = get_float8_nan();
4685 : }
4686 : else
4687 : {
4688 : NumericVar x;
4689 :
4690 28 : init_var_from_num(num, &x);
4691 28 : val = numericvar_to_double_no_overflow(&x);
4692 : }
4693 :
4694 28 : PG_RETURN_FLOAT8(val);
4695 : }
4696 :
4697 : Datum
4698 22406 : float4_numeric(PG_FUNCTION_ARGS)
4699 : {
4700 22406 : float4 val = PG_GETARG_FLOAT4(0);
4701 : Numeric res;
4702 : NumericVar result;
4703 : char buf[FLT_DIG + 100];
4704 : const char *endptr;
4705 :
4706 22406 : if (isnan(val))
4707 6 : PG_RETURN_NUMERIC(make_result(&const_nan));
4708 :
4709 22400 : if (isinf(val))
4710 : {
4711 12 : if (val < 0)
4712 6 : PG_RETURN_NUMERIC(make_result(&const_ninf));
4713 : else
4714 6 : PG_RETURN_NUMERIC(make_result(&const_pinf));
4715 : }
4716 :
4717 22388 : snprintf(buf, sizeof(buf), "%.*g", FLT_DIG, val);
4718 :
4719 22388 : init_var(&result);
4720 :
4721 : /* Assume we need not worry about leading/trailing spaces */
4722 22388 : (void) set_var_from_str(buf, buf, &result, &endptr, NULL);
4723 :
4724 22388 : res = make_result(&result);
4725 :
4726 22388 : free_var(&result);
4727 :
4728 22388 : PG_RETURN_NUMERIC(res);
4729 : }
4730 :
4731 :
4732 : Datum
4733 2456 : numeric_float4(PG_FUNCTION_ARGS)
4734 : {
4735 2456 : Numeric num = PG_GETARG_NUMERIC(0);
4736 : char *tmp;
4737 : Datum result;
4738 :
4739 2456 : if (NUMERIC_IS_SPECIAL(num))
4740 : {
4741 78 : if (NUMERIC_IS_PINF(num))
4742 24 : PG_RETURN_FLOAT4(get_float4_infinity());
4743 54 : else if (NUMERIC_IS_NINF(num))
4744 24 : PG_RETURN_FLOAT4(-get_float4_infinity());
4745 : else
4746 30 : PG_RETURN_FLOAT4(get_float4_nan());
4747 : }
4748 :
4749 2378 : tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
4750 : NumericGetDatum(num)));
4751 :
4752 2378 : result = DirectFunctionCall1(float4in, CStringGetDatum(tmp));
4753 :
4754 2378 : pfree(tmp);
4755 :
4756 2378 : PG_RETURN_DATUM(result);
4757 : }
4758 :
4759 :
4760 : Datum
4761 120 : numeric_pg_lsn(PG_FUNCTION_ARGS)
4762 : {
4763 120 : Numeric num = PG_GETARG_NUMERIC(0);
4764 : NumericVar x;
4765 : XLogRecPtr result;
4766 :
4767 120 : if (NUMERIC_IS_SPECIAL(num))
4768 : {
4769 6 : if (NUMERIC_IS_NAN(num))
4770 6 : ereport(ERROR,
4771 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4772 : errmsg("cannot convert NaN to %s", "pg_lsn")));
4773 : else
4774 0 : ereport(ERROR,
4775 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4776 : errmsg("cannot convert infinity to %s", "pg_lsn")));
4777 : }
4778 :
4779 : /* Convert to variable format and thence to pg_lsn */
4780 114 : init_var_from_num(num, &x);
4781 :
4782 114 : if (!numericvar_to_uint64(&x, (uint64 *) &result))
4783 24 : ereport(ERROR,
4784 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4785 : errmsg("pg_lsn out of range")));
4786 :
4787 90 : PG_RETURN_LSN(result);
4788 : }
4789 :
4790 :
4791 : /* ----------------------------------------------------------------------
4792 : *
4793 : * Aggregate functions
4794 : *
4795 : * The transition datatype for all these aggregates is declared as INTERNAL.
4796 : * Actually, it's a pointer to a NumericAggState allocated in the aggregate
4797 : * context. The digit buffers for the NumericVars will be there too.
4798 : *
4799 : * For integer inputs, some aggregates use special-purpose 64-bit or 128-bit
4800 : * integer based transition datatypes to speed up calculations.
4801 : *
4802 : * ----------------------------------------------------------------------
4803 : */
4804 :
4805 : typedef struct NumericAggState
4806 : {
4807 : bool calcSumX2; /* if true, calculate sumX2 */
4808 : MemoryContext agg_context; /* context we're calculating in */
4809 : int64 N; /* count of processed numbers */
4810 : NumericSumAccum sumX; /* sum of processed numbers */
4811 : NumericSumAccum sumX2; /* sum of squares of processed numbers */
4812 : int maxScale; /* maximum scale seen so far */
4813 : int64 maxScaleCount; /* number of values seen with maximum scale */
4814 : /* These counts are *not* included in N! Use NA_TOTAL_COUNT() as needed */
4815 : int64 NaNcount; /* count of NaN values */
4816 : int64 pInfcount; /* count of +Inf values */
4817 : int64 nInfcount; /* count of -Inf values */
4818 : } NumericAggState;
4819 :
4820 : #define NA_TOTAL_COUNT(na) \
4821 : ((na)->N + (na)->NaNcount + (na)->pInfcount + (na)->nInfcount)
4822 :
4823 : /*
4824 : * Prepare state data for a numeric aggregate function that needs to compute
4825 : * sum, count and optionally sum of squares of the input.
4826 : */
4827 : static NumericAggState *
4828 171136 : makeNumericAggState(FunctionCallInfo fcinfo, bool calcSumX2)
4829 : {
4830 : NumericAggState *state;
4831 : MemoryContext agg_context;
4832 : MemoryContext old_context;
4833 :
4834 171136 : if (!AggCheckCallContext(fcinfo, &agg_context))
4835 0 : elog(ERROR, "aggregate function called in non-aggregate context");
4836 :
4837 171136 : old_context = MemoryContextSwitchTo(agg_context);
4838 :
4839 171136 : state = (NumericAggState *) palloc0(sizeof(NumericAggState));
4840 171136 : state->calcSumX2 = calcSumX2;
4841 171136 : state->agg_context = agg_context;
4842 :
4843 171136 : MemoryContextSwitchTo(old_context);
4844 :
4845 171136 : return state;
4846 : }
4847 :
4848 : /*
4849 : * Like makeNumericAggState(), but allocate the state in the current memory
4850 : * context.
4851 : */
4852 : static NumericAggState *
4853 80 : makeNumericAggStateCurrentContext(bool calcSumX2)
4854 : {
4855 : NumericAggState *state;
4856 :
4857 80 : state = (NumericAggState *) palloc0(sizeof(NumericAggState));
4858 80 : state->calcSumX2 = calcSumX2;
4859 80 : state->agg_context = CurrentMemoryContext;
4860 :
4861 80 : return state;
4862 : }
4863 :
4864 : /*
4865 : * Accumulate a new input value for numeric aggregate functions.
4866 : */
4867 : static void
4868 2113552 : do_numeric_accum(NumericAggState *state, Numeric newval)
4869 : {
4870 : NumericVar X;
4871 : NumericVar X2;
4872 : MemoryContext old_context;
4873 :
4874 : /* Count NaN/infinity inputs separately from all else */
4875 2113552 : if (NUMERIC_IS_SPECIAL(newval))
4876 : {
4877 162 : if (NUMERIC_IS_PINF(newval))
4878 72 : state->pInfcount++;
4879 90 : else if (NUMERIC_IS_NINF(newval))
4880 36 : state->nInfcount++;
4881 : else
4882 54 : state->NaNcount++;
4883 162 : return;
4884 : }
4885 :
4886 : /* load processed number in short-lived context */
4887 2113390 : init_var_from_num(newval, &X);
4888 :
4889 : /*
4890 : * Track the highest input dscale that we've seen, to support inverse
4891 : * transitions (see do_numeric_discard).
4892 : */
4893 2113390 : if (X.dscale > state->maxScale)
4894 : {
4895 156 : state->maxScale = X.dscale;
4896 156 : state->maxScaleCount = 1;
4897 : }
4898 2113234 : else if (X.dscale == state->maxScale)
4899 2113198 : state->maxScaleCount++;
4900 :
4901 : /* if we need X^2, calculate that in short-lived context */
4902 2113390 : if (state->calcSumX2)
4903 : {
4904 240732 : init_var(&X2);
4905 240732 : mul_var(&X, &X, &X2, X.dscale * 2);
4906 : }
4907 :
4908 : /* The rest of this needs to work in the aggregate context */
4909 2113390 : old_context = MemoryContextSwitchTo(state->agg_context);
4910 :
4911 2113390 : state->N++;
4912 :
4913 : /* Accumulate sums */
4914 2113390 : accum_sum_add(&(state->sumX), &X);
4915 :
4916 2113390 : if (state->calcSumX2)
4917 240732 : accum_sum_add(&(state->sumX2), &X2);
4918 :
4919 2113390 : MemoryContextSwitchTo(old_context);
4920 : }
4921 :
4922 : /*
4923 : * Attempt to remove an input value from the aggregated state.
4924 : *
4925 : * If the value cannot be removed then the function will return false; the
4926 : * possible reasons for failing are described below.
4927 : *
4928 : * If we aggregate the values 1.01 and 2 then the result will be 3.01.
4929 : * If we are then asked to un-aggregate the 1.01 then we must fail as we
4930 : * won't be able to tell what the new aggregated value's dscale should be.
4931 : * We don't want to return 2.00 (dscale = 2), since the sum's dscale would
4932 : * have been zero if we'd really aggregated only 2.
4933 : *
4934 : * Note: alternatively, we could count the number of inputs with each possible
4935 : * dscale (up to some sane limit). Not yet clear if it's worth the trouble.
4936 : */
4937 : static bool
4938 342 : do_numeric_discard(NumericAggState *state, Numeric newval)
4939 : {
4940 : NumericVar X;
4941 : NumericVar X2;
4942 : MemoryContext old_context;
4943 :
4944 : /* Count NaN/infinity inputs separately from all else */
4945 342 : if (NUMERIC_IS_SPECIAL(newval))
4946 : {
4947 6 : if (NUMERIC_IS_PINF(newval))
4948 0 : state->pInfcount--;
4949 6 : else if (NUMERIC_IS_NINF(newval))
4950 0 : state->nInfcount--;
4951 : else
4952 6 : state->NaNcount--;
4953 6 : return true;
4954 : }
4955 :
4956 : /* load processed number in short-lived context */
4957 336 : init_var_from_num(newval, &X);
4958 :
4959 : /*
4960 : * state->sumX's dscale is the maximum dscale of any of the inputs.
4961 : * Removing the last input with that dscale would require us to recompute
4962 : * the maximum dscale of the *remaining* inputs, which we cannot do unless
4963 : * no more non-NaN inputs remain at all. So we report a failure instead,
4964 : * and force the aggregation to be redone from scratch.
4965 : */
4966 336 : if (X.dscale == state->maxScale)
4967 : {
4968 336 : if (state->maxScaleCount > 1 || state->maxScale == 0)
4969 : {
4970 : /*
4971 : * Some remaining inputs have same dscale, or dscale hasn't gotten
4972 : * above zero anyway
4973 : */
4974 318 : state->maxScaleCount--;
4975 : }
4976 18 : else if (state->N == 1)
4977 : {
4978 : /* No remaining non-NaN inputs at all, so reset maxScale */
4979 12 : state->maxScale = 0;
4980 12 : state->maxScaleCount = 0;
4981 : }
4982 : else
4983 : {
4984 : /* Correct new maxScale is uncertain, must fail */
4985 6 : return false;
4986 : }
4987 : }
4988 :
4989 : /* if we need X^2, calculate that in short-lived context */
4990 330 : if (state->calcSumX2)
4991 : {
4992 288 : init_var(&X2);
4993 288 : mul_var(&X, &X, &X2, X.dscale * 2);
4994 : }
4995 :
4996 : /* The rest of this needs to work in the aggregate context */
4997 330 : old_context = MemoryContextSwitchTo(state->agg_context);
4998 :
4999 330 : if (state->N-- > 1)
5000 : {
5001 : /* Negate X, to subtract it from the sum */
5002 312 : X.sign = (X.sign == NUMERIC_POS ? NUMERIC_NEG : NUMERIC_POS);
5003 312 : accum_sum_add(&(state->sumX), &X);
5004 :
5005 312 : if (state->calcSumX2)
5006 : {
5007 : /* Negate X^2. X^2 is always positive */
5008 288 : X2.sign = NUMERIC_NEG;
5009 288 : accum_sum_add(&(state->sumX2), &X2);
5010 : }
5011 : }
5012 : else
5013 : {
5014 : /* Zero the sums */
5015 : Assert(state->N == 0);
5016 :
5017 18 : accum_sum_reset(&state->sumX);
5018 18 : if (state->calcSumX2)
5019 0 : accum_sum_reset(&state->sumX2);
5020 : }
5021 :
5022 330 : MemoryContextSwitchTo(old_context);
5023 :
5024 330 : return true;
5025 : }
5026 :
5027 : /*
5028 : * Generic transition function for numeric aggregates that require sumX2.
5029 : */
5030 : Datum
5031 642 : numeric_accum(PG_FUNCTION_ARGS)
5032 : {
5033 : NumericAggState *state;
5034 :
5035 642 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
5036 :
5037 : /* Create the state data on the first call */
5038 642 : if (state == NULL)
5039 174 : state = makeNumericAggState(fcinfo, true);
5040 :
5041 642 : if (!PG_ARGISNULL(1))
5042 624 : do_numeric_accum(state, PG_GETARG_NUMERIC(1));
5043 :
5044 642 : PG_RETURN_POINTER(state);
5045 : }
5046 :
5047 : /*
5048 : * Generic combine function for numeric aggregates which require sumX2
5049 : */
5050 : Datum
5051 34 : numeric_combine(PG_FUNCTION_ARGS)
5052 : {
5053 : NumericAggState *state1;
5054 : NumericAggState *state2;
5055 : MemoryContext agg_context;
5056 : MemoryContext old_context;
5057 :
5058 34 : if (!AggCheckCallContext(fcinfo, &agg_context))
5059 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5060 :
5061 34 : state1 = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
5062 34 : state2 = PG_ARGISNULL(1) ? NULL : (NumericAggState *) PG_GETARG_POINTER(1);
5063 :
5064 34 : if (state2 == NULL)
5065 0 : PG_RETURN_POINTER(state1);
5066 :
5067 : /* manually copy all fields from state2 to state1 */
5068 34 : if (state1 == NULL)
5069 : {
5070 18 : old_context = MemoryContextSwitchTo(agg_context);
5071 :
5072 18 : state1 = makeNumericAggStateCurrentContext(true);
5073 18 : state1->N = state2->N;
5074 18 : state1->NaNcount = state2->NaNcount;
5075 18 : state1->pInfcount = state2->pInfcount;
5076 18 : state1->nInfcount = state2->nInfcount;
5077 18 : state1->maxScale = state2->maxScale;
5078 18 : state1->maxScaleCount = state2->maxScaleCount;
5079 :
5080 18 : accum_sum_copy(&state1->sumX, &state2->sumX);
5081 18 : accum_sum_copy(&state1->sumX2, &state2->sumX2);
5082 :
5083 18 : MemoryContextSwitchTo(old_context);
5084 :
5085 18 : PG_RETURN_POINTER(state1);
5086 : }
5087 :
5088 16 : state1->N += state2->N;
5089 16 : state1->NaNcount += state2->NaNcount;
5090 16 : state1->pInfcount += state2->pInfcount;
5091 16 : state1->nInfcount += state2->nInfcount;
5092 :
5093 16 : if (state2->N > 0)
5094 : {
5095 : /*
5096 : * These are currently only needed for moving aggregates, but let's do
5097 : * the right thing anyway...
5098 : */
5099 16 : if (state2->maxScale > state1->maxScale)
5100 : {
5101 0 : state1->maxScale = state2->maxScale;
5102 0 : state1->maxScaleCount = state2->maxScaleCount;
5103 : }
5104 16 : else if (state2->maxScale == state1->maxScale)
5105 16 : state1->maxScaleCount += state2->maxScaleCount;
5106 :
5107 : /* The rest of this needs to work in the aggregate context */
5108 16 : old_context = MemoryContextSwitchTo(agg_context);
5109 :
5110 : /* Accumulate sums */
5111 16 : accum_sum_combine(&state1->sumX, &state2->sumX);
5112 16 : accum_sum_combine(&state1->sumX2, &state2->sumX2);
5113 :
5114 16 : MemoryContextSwitchTo(old_context);
5115 : }
5116 16 : PG_RETURN_POINTER(state1);
5117 : }
5118 :
5119 : /*
5120 : * Generic transition function for numeric aggregates that don't require sumX2.
5121 : */
5122 : Datum
5123 1872808 : numeric_avg_accum(PG_FUNCTION_ARGS)
5124 : {
5125 : NumericAggState *state;
5126 :
5127 1872808 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
5128 :
5129 : /* Create the state data on the first call */
5130 1872808 : if (state == NULL)
5131 170904 : state = makeNumericAggState(fcinfo, false);
5132 :
5133 1872808 : if (!PG_ARGISNULL(1))
5134 1872748 : do_numeric_accum(state, PG_GETARG_NUMERIC(1));
5135 :
5136 1872808 : PG_RETURN_POINTER(state);
5137 : }
5138 :
5139 : /*
5140 : * Combine function for numeric aggregates which don't require sumX2
5141 : */
5142 : Datum
5143 22 : numeric_avg_combine(PG_FUNCTION_ARGS)
5144 : {
5145 : NumericAggState *state1;
5146 : NumericAggState *state2;
5147 : MemoryContext agg_context;
5148 : MemoryContext old_context;
5149 :
5150 22 : if (!AggCheckCallContext(fcinfo, &agg_context))
5151 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5152 :
5153 22 : state1 = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
5154 22 : state2 = PG_ARGISNULL(1) ? NULL : (NumericAggState *) PG_GETARG_POINTER(1);
5155 :
5156 22 : if (state2 == NULL)
5157 0 : PG_RETURN_POINTER(state1);
5158 :
5159 : /* manually copy all fields from state2 to state1 */
5160 22 : if (state1 == NULL)
5161 : {
5162 6 : old_context = MemoryContextSwitchTo(agg_context);
5163 :
5164 6 : state1 = makeNumericAggStateCurrentContext(false);
5165 6 : state1->N = state2->N;
5166 6 : state1->NaNcount = state2->NaNcount;
5167 6 : state1->pInfcount = state2->pInfcount;
5168 6 : state1->nInfcount = state2->nInfcount;
5169 6 : state1->maxScale = state2->maxScale;
5170 6 : state1->maxScaleCount = state2->maxScaleCount;
5171 :
5172 6 : accum_sum_copy(&state1->sumX, &state2->sumX);
5173 :
5174 6 : MemoryContextSwitchTo(old_context);
5175 :
5176 6 : PG_RETURN_POINTER(state1);
5177 : }
5178 :
5179 16 : state1->N += state2->N;
5180 16 : state1->NaNcount += state2->NaNcount;
5181 16 : state1->pInfcount += state2->pInfcount;
5182 16 : state1->nInfcount += state2->nInfcount;
5183 :
5184 16 : if (state2->N > 0)
5185 : {
5186 : /*
5187 : * These are currently only needed for moving aggregates, but let's do
5188 : * the right thing anyway...
5189 : */
5190 16 : if (state2->maxScale > state1->maxScale)
5191 : {
5192 0 : state1->maxScale = state2->maxScale;
5193 0 : state1->maxScaleCount = state2->maxScaleCount;
5194 : }
5195 16 : else if (state2->maxScale == state1->maxScale)
5196 16 : state1->maxScaleCount += state2->maxScaleCount;
5197 :
5198 : /* The rest of this needs to work in the aggregate context */
5199 16 : old_context = MemoryContextSwitchTo(agg_context);
5200 :
5201 : /* Accumulate sums */
5202 16 : accum_sum_combine(&state1->sumX, &state2->sumX);
5203 :
5204 16 : MemoryContextSwitchTo(old_context);
5205 : }
5206 16 : PG_RETURN_POINTER(state1);
5207 : }
5208 :
5209 : /*
5210 : * numeric_avg_serialize
5211 : * Serialize NumericAggState for numeric aggregates that don't require
5212 : * sumX2.
5213 : */
5214 : Datum
5215 22 : numeric_avg_serialize(PG_FUNCTION_ARGS)
5216 : {
5217 : NumericAggState *state;
5218 : StringInfoData buf;
5219 : bytea *result;
5220 : NumericVar tmp_var;
5221 :
5222 : /* Ensure we disallow calling when not in aggregate context */
5223 22 : if (!AggCheckCallContext(fcinfo, NULL))
5224 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5225 :
5226 22 : state = (NumericAggState *) PG_GETARG_POINTER(0);
5227 :
5228 22 : init_var(&tmp_var);
5229 :
5230 22 : pq_begintypsend(&buf);
5231 :
5232 : /* N */
5233 22 : pq_sendint64(&buf, state->N);
5234 :
5235 : /* sumX */
5236 22 : accum_sum_final(&state->sumX, &tmp_var);
5237 22 : numericvar_serialize(&buf, &tmp_var);
5238 :
5239 : /* maxScale */
5240 22 : pq_sendint32(&buf, state->maxScale);
5241 :
5242 : /* maxScaleCount */
5243 22 : pq_sendint64(&buf, state->maxScaleCount);
5244 :
5245 : /* NaNcount */
5246 22 : pq_sendint64(&buf, state->NaNcount);
5247 :
5248 : /* pInfcount */
5249 22 : pq_sendint64(&buf, state->pInfcount);
5250 :
5251 : /* nInfcount */
5252 22 : pq_sendint64(&buf, state->nInfcount);
5253 :
5254 22 : result = pq_endtypsend(&buf);
5255 :
5256 22 : free_var(&tmp_var);
5257 :
5258 22 : PG_RETURN_BYTEA_P(result);
5259 : }
5260 :
5261 : /*
5262 : * numeric_avg_deserialize
5263 : * Deserialize bytea into NumericAggState for numeric aggregates that
5264 : * don't require sumX2.
5265 : */
5266 : Datum
5267 22 : numeric_avg_deserialize(PG_FUNCTION_ARGS)
5268 : {
5269 : bytea *sstate;
5270 : NumericAggState *result;
5271 : StringInfoData buf;
5272 : NumericVar tmp_var;
5273 :
5274 22 : if (!AggCheckCallContext(fcinfo, NULL))
5275 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5276 :
5277 22 : sstate = PG_GETARG_BYTEA_PP(0);
5278 :
5279 22 : init_var(&tmp_var);
5280 :
5281 : /*
5282 : * Initialize a StringInfo so that we can "receive" it using the standard
5283 : * recv-function infrastructure.
5284 : */
5285 22 : initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
5286 22 : VARSIZE_ANY_EXHDR(sstate));
5287 :
5288 22 : result = makeNumericAggStateCurrentContext(false);
5289 :
5290 : /* N */
5291 22 : result->N = pq_getmsgint64(&buf);
5292 :
5293 : /* sumX */
5294 22 : numericvar_deserialize(&buf, &tmp_var);
5295 22 : accum_sum_add(&(result->sumX), &tmp_var);
5296 :
5297 : /* maxScale */
5298 22 : result->maxScale = pq_getmsgint(&buf, 4);
5299 :
5300 : /* maxScaleCount */
5301 22 : result->maxScaleCount = pq_getmsgint64(&buf);
5302 :
5303 : /* NaNcount */
5304 22 : result->NaNcount = pq_getmsgint64(&buf);
5305 :
5306 : /* pInfcount */
5307 22 : result->pInfcount = pq_getmsgint64(&buf);
5308 :
5309 : /* nInfcount */
5310 22 : result->nInfcount = pq_getmsgint64(&buf);
5311 :
5312 22 : pq_getmsgend(&buf);
5313 :
5314 22 : free_var(&tmp_var);
5315 :
5316 22 : PG_RETURN_POINTER(result);
5317 : }
5318 :
5319 : /*
5320 : * numeric_serialize
5321 : * Serialization function for NumericAggState for numeric aggregates that
5322 : * require sumX2.
5323 : */
5324 : Datum
5325 34 : numeric_serialize(PG_FUNCTION_ARGS)
5326 : {
5327 : NumericAggState *state;
5328 : StringInfoData buf;
5329 : bytea *result;
5330 : NumericVar tmp_var;
5331 :
5332 : /* Ensure we disallow calling when not in aggregate context */
5333 34 : if (!AggCheckCallContext(fcinfo, NULL))
5334 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5335 :
5336 34 : state = (NumericAggState *) PG_GETARG_POINTER(0);
5337 :
5338 34 : init_var(&tmp_var);
5339 :
5340 34 : pq_begintypsend(&buf);
5341 :
5342 : /* N */
5343 34 : pq_sendint64(&buf, state->N);
5344 :
5345 : /* sumX */
5346 34 : accum_sum_final(&state->sumX, &tmp_var);
5347 34 : numericvar_serialize(&buf, &tmp_var);
5348 :
5349 : /* sumX2 */
5350 34 : accum_sum_final(&state->sumX2, &tmp_var);
5351 34 : numericvar_serialize(&buf, &tmp_var);
5352 :
5353 : /* maxScale */
5354 34 : pq_sendint32(&buf, state->maxScale);
5355 :
5356 : /* maxScaleCount */
5357 34 : pq_sendint64(&buf, state->maxScaleCount);
5358 :
5359 : /* NaNcount */
5360 34 : pq_sendint64(&buf, state->NaNcount);
5361 :
5362 : /* pInfcount */
5363 34 : pq_sendint64(&buf, state->pInfcount);
5364 :
5365 : /* nInfcount */
5366 34 : pq_sendint64(&buf, state->nInfcount);
5367 :
5368 34 : result = pq_endtypsend(&buf);
5369 :
5370 34 : free_var(&tmp_var);
5371 :
5372 34 : PG_RETURN_BYTEA_P(result);
5373 : }
5374 :
5375 : /*
5376 : * numeric_deserialize
5377 : * Deserialization function for NumericAggState for numeric aggregates that
5378 : * require sumX2.
5379 : */
5380 : Datum
5381 34 : numeric_deserialize(PG_FUNCTION_ARGS)
5382 : {
5383 : bytea *sstate;
5384 : NumericAggState *result;
5385 : StringInfoData buf;
5386 : NumericVar tmp_var;
5387 :
5388 34 : if (!AggCheckCallContext(fcinfo, NULL))
5389 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5390 :
5391 34 : sstate = PG_GETARG_BYTEA_PP(0);
5392 :
5393 34 : init_var(&tmp_var);
5394 :
5395 : /*
5396 : * Initialize a StringInfo so that we can "receive" it using the standard
5397 : * recv-function infrastructure.
5398 : */
5399 34 : initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
5400 34 : VARSIZE_ANY_EXHDR(sstate));
5401 :
5402 34 : result = makeNumericAggStateCurrentContext(false);
5403 :
5404 : /* N */
5405 34 : result->N = pq_getmsgint64(&buf);
5406 :
5407 : /* sumX */
5408 34 : numericvar_deserialize(&buf, &tmp_var);
5409 34 : accum_sum_add(&(result->sumX), &tmp_var);
5410 :
5411 : /* sumX2 */
5412 34 : numericvar_deserialize(&buf, &tmp_var);
5413 34 : accum_sum_add(&(result->sumX2), &tmp_var);
5414 :
5415 : /* maxScale */
5416 34 : result->maxScale = pq_getmsgint(&buf, 4);
5417 :
5418 : /* maxScaleCount */
5419 34 : result->maxScaleCount = pq_getmsgint64(&buf);
5420 :
5421 : /* NaNcount */
5422 34 : result->NaNcount = pq_getmsgint64(&buf);
5423 :
5424 : /* pInfcount */
5425 34 : result->pInfcount = pq_getmsgint64(&buf);
5426 :
5427 : /* nInfcount */
5428 34 : result->nInfcount = pq_getmsgint64(&buf);
5429 :
5430 34 : pq_getmsgend(&buf);
5431 :
5432 34 : free_var(&tmp_var);
5433 :
5434 34 : PG_RETURN_POINTER(result);
5435 : }
5436 :
5437 : /*
5438 : * Generic inverse transition function for numeric aggregates
5439 : * (with or without requirement for X^2).
5440 : */
5441 : Datum
5442 228 : numeric_accum_inv(PG_FUNCTION_ARGS)
5443 : {
5444 : NumericAggState *state;
5445 :
5446 228 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
5447 :
5448 : /* Should not get here with no state */
5449 228 : if (state == NULL)
5450 0 : elog(ERROR, "numeric_accum_inv called with NULL state");
5451 :
5452 228 : if (!PG_ARGISNULL(1))
5453 : {
5454 : /* If we fail to perform the inverse transition, return NULL */
5455 198 : if (!do_numeric_discard(state, PG_GETARG_NUMERIC(1)))
5456 6 : PG_RETURN_NULL();
5457 : }
5458 :
5459 222 : PG_RETURN_POINTER(state);
5460 : }
5461 :
5462 :
5463 : /*
5464 : * Integer data types in general use Numeric accumulators to share code and
5465 : * avoid risk of overflow. However for performance reasons optimized
5466 : * special-purpose accumulator routines are used when possible:
5467 : *
5468 : * For 16-bit and 32-bit inputs, N and sum(X) fit into 64-bit, so 64-bit
5469 : * accumulators are used for SUM and AVG of these data types.
5470 : *
5471 : * For 16-bit and 32-bit inputs, sum(X^2) fits into 128-bit, so 128-bit
5472 : * accumulators are used for STDDEV_POP, STDDEV_SAMP, VAR_POP, and VAR_SAMP of
5473 : * these data types.
5474 : *
5475 : * For 64-bit inputs, sum(X) fits into 128-bit, so a 128-bit accumulator is
5476 : * used for SUM(int8) and AVG(int8).
5477 : */
5478 :
5479 : typedef struct Int128AggState
5480 : {
5481 : bool calcSumX2; /* if true, calculate sumX2 */
5482 : int64 N; /* count of processed numbers */
5483 : INT128 sumX; /* sum of processed numbers */
5484 : INT128 sumX2; /* sum of squares of processed numbers */
5485 : } Int128AggState;
5486 :
5487 : /*
5488 : * Prepare state data for a 128-bit aggregate function that needs to compute
5489 : * sum, count and optionally sum of squares of the input.
5490 : */
5491 : static Int128AggState *
5492 966 : makeInt128AggState(FunctionCallInfo fcinfo, bool calcSumX2)
5493 : {
5494 : Int128AggState *state;
5495 : MemoryContext agg_context;
5496 : MemoryContext old_context;
5497 :
5498 966 : if (!AggCheckCallContext(fcinfo, &agg_context))
5499 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5500 :
5501 966 : old_context = MemoryContextSwitchTo(agg_context);
5502 :
5503 966 : state = (Int128AggState *) palloc0(sizeof(Int128AggState));
5504 966 : state->calcSumX2 = calcSumX2;
5505 :
5506 966 : MemoryContextSwitchTo(old_context);
5507 :
5508 966 : return state;
5509 : }
5510 :
5511 : /*
5512 : * Like makeInt128AggState(), but allocate the state in the current memory
5513 : * context.
5514 : */
5515 : static Int128AggState *
5516 50 : makeInt128AggStateCurrentContext(bool calcSumX2)
5517 : {
5518 : Int128AggState *state;
5519 :
5520 50 : state = (Int128AggState *) palloc0(sizeof(Int128AggState));
5521 50 : state->calcSumX2 = calcSumX2;
5522 :
5523 50 : return state;
5524 : }
5525 :
5526 : /*
5527 : * Accumulate a new input value for 128-bit aggregate functions.
5528 : */
5529 : static void
5530 557482 : do_int128_accum(Int128AggState *state, int64 newval)
5531 : {
5532 557482 : if (state->calcSumX2)
5533 242360 : int128_add_int64_mul_int64(&state->sumX2, newval, newval);
5534 :
5535 557482 : int128_add_int64(&state->sumX, newval);
5536 557482 : state->N++;
5537 557482 : }
5538 :
5539 : /*
5540 : * Remove an input value from the aggregated state.
5541 : */
5542 : static void
5543 312 : do_int128_discard(Int128AggState *state, int64 newval)
5544 : {
5545 312 : if (state->calcSumX2)
5546 288 : int128_sub_int64_mul_int64(&state->sumX2, newval, newval);
5547 :
5548 312 : int128_sub_int64(&state->sumX, newval);
5549 312 : state->N--;
5550 312 : }
5551 :
5552 : Datum
5553 198 : int2_accum(PG_FUNCTION_ARGS)
5554 : {
5555 : Int128AggState *state;
5556 :
5557 198 : state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
5558 :
5559 : /* Create the state data on the first call */
5560 198 : if (state == NULL)
5561 36 : state = makeInt128AggState(fcinfo, true);
5562 :
5563 198 : if (!PG_ARGISNULL(1))
5564 180 : do_int128_accum(state, PG_GETARG_INT16(1));
5565 :
5566 198 : PG_RETURN_POINTER(state);
5567 : }
5568 :
5569 : Datum
5570 242198 : int4_accum(PG_FUNCTION_ARGS)
5571 : {
5572 : Int128AggState *state;
5573 :
5574 242198 : state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
5575 :
5576 : /* Create the state data on the first call */
5577 242198 : if (state == NULL)
5578 78 : state = makeInt128AggState(fcinfo, true);
5579 :
5580 242198 : if (!PG_ARGISNULL(1))
5581 242180 : do_int128_accum(state, PG_GETARG_INT32(1));
5582 :
5583 242198 : PG_RETURN_POINTER(state);
5584 : }
5585 :
5586 : Datum
5587 240198 : int8_accum(PG_FUNCTION_ARGS)
5588 : {
5589 : NumericAggState *state;
5590 :
5591 240198 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
5592 :
5593 : /* Create the state data on the first call */
5594 240198 : if (state == NULL)
5595 58 : state = makeNumericAggState(fcinfo, true);
5596 :
5597 240198 : if (!PG_ARGISNULL(1))
5598 240180 : do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT64(1)));
5599 :
5600 240198 : PG_RETURN_POINTER(state);
5601 : }
5602 :
5603 : /*
5604 : * Combine function for Int128AggState for aggregates which require sumX2
5605 : */
5606 : Datum
5607 22 : numeric_poly_combine(PG_FUNCTION_ARGS)
5608 : {
5609 : Int128AggState *state1;
5610 : Int128AggState *state2;
5611 : MemoryContext agg_context;
5612 : MemoryContext old_context;
5613 :
5614 22 : if (!AggCheckCallContext(fcinfo, &agg_context))
5615 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5616 :
5617 22 : state1 = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
5618 22 : state2 = PG_ARGISNULL(1) ? NULL : (Int128AggState *) PG_GETARG_POINTER(1);
5619 :
5620 22 : if (state2 == NULL)
5621 0 : PG_RETURN_POINTER(state1);
5622 :
5623 : /* manually copy all fields from state2 to state1 */
5624 22 : if (state1 == NULL)
5625 : {
5626 6 : old_context = MemoryContextSwitchTo(agg_context);
5627 :
5628 6 : state1 = makeInt128AggState(fcinfo, true);
5629 6 : state1->N = state2->N;
5630 6 : state1->sumX = state2->sumX;
5631 6 : state1->sumX2 = state2->sumX2;
5632 :
5633 6 : MemoryContextSwitchTo(old_context);
5634 :
5635 6 : PG_RETURN_POINTER(state1);
5636 : }
5637 :
5638 16 : if (state2->N > 0)
5639 : {
5640 16 : state1->N += state2->N;
5641 16 : int128_add_int128(&state1->sumX, state2->sumX);
5642 16 : int128_add_int128(&state1->sumX2, state2->sumX2);
5643 : }
5644 16 : PG_RETURN_POINTER(state1);
5645 : }
5646 :
5647 : /*
5648 : * int128_serialize - serialize a 128-bit integer to binary format
5649 : */
5650 : static inline void
5651 72 : int128_serialize(StringInfo buf, INT128 val)
5652 : {
5653 72 : pq_sendint64(buf, PG_INT128_HI_INT64(val));
5654 72 : pq_sendint64(buf, PG_INT128_LO_UINT64(val));
5655 72 : }
5656 :
5657 : /*
5658 : * int128_deserialize - deserialize binary format to a 128-bit integer.
5659 : */
5660 : static inline INT128
5661 72 : int128_deserialize(StringInfo buf)
5662 : {
5663 72 : int64 hi = pq_getmsgint64(buf);
5664 72 : uint64 lo = pq_getmsgint64(buf);
5665 :
5666 72 : return make_int128(hi, lo);
5667 : }
5668 :
5669 : /*
5670 : * numeric_poly_serialize
5671 : * Serialize Int128AggState into bytea for aggregate functions which
5672 : * require sumX2.
5673 : */
5674 : Datum
5675 22 : numeric_poly_serialize(PG_FUNCTION_ARGS)
5676 : {
5677 : Int128AggState *state;
5678 : StringInfoData buf;
5679 : bytea *result;
5680 :
5681 : /* Ensure we disallow calling when not in aggregate context */
5682 22 : if (!AggCheckCallContext(fcinfo, NULL))
5683 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5684 :
5685 22 : state = (Int128AggState *) PG_GETARG_POINTER(0);
5686 :
5687 22 : pq_begintypsend(&buf);
5688 :
5689 : /* N */
5690 22 : pq_sendint64(&buf, state->N);
5691 :
5692 : /* sumX */
5693 22 : int128_serialize(&buf, state->sumX);
5694 :
5695 : /* sumX2 */
5696 22 : int128_serialize(&buf, state->sumX2);
5697 :
5698 22 : result = pq_endtypsend(&buf);
5699 :
5700 22 : PG_RETURN_BYTEA_P(result);
5701 : }
5702 :
5703 : /*
5704 : * numeric_poly_deserialize
5705 : * Deserialize Int128AggState from bytea for aggregate functions which
5706 : * require sumX2.
5707 : */
5708 : Datum
5709 22 : numeric_poly_deserialize(PG_FUNCTION_ARGS)
5710 : {
5711 : bytea *sstate;
5712 : Int128AggState *result;
5713 : StringInfoData buf;
5714 :
5715 22 : if (!AggCheckCallContext(fcinfo, NULL))
5716 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5717 :
5718 22 : sstate = PG_GETARG_BYTEA_PP(0);
5719 :
5720 : /*
5721 : * Initialize a StringInfo so that we can "receive" it using the standard
5722 : * recv-function infrastructure.
5723 : */
5724 22 : initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
5725 22 : VARSIZE_ANY_EXHDR(sstate));
5726 :
5727 22 : result = makeInt128AggStateCurrentContext(false);
5728 :
5729 : /* N */
5730 22 : result->N = pq_getmsgint64(&buf);
5731 :
5732 : /* sumX */
5733 22 : result->sumX = int128_deserialize(&buf);
5734 :
5735 : /* sumX2 */
5736 22 : result->sumX2 = int128_deserialize(&buf);
5737 :
5738 22 : pq_getmsgend(&buf);
5739 :
5740 22 : PG_RETURN_POINTER(result);
5741 : }
5742 :
5743 : /*
5744 : * Transition function for int8 input when we don't need sumX2.
5745 : */
5746 : Datum
5747 318920 : int8_avg_accum(PG_FUNCTION_ARGS)
5748 : {
5749 : Int128AggState *state;
5750 :
5751 318920 : state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
5752 :
5753 : /* Create the state data on the first call */
5754 318920 : if (state == NULL)
5755 834 : state = makeInt128AggState(fcinfo, false);
5756 :
5757 318920 : if (!PG_ARGISNULL(1))
5758 315122 : do_int128_accum(state, PG_GETARG_INT64(1));
5759 :
5760 318920 : PG_RETURN_POINTER(state);
5761 : }
5762 :
5763 : /*
5764 : * Combine function for Int128AggState for aggregates which don't require
5765 : * sumX2
5766 : */
5767 : Datum
5768 28 : int8_avg_combine(PG_FUNCTION_ARGS)
5769 : {
5770 : Int128AggState *state1;
5771 : Int128AggState *state2;
5772 : MemoryContext agg_context;
5773 : MemoryContext old_context;
5774 :
5775 28 : if (!AggCheckCallContext(fcinfo, &agg_context))
5776 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5777 :
5778 28 : state1 = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
5779 28 : state2 = PG_ARGISNULL(1) ? NULL : (Int128AggState *) PG_GETARG_POINTER(1);
5780 :
5781 28 : if (state2 == NULL)
5782 0 : PG_RETURN_POINTER(state1);
5783 :
5784 : /* manually copy all fields from state2 to state1 */
5785 28 : if (state1 == NULL)
5786 : {
5787 12 : old_context = MemoryContextSwitchTo(agg_context);
5788 :
5789 12 : state1 = makeInt128AggState(fcinfo, false);
5790 12 : state1->N = state2->N;
5791 12 : state1->sumX = state2->sumX;
5792 :
5793 12 : MemoryContextSwitchTo(old_context);
5794 :
5795 12 : PG_RETURN_POINTER(state1);
5796 : }
5797 :
5798 16 : if (state2->N > 0)
5799 : {
5800 16 : state1->N += state2->N;
5801 16 : int128_add_int128(&state1->sumX, state2->sumX);
5802 : }
5803 16 : PG_RETURN_POINTER(state1);
5804 : }
5805 :
5806 : /*
5807 : * int8_avg_serialize
5808 : * Serialize Int128AggState into bytea for aggregate functions which
5809 : * don't require sumX2.
5810 : */
5811 : Datum
5812 28 : int8_avg_serialize(PG_FUNCTION_ARGS)
5813 : {
5814 : Int128AggState *state;
5815 : StringInfoData buf;
5816 : bytea *result;
5817 :
5818 : /* Ensure we disallow calling when not in aggregate context */
5819 28 : if (!AggCheckCallContext(fcinfo, NULL))
5820 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5821 :
5822 28 : state = (Int128AggState *) PG_GETARG_POINTER(0);
5823 :
5824 28 : pq_begintypsend(&buf);
5825 :
5826 : /* N */
5827 28 : pq_sendint64(&buf, state->N);
5828 :
5829 : /* sumX */
5830 28 : int128_serialize(&buf, state->sumX);
5831 :
5832 28 : result = pq_endtypsend(&buf);
5833 :
5834 28 : PG_RETURN_BYTEA_P(result);
5835 : }
5836 :
5837 : /*
5838 : * int8_avg_deserialize
5839 : * Deserialize Int128AggState from bytea for aggregate functions which
5840 : * don't require sumX2.
5841 : */
5842 : Datum
5843 28 : int8_avg_deserialize(PG_FUNCTION_ARGS)
5844 : {
5845 : bytea *sstate;
5846 : Int128AggState *result;
5847 : StringInfoData buf;
5848 :
5849 28 : if (!AggCheckCallContext(fcinfo, NULL))
5850 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5851 :
5852 28 : sstate = PG_GETARG_BYTEA_PP(0);
5853 :
5854 : /*
5855 : * Initialize a StringInfo so that we can "receive" it using the standard
5856 : * recv-function infrastructure.
5857 : */
5858 28 : initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
5859 28 : VARSIZE_ANY_EXHDR(sstate));
5860 :
5861 28 : result = makeInt128AggStateCurrentContext(false);
5862 :
5863 : /* N */
5864 28 : result->N = pq_getmsgint64(&buf);
5865 :
5866 : /* sumX */
5867 28 : result->sumX = int128_deserialize(&buf);
5868 :
5869 28 : pq_getmsgend(&buf);
5870 :
5871 28 : PG_RETURN_POINTER(result);
5872 : }
5873 :
5874 : /*
5875 : * Inverse transition functions to go with the above.
5876 : */
5877 :
5878 : Datum
5879 162 : int2_accum_inv(PG_FUNCTION_ARGS)
5880 : {
5881 : Int128AggState *state;
5882 :
5883 162 : state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
5884 :
5885 : /* Should not get here with no state */
5886 162 : if (state == NULL)
5887 0 : elog(ERROR, "int2_accum_inv called with NULL state");
5888 :
5889 162 : if (!PG_ARGISNULL(1))
5890 144 : do_int128_discard(state, PG_GETARG_INT16(1));
5891 :
5892 162 : PG_RETURN_POINTER(state);
5893 : }
5894 :
5895 : Datum
5896 162 : int4_accum_inv(PG_FUNCTION_ARGS)
5897 : {
5898 : Int128AggState *state;
5899 :
5900 162 : state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
5901 :
5902 : /* Should not get here with no state */
5903 162 : if (state == NULL)
5904 0 : elog(ERROR, "int4_accum_inv called with NULL state");
5905 :
5906 162 : if (!PG_ARGISNULL(1))
5907 144 : do_int128_discard(state, PG_GETARG_INT32(1));
5908 :
5909 162 : PG_RETURN_POINTER(state);
5910 : }
5911 :
5912 : Datum
5913 162 : int8_accum_inv(PG_FUNCTION_ARGS)
5914 : {
5915 : NumericAggState *state;
5916 :
5917 162 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
5918 :
5919 : /* Should not get here with no state */
5920 162 : if (state == NULL)
5921 0 : elog(ERROR, "int8_accum_inv called with NULL state");
5922 :
5923 162 : if (!PG_ARGISNULL(1))
5924 : {
5925 : /* Should never fail, all inputs have dscale 0 */
5926 144 : if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT64(1))))
5927 0 : elog(ERROR, "do_numeric_discard failed unexpectedly");
5928 : }
5929 :
5930 162 : PG_RETURN_POINTER(state);
5931 : }
5932 :
5933 : Datum
5934 36 : int8_avg_accum_inv(PG_FUNCTION_ARGS)
5935 : {
5936 : Int128AggState *state;
5937 :
5938 36 : state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
5939 :
5940 : /* Should not get here with no state */
5941 36 : if (state == NULL)
5942 0 : elog(ERROR, "int8_avg_accum_inv called with NULL state");
5943 :
5944 36 : if (!PG_ARGISNULL(1))
5945 24 : do_int128_discard(state, PG_GETARG_INT64(1));
5946 :
5947 36 : PG_RETURN_POINTER(state);
5948 : }
5949 :
5950 : Datum
5951 1052 : numeric_poly_sum(PG_FUNCTION_ARGS)
5952 : {
5953 : Int128AggState *state;
5954 : Numeric res;
5955 : NumericVar result;
5956 :
5957 1052 : state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
5958 :
5959 : /* If there were no non-null inputs, return NULL */
5960 1052 : if (state == NULL || state->N == 0)
5961 24 : PG_RETURN_NULL();
5962 :
5963 1028 : init_var(&result);
5964 :
5965 1028 : int128_to_numericvar(state->sumX, &result);
5966 :
5967 1028 : res = make_result(&result);
5968 :
5969 1028 : free_var(&result);
5970 :
5971 1028 : PG_RETURN_NUMERIC(res);
5972 : }
5973 :
5974 : Datum
5975 36 : numeric_poly_avg(PG_FUNCTION_ARGS)
5976 : {
5977 : Int128AggState *state;
5978 : NumericVar result;
5979 : Datum countd,
5980 : sumd;
5981 :
5982 36 : state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
5983 :
5984 : /* If there were no non-null inputs, return NULL */
5985 36 : if (state == NULL || state->N == 0)
5986 18 : PG_RETURN_NULL();
5987 :
5988 18 : init_var(&result);
5989 :
5990 18 : int128_to_numericvar(state->sumX, &result);
5991 :
5992 18 : countd = NumericGetDatum(int64_to_numeric(state->N));
5993 18 : sumd = NumericGetDatum(make_result(&result));
5994 :
5995 18 : free_var(&result);
5996 :
5997 18 : PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumd, countd));
5998 : }
5999 :
6000 : Datum
6001 78 : numeric_avg(PG_FUNCTION_ARGS)
6002 : {
6003 : NumericAggState *state;
6004 : Datum N_datum;
6005 : Datum sumX_datum;
6006 : NumericVar sumX_var;
6007 :
6008 78 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
6009 :
6010 : /* If there were no non-null inputs, return NULL */
6011 78 : if (state == NULL || NA_TOTAL_COUNT(state) == 0)
6012 18 : PG_RETURN_NULL();
6013 :
6014 60 : if (state->NaNcount > 0) /* there was at least one NaN input */
6015 6 : PG_RETURN_NUMERIC(make_result(&const_nan));
6016 :
6017 : /* adding plus and minus infinities gives NaN */
6018 54 : if (state->pInfcount > 0 && state->nInfcount > 0)
6019 6 : PG_RETURN_NUMERIC(make_result(&const_nan));
6020 48 : if (state->pInfcount > 0)
6021 18 : PG_RETURN_NUMERIC(make_result(&const_pinf));
6022 30 : if (state->nInfcount > 0)
6023 6 : PG_RETURN_NUMERIC(make_result(&const_ninf));
6024 :
6025 24 : N_datum = NumericGetDatum(int64_to_numeric(state->N));
6026 :
6027 24 : init_var(&sumX_var);
6028 24 : accum_sum_final(&state->sumX, &sumX_var);
6029 24 : sumX_datum = NumericGetDatum(make_result(&sumX_var));
6030 24 : free_var(&sumX_var);
6031 :
6032 24 : PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumX_datum, N_datum));
6033 : }
6034 :
6035 : Datum
6036 170906 : numeric_sum(PG_FUNCTION_ARGS)
6037 : {
6038 : NumericAggState *state;
6039 : NumericVar sumX_var;
6040 : Numeric result;
6041 :
6042 170906 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
6043 :
6044 : /* If there were no non-null inputs, return NULL */
6045 170906 : if (state == NULL || NA_TOTAL_COUNT(state) == 0)
6046 18 : PG_RETURN_NULL();
6047 :
6048 170888 : if (state->NaNcount > 0) /* there was at least one NaN input */
6049 18 : PG_RETURN_NUMERIC(make_result(&const_nan));
6050 :
6051 : /* adding plus and minus infinities gives NaN */
6052 170870 : if (state->pInfcount > 0 && state->nInfcount > 0)
6053 6 : PG_RETURN_NUMERIC(make_result(&const_nan));
6054 170864 : if (state->pInfcount > 0)
6055 18 : PG_RETURN_NUMERIC(make_result(&const_pinf));
6056 170846 : if (state->nInfcount > 0)
6057 6 : PG_RETURN_NUMERIC(make_result(&const_ninf));
6058 :
6059 170840 : init_var(&sumX_var);
6060 170840 : accum_sum_final(&state->sumX, &sumX_var);
6061 170840 : result = make_result(&sumX_var);
6062 170840 : free_var(&sumX_var);
6063 :
6064 170840 : PG_RETURN_NUMERIC(result);
6065 : }
6066 :
6067 : /*
6068 : * Workhorse routine for the standard deviance and variance
6069 : * aggregates. 'state' is aggregate's transition state.
6070 : * 'variance' specifies whether we should calculate the
6071 : * variance or the standard deviation. 'sample' indicates whether the
6072 : * caller is interested in the sample or the population
6073 : * variance/stddev.
6074 : *
6075 : * If appropriate variance statistic is undefined for the input,
6076 : * *is_null is set to true and NULL is returned.
6077 : */
6078 : static Numeric
6079 986 : numeric_stddev_internal(NumericAggState *state,
6080 : bool variance, bool sample,
6081 : bool *is_null)
6082 : {
6083 : Numeric res;
6084 : NumericVar vN,
6085 : vsumX,
6086 : vsumX2,
6087 : vNminus1;
6088 : int64 totCount;
6089 : int rscale;
6090 :
6091 : /*
6092 : * Sample stddev and variance are undefined when N <= 1; population stddev
6093 : * is undefined when N == 0. Return NULL in either case (note that NaNs
6094 : * and infinities count as normal inputs for this purpose).
6095 : */
6096 986 : if (state == NULL || (totCount = NA_TOTAL_COUNT(state)) == 0)
6097 : {
6098 0 : *is_null = true;
6099 0 : return NULL;
6100 : }
6101 :
6102 986 : if (sample && totCount <= 1)
6103 : {
6104 132 : *is_null = true;
6105 132 : return NULL;
6106 : }
6107 :
6108 854 : *is_null = false;
6109 :
6110 : /*
6111 : * Deal with NaN and infinity cases. By analogy to the behavior of the
6112 : * float8 functions, any infinity input produces NaN output.
6113 : */
6114 854 : if (state->NaNcount > 0 || state->pInfcount > 0 || state->nInfcount > 0)
6115 54 : return make_result(&const_nan);
6116 :
6117 : /* OK, normal calculation applies */
6118 800 : init_var(&vN);
6119 800 : init_var(&vsumX);
6120 800 : init_var(&vsumX2);
6121 :
6122 800 : int64_to_numericvar(state->N, &vN);
6123 800 : accum_sum_final(&(state->sumX), &vsumX);
6124 800 : accum_sum_final(&(state->sumX2), &vsumX2);
6125 :
6126 800 : init_var(&vNminus1);
6127 800 : sub_var(&vN, &const_one, &vNminus1);
6128 :
6129 : /* compute rscale for mul_var calls */
6130 800 : rscale = vsumX.dscale * 2;
6131 :
6132 800 : mul_var(&vsumX, &vsumX, &vsumX, rscale); /* vsumX = sumX * sumX */
6133 800 : mul_var(&vN, &vsumX2, &vsumX2, rscale); /* vsumX2 = N * sumX2 */
6134 800 : sub_var(&vsumX2, &vsumX, &vsumX2); /* N * sumX2 - sumX * sumX */
6135 :
6136 800 : if (cmp_var(&vsumX2, &const_zero) <= 0)
6137 : {
6138 : /* Watch out for roundoff error producing a negative numerator */
6139 80 : res = make_result(&const_zero);
6140 : }
6141 : else
6142 : {
6143 720 : if (sample)
6144 492 : mul_var(&vN, &vNminus1, &vNminus1, 0); /* N * (N - 1) */
6145 : else
6146 228 : mul_var(&vN, &vN, &vNminus1, 0); /* N * N */
6147 720 : rscale = select_div_scale(&vsumX2, &vNminus1);
6148 720 : div_var(&vsumX2, &vNminus1, &vsumX, rscale, true, true); /* variance */
6149 720 : if (!variance)
6150 378 : sqrt_var(&vsumX, &vsumX, rscale); /* stddev */
6151 :
6152 720 : res = make_result(&vsumX);
6153 : }
6154 :
6155 800 : free_var(&vNminus1);
6156 800 : free_var(&vsumX);
6157 800 : free_var(&vsumX2);
6158 :
6159 800 : return res;
6160 : }
6161 :
6162 : Datum
6163 180 : numeric_var_samp(PG_FUNCTION_ARGS)
6164 : {
6165 : NumericAggState *state;
6166 : Numeric res;
6167 : bool is_null;
6168 :
6169 180 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
6170 :
6171 180 : res = numeric_stddev_internal(state, true, true, &is_null);
6172 :
6173 180 : if (is_null)
6174 42 : PG_RETURN_NULL();
6175 : else
6176 138 : PG_RETURN_NUMERIC(res);
6177 : }
6178 :
6179 : Datum
6180 174 : numeric_stddev_samp(PG_FUNCTION_ARGS)
6181 : {
6182 : NumericAggState *state;
6183 : Numeric res;
6184 : bool is_null;
6185 :
6186 174 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
6187 :
6188 174 : res = numeric_stddev_internal(state, false, true, &is_null);
6189 :
6190 174 : if (is_null)
6191 42 : PG_RETURN_NULL();
6192 : else
6193 132 : PG_RETURN_NUMERIC(res);
6194 : }
6195 :
6196 : Datum
6197 114 : numeric_var_pop(PG_FUNCTION_ARGS)
6198 : {
6199 : NumericAggState *state;
6200 : Numeric res;
6201 : bool is_null;
6202 :
6203 114 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
6204 :
6205 114 : res = numeric_stddev_internal(state, true, false, &is_null);
6206 :
6207 114 : if (is_null)
6208 0 : PG_RETURN_NULL();
6209 : else
6210 114 : PG_RETURN_NUMERIC(res);
6211 : }
6212 :
6213 : Datum
6214 96 : numeric_stddev_pop(PG_FUNCTION_ARGS)
6215 : {
6216 : NumericAggState *state;
6217 : Numeric res;
6218 : bool is_null;
6219 :
6220 96 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
6221 :
6222 96 : res = numeric_stddev_internal(state, false, false, &is_null);
6223 :
6224 96 : if (is_null)
6225 0 : PG_RETURN_NULL();
6226 : else
6227 96 : PG_RETURN_NUMERIC(res);
6228 : }
6229 :
6230 : static Numeric
6231 422 : numeric_poly_stddev_internal(Int128AggState *state,
6232 : bool variance, bool sample,
6233 : bool *is_null)
6234 : {
6235 : NumericAggState numstate;
6236 : Numeric res;
6237 :
6238 : /* Initialize an empty agg state */
6239 422 : memset(&numstate, 0, sizeof(NumericAggState));
6240 :
6241 422 : if (state)
6242 : {
6243 : NumericVar tmp_var;
6244 :
6245 422 : numstate.N = state->N;
6246 :
6247 422 : init_var(&tmp_var);
6248 :
6249 422 : int128_to_numericvar(state->sumX, &tmp_var);
6250 422 : accum_sum_add(&numstate.sumX, &tmp_var);
6251 :
6252 422 : int128_to_numericvar(state->sumX2, &tmp_var);
6253 422 : accum_sum_add(&numstate.sumX2, &tmp_var);
6254 :
6255 422 : free_var(&tmp_var);
6256 : }
6257 :
6258 422 : res = numeric_stddev_internal(&numstate, variance, sample, is_null);
6259 :
6260 422 : if (numstate.sumX.ndigits > 0)
6261 : {
6262 422 : pfree(numstate.sumX.pos_digits);
6263 422 : pfree(numstate.sumX.neg_digits);
6264 : }
6265 422 : if (numstate.sumX2.ndigits > 0)
6266 : {
6267 422 : pfree(numstate.sumX2.pos_digits);
6268 422 : pfree(numstate.sumX2.neg_digits);
6269 : }
6270 :
6271 422 : return res;
6272 : }
6273 :
6274 : Datum
6275 126 : numeric_poly_var_samp(PG_FUNCTION_ARGS)
6276 : {
6277 : Int128AggState *state;
6278 : Numeric res;
6279 : bool is_null;
6280 :
6281 126 : state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
6282 :
6283 126 : res = numeric_poly_stddev_internal(state, true, true, &is_null);
6284 :
6285 126 : if (is_null)
6286 24 : PG_RETURN_NULL();
6287 : else
6288 102 : PG_RETURN_NUMERIC(res);
6289 : }
6290 :
6291 : Datum
6292 164 : numeric_poly_stddev_samp(PG_FUNCTION_ARGS)
6293 : {
6294 : Int128AggState *state;
6295 : Numeric res;
6296 : bool is_null;
6297 :
6298 164 : state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
6299 :
6300 164 : res = numeric_poly_stddev_internal(state, false, true, &is_null);
6301 :
6302 164 : if (is_null)
6303 24 : PG_RETURN_NULL();
6304 : else
6305 140 : PG_RETURN_NUMERIC(res);
6306 : }
6307 :
6308 : Datum
6309 60 : numeric_poly_var_pop(PG_FUNCTION_ARGS)
6310 : {
6311 : Int128AggState *state;
6312 : Numeric res;
6313 : bool is_null;
6314 :
6315 60 : state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
6316 :
6317 60 : res = numeric_poly_stddev_internal(state, true, false, &is_null);
6318 :
6319 60 : if (is_null)
6320 0 : PG_RETURN_NULL();
6321 : else
6322 60 : PG_RETURN_NUMERIC(res);
6323 : }
6324 :
6325 : Datum
6326 72 : numeric_poly_stddev_pop(PG_FUNCTION_ARGS)
6327 : {
6328 : Int128AggState *state;
6329 : Numeric res;
6330 : bool is_null;
6331 :
6332 72 : state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
6333 :
6334 72 : res = numeric_poly_stddev_internal(state, false, false, &is_null);
6335 :
6336 72 : if (is_null)
6337 0 : PG_RETURN_NULL();
6338 : else
6339 72 : PG_RETURN_NUMERIC(res);
6340 : }
6341 :
6342 : /*
6343 : * SUM transition functions for integer datatypes.
6344 : *
6345 : * To avoid overflow, we use accumulators wider than the input datatype.
6346 : * A Numeric accumulator is needed for int8 input; for int4 and int2
6347 : * inputs, we use int8 accumulators which should be sufficient for practical
6348 : * purposes. (The latter two therefore don't really belong in this file,
6349 : * but we keep them here anyway.)
6350 : *
6351 : * Because SQL defines the SUM() of no values to be NULL, not zero,
6352 : * the initial condition of the transition data value needs to be NULL. This
6353 : * means we can't rely on ExecAgg to automatically insert the first non-null
6354 : * data value into the transition data: it doesn't know how to do the type
6355 : * conversion. The upshot is that these routines have to be marked non-strict
6356 : * and handle substitution of the first non-null input themselves.
6357 : *
6358 : * Note: these functions are used only in plain aggregation mode.
6359 : * In moving-aggregate mode, we use intX_avg_accum and intX_avg_accum_inv.
6360 : */
6361 :
6362 : Datum
6363 24 : int2_sum(PG_FUNCTION_ARGS)
6364 : {
6365 : int64 oldsum;
6366 : int64 newval;
6367 :
6368 24 : if (PG_ARGISNULL(0))
6369 : {
6370 : /* No non-null input seen so far... */
6371 6 : if (PG_ARGISNULL(1))
6372 0 : PG_RETURN_NULL(); /* still no non-null */
6373 : /* This is the first non-null input. */
6374 6 : newval = (int64) PG_GETARG_INT16(1);
6375 6 : PG_RETURN_INT64(newval);
6376 : }
6377 :
6378 18 : oldsum = PG_GETARG_INT64(0);
6379 :
6380 : /* Leave sum unchanged if new input is null. */
6381 18 : if (PG_ARGISNULL(1))
6382 0 : PG_RETURN_INT64(oldsum);
6383 :
6384 : /* OK to do the addition. */
6385 18 : newval = oldsum + (int64) PG_GETARG_INT16(1);
6386 :
6387 18 : PG_RETURN_INT64(newval);
6388 : }
6389 :
6390 : Datum
6391 3698156 : int4_sum(PG_FUNCTION_ARGS)
6392 : {
6393 : int64 oldsum;
6394 : int64 newval;
6395 :
6396 3698156 : if (PG_ARGISNULL(0))
6397 : {
6398 : /* No non-null input seen so far... */
6399 207124 : if (PG_ARGISNULL(1))
6400 986 : PG_RETURN_NULL(); /* still no non-null */
6401 : /* This is the first non-null input. */
6402 206138 : newval = (int64) PG_GETARG_INT32(1);
6403 206138 : PG_RETURN_INT64(newval);
6404 : }
6405 :
6406 3491032 : oldsum = PG_GETARG_INT64(0);
6407 :
6408 : /* Leave sum unchanged if new input is null. */
6409 3491032 : if (PG_ARGISNULL(1))
6410 30874 : PG_RETURN_INT64(oldsum);
6411 :
6412 : /* OK to do the addition. */
6413 3460158 : newval = oldsum + (int64) PG_GETARG_INT32(1);
6414 :
6415 3460158 : PG_RETURN_INT64(newval);
6416 : }
6417 :
6418 : /*
6419 : * Note: this function is obsolete, it's no longer used for SUM(int8).
6420 : */
6421 : Datum
6422 0 : int8_sum(PG_FUNCTION_ARGS)
6423 : {
6424 : Numeric oldsum;
6425 :
6426 0 : if (PG_ARGISNULL(0))
6427 : {
6428 : /* No non-null input seen so far... */
6429 0 : if (PG_ARGISNULL(1))
6430 0 : PG_RETURN_NULL(); /* still no non-null */
6431 : /* This is the first non-null input. */
6432 0 : PG_RETURN_NUMERIC(int64_to_numeric(PG_GETARG_INT64(1)));
6433 : }
6434 :
6435 : /*
6436 : * Note that we cannot special-case the aggregate case here, as we do for
6437 : * int2_sum and int4_sum: numeric is of variable size, so we cannot modify
6438 : * our first parameter in-place.
6439 : */
6440 :
6441 0 : oldsum = PG_GETARG_NUMERIC(0);
6442 :
6443 : /* Leave sum unchanged if new input is null. */
6444 0 : if (PG_ARGISNULL(1))
6445 0 : PG_RETURN_NUMERIC(oldsum);
6446 :
6447 : /* OK to do the addition. */
6448 0 : PG_RETURN_DATUM(DirectFunctionCall2(numeric_add,
6449 : NumericGetDatum(oldsum),
6450 : NumericGetDatum(int64_to_numeric(PG_GETARG_INT64(1)))));
6451 : }
6452 :
6453 :
6454 : /*
6455 : * Routines for avg(int2) and avg(int4). The transition datatype
6456 : * is a two-element int8 array, holding count and sum.
6457 : *
6458 : * These functions are also used for sum(int2) and sum(int4) when
6459 : * operating in moving-aggregate mode, since for correct inverse transitions
6460 : * we need to count the inputs.
6461 : */
6462 :
6463 : typedef struct Int8TransTypeData
6464 : {
6465 : int64 count;
6466 : int64 sum;
6467 : } Int8TransTypeData;
6468 :
6469 : Datum
6470 42 : int2_avg_accum(PG_FUNCTION_ARGS)
6471 : {
6472 : ArrayType *transarray;
6473 42 : int16 newval = PG_GETARG_INT16(1);
6474 : Int8TransTypeData *transdata;
6475 :
6476 : /*
6477 : * If we're invoked as an aggregate, we can cheat and modify our first
6478 : * parameter in-place to reduce palloc overhead. Otherwise we need to make
6479 : * a copy of it before scribbling on it.
6480 : */
6481 42 : if (AggCheckCallContext(fcinfo, NULL))
6482 42 : transarray = PG_GETARG_ARRAYTYPE_P(0);
6483 : else
6484 0 : transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
6485 :
6486 84 : if (ARR_HASNULL(transarray) ||
6487 42 : ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
6488 0 : elog(ERROR, "expected 2-element int8 array");
6489 :
6490 42 : transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
6491 42 : transdata->count++;
6492 42 : transdata->sum += newval;
6493 :
6494 42 : PG_RETURN_ARRAYTYPE_P(transarray);
6495 : }
6496 :
6497 : Datum
6498 2620302 : int4_avg_accum(PG_FUNCTION_ARGS)
6499 : {
6500 : ArrayType *transarray;
6501 2620302 : int32 newval = PG_GETARG_INT32(1);
6502 : Int8TransTypeData *transdata;
6503 :
6504 : /*
6505 : * If we're invoked as an aggregate, we can cheat and modify our first
6506 : * parameter in-place to reduce palloc overhead. Otherwise we need to make
6507 : * a copy of it before scribbling on it.
6508 : */
6509 2620302 : if (AggCheckCallContext(fcinfo, NULL))
6510 2620302 : transarray = PG_GETARG_ARRAYTYPE_P(0);
6511 : else
6512 0 : transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
6513 :
6514 5240604 : if (ARR_HASNULL(transarray) ||
6515 2620302 : ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
6516 0 : elog(ERROR, "expected 2-element int8 array");
6517 :
6518 2620302 : transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
6519 2620302 : transdata->count++;
6520 2620302 : transdata->sum += newval;
6521 :
6522 2620302 : PG_RETURN_ARRAYTYPE_P(transarray);
6523 : }
6524 :
6525 : Datum
6526 4028 : int4_avg_combine(PG_FUNCTION_ARGS)
6527 : {
6528 : ArrayType *transarray1;
6529 : ArrayType *transarray2;
6530 : Int8TransTypeData *state1;
6531 : Int8TransTypeData *state2;
6532 :
6533 4028 : if (!AggCheckCallContext(fcinfo, NULL))
6534 0 : elog(ERROR, "aggregate function called in non-aggregate context");
6535 :
6536 4028 : transarray1 = PG_GETARG_ARRAYTYPE_P(0);
6537 4028 : transarray2 = PG_GETARG_ARRAYTYPE_P(1);
6538 :
6539 8056 : if (ARR_HASNULL(transarray1) ||
6540 4028 : ARR_SIZE(transarray1) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
6541 0 : elog(ERROR, "expected 2-element int8 array");
6542 :
6543 8056 : if (ARR_HASNULL(transarray2) ||
6544 4028 : ARR_SIZE(transarray2) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
6545 0 : elog(ERROR, "expected 2-element int8 array");
6546 :
6547 4028 : state1 = (Int8TransTypeData *) ARR_DATA_PTR(transarray1);
6548 4028 : state2 = (Int8TransTypeData *) ARR_DATA_PTR(transarray2);
6549 :
6550 4028 : state1->count += state2->count;
6551 4028 : state1->sum += state2->sum;
6552 :
6553 4028 : PG_RETURN_ARRAYTYPE_P(transarray1);
6554 : }
6555 :
6556 : Datum
6557 12 : int2_avg_accum_inv(PG_FUNCTION_ARGS)
6558 : {
6559 : ArrayType *transarray;
6560 12 : int16 newval = PG_GETARG_INT16(1);
6561 : Int8TransTypeData *transdata;
6562 :
6563 : /*
6564 : * If we're invoked as an aggregate, we can cheat and modify our first
6565 : * parameter in-place to reduce palloc overhead. Otherwise we need to make
6566 : * a copy of it before scribbling on it.
6567 : */
6568 12 : if (AggCheckCallContext(fcinfo, NULL))
6569 12 : transarray = PG_GETARG_ARRAYTYPE_P(0);
6570 : else
6571 0 : transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
6572 :
6573 24 : if (ARR_HASNULL(transarray) ||
6574 12 : ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
6575 0 : elog(ERROR, "expected 2-element int8 array");
6576 :
6577 12 : transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
6578 12 : transdata->count--;
6579 12 : transdata->sum -= newval;
6580 :
6581 12 : PG_RETURN_ARRAYTYPE_P(transarray);
6582 : }
6583 :
6584 : Datum
6585 1452 : int4_avg_accum_inv(PG_FUNCTION_ARGS)
6586 : {
6587 : ArrayType *transarray;
6588 1452 : int32 newval = PG_GETARG_INT32(1);
6589 : Int8TransTypeData *transdata;
6590 :
6591 : /*
6592 : * If we're invoked as an aggregate, we can cheat and modify our first
6593 : * parameter in-place to reduce palloc overhead. Otherwise we need to make
6594 : * a copy of it before scribbling on it.
6595 : */
6596 1452 : if (AggCheckCallContext(fcinfo, NULL))
6597 1452 : transarray = PG_GETARG_ARRAYTYPE_P(0);
6598 : else
6599 0 : transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
6600 :
6601 2904 : if (ARR_HASNULL(transarray) ||
6602 1452 : ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
6603 0 : elog(ERROR, "expected 2-element int8 array");
6604 :
6605 1452 : transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
6606 1452 : transdata->count--;
6607 1452 : transdata->sum -= newval;
6608 :
6609 1452 : PG_RETURN_ARRAYTYPE_P(transarray);
6610 : }
6611 :
6612 : Datum
6613 10774 : int8_avg(PG_FUNCTION_ARGS)
6614 : {
6615 10774 : ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
6616 : Int8TransTypeData *transdata;
6617 : Datum countd,
6618 : sumd;
6619 :
6620 21548 : if (ARR_HASNULL(transarray) ||
6621 10774 : ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
6622 0 : elog(ERROR, "expected 2-element int8 array");
6623 10774 : transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
6624 :
6625 : /* SQL defines AVG of no values to be NULL */
6626 10774 : if (transdata->count == 0)
6627 118 : PG_RETURN_NULL();
6628 :
6629 10656 : countd = NumericGetDatum(int64_to_numeric(transdata->count));
6630 10656 : sumd = NumericGetDatum(int64_to_numeric(transdata->sum));
6631 :
6632 10656 : PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumd, countd));
6633 : }
6634 :
6635 : /*
6636 : * SUM(int2) and SUM(int4) both return int8, so we can use this
6637 : * final function for both.
6638 : */
6639 : Datum
6640 3834 : int2int4_sum(PG_FUNCTION_ARGS)
6641 : {
6642 3834 : ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
6643 : Int8TransTypeData *transdata;
6644 :
6645 7668 : if (ARR_HASNULL(transarray) ||
6646 3834 : ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
6647 0 : elog(ERROR, "expected 2-element int8 array");
6648 3834 : transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
6649 :
6650 : /* SQL defines SUM of no values to be NULL */
6651 3834 : if (transdata->count == 0)
6652 480 : PG_RETURN_NULL();
6653 :
6654 3354 : PG_RETURN_DATUM(Int64GetDatumFast(transdata->sum));
6655 : }
6656 :
6657 :
6658 : /* ----------------------------------------------------------------------
6659 : *
6660 : * Debug support
6661 : *
6662 : * ----------------------------------------------------------------------
6663 : */
6664 :
6665 : #ifdef NUMERIC_DEBUG
6666 :
6667 : /*
6668 : * dump_numeric() - Dump a value in the db storage format for debugging
6669 : */
6670 : static void
6671 : dump_numeric(const char *str, Numeric num)
6672 : {
6673 : NumericDigit *digits = NUMERIC_DIGITS(num);
6674 : int ndigits;
6675 : int i;
6676 :
6677 : ndigits = NUMERIC_NDIGITS(num);
6678 :
6679 : printf("%s: NUMERIC w=%d d=%d ", str,
6680 : NUMERIC_WEIGHT(num), NUMERIC_DSCALE(num));
6681 : switch (NUMERIC_SIGN(num))
6682 : {
6683 : case NUMERIC_POS:
6684 : printf("POS");
6685 : break;
6686 : case NUMERIC_NEG:
6687 : printf("NEG");
6688 : break;
6689 : case NUMERIC_NAN:
6690 : printf("NaN");
6691 : break;
6692 : case NUMERIC_PINF:
6693 : printf("Infinity");
6694 : break;
6695 : case NUMERIC_NINF:
6696 : printf("-Infinity");
6697 : break;
6698 : default:
6699 : printf("SIGN=0x%x", NUMERIC_SIGN(num));
6700 : break;
6701 : }
6702 :
6703 : for (i = 0; i < ndigits; i++)
6704 : printf(" %0*d", DEC_DIGITS, digits[i]);
6705 : printf("\n");
6706 : }
6707 :
6708 :
6709 : /*
6710 : * dump_var() - Dump a value in the variable format for debugging
6711 : */
6712 : static void
6713 : dump_var(const char *str, NumericVar *var)
6714 : {
6715 : int i;
6716 :
6717 : printf("%s: VAR w=%d d=%d ", str, var->weight, var->dscale);
6718 : switch (var->sign)
6719 : {
6720 : case NUMERIC_POS:
6721 : printf("POS");
6722 : break;
6723 : case NUMERIC_NEG:
6724 : printf("NEG");
6725 : break;
6726 : case NUMERIC_NAN:
6727 : printf("NaN");
6728 : break;
6729 : case NUMERIC_PINF:
6730 : printf("Infinity");
6731 : break;
6732 : case NUMERIC_NINF:
6733 : printf("-Infinity");
6734 : break;
6735 : default:
6736 : printf("SIGN=0x%x", var->sign);
6737 : break;
6738 : }
6739 :
6740 : for (i = 0; i < var->ndigits; i++)
6741 : printf(" %0*d", DEC_DIGITS, var->digits[i]);
6742 :
6743 : printf("\n");
6744 : }
6745 : #endif /* NUMERIC_DEBUG */
6746 :
6747 :
6748 : /* ----------------------------------------------------------------------
6749 : *
6750 : * Local functions follow
6751 : *
6752 : * In general, these do not support "special" (NaN or infinity) inputs;
6753 : * callers should handle those possibilities first.
6754 : * (There are one or two exceptions, noted in their header comments.)
6755 : *
6756 : * ----------------------------------------------------------------------
6757 : */
6758 :
6759 :
6760 : /*
6761 : * alloc_var() -
6762 : *
6763 : * Allocate a digit buffer of ndigits digits (plus a spare digit for rounding)
6764 : */
6765 : static void
6766 2177376 : alloc_var(NumericVar *var, int ndigits)
6767 : {
6768 2177376 : digitbuf_free(var->buf);
6769 2177376 : var->buf = digitbuf_alloc(ndigits + 1);
6770 2177376 : var->buf[0] = 0; /* spare digit for rounding */
6771 2177376 : var->digits = var->buf + 1;
6772 2177376 : var->ndigits = ndigits;
6773 2177376 : }
6774 :
6775 :
6776 : /*
6777 : * free_var() -
6778 : *
6779 : * Return the digit buffer of a variable to the free pool
6780 : */
6781 : static void
6782 4189276 : free_var(NumericVar *var)
6783 : {
6784 4189276 : digitbuf_free(var->buf);
6785 4189276 : var->buf = NULL;
6786 4189276 : var->digits = NULL;
6787 4189276 : var->sign = NUMERIC_NAN;
6788 4189276 : }
6789 :
6790 :
6791 : /*
6792 : * zero_var() -
6793 : *
6794 : * Set a variable to ZERO.
6795 : * Note: its dscale is not touched.
6796 : */
6797 : static void
6798 61068 : zero_var(NumericVar *var)
6799 : {
6800 61068 : digitbuf_free(var->buf);
6801 61068 : var->buf = NULL;
6802 61068 : var->digits = NULL;
6803 61068 : var->ndigits = 0;
6804 61068 : var->weight = 0; /* by convention; doesn't really matter */
6805 61068 : var->sign = NUMERIC_POS; /* anything but NAN... */
6806 61068 : }
6807 :
6808 :
6809 : /*
6810 : * set_var_from_str()
6811 : *
6812 : * Parse a string and put the number into a variable
6813 : *
6814 : * This function does not handle leading or trailing spaces. It returns
6815 : * the end+1 position parsed into *endptr, so that caller can check for
6816 : * trailing spaces/garbage if deemed necessary.
6817 : *
6818 : * cp is the place to actually start parsing; str is what to use in error
6819 : * reports. (Typically cp would be the same except advanced over spaces.)
6820 : *
6821 : * Returns true on success, false on failure (if escontext points to an
6822 : * ErrorSaveContext; otherwise errors are thrown).
6823 : */
6824 : static bool
6825 185008 : set_var_from_str(const char *str, const char *cp,
6826 : NumericVar *dest, const char **endptr,
6827 : Node *escontext)
6828 : {
6829 185008 : bool have_dp = false;
6830 : int i;
6831 : unsigned char *decdigits;
6832 185008 : int sign = NUMERIC_POS;
6833 185008 : int dweight = -1;
6834 : int ddigits;
6835 185008 : int dscale = 0;
6836 : int weight;
6837 : int ndigits;
6838 : int offset;
6839 : NumericDigit *digits;
6840 :
6841 : /*
6842 : * We first parse the string to extract decimal digits and determine the
6843 : * correct decimal weight. Then convert to NBASE representation.
6844 : */
6845 185008 : switch (*cp)
6846 : {
6847 0 : case '+':
6848 0 : sign = NUMERIC_POS;
6849 0 : cp++;
6850 0 : break;
6851 :
6852 300 : case '-':
6853 300 : sign = NUMERIC_NEG;
6854 300 : cp++;
6855 300 : break;
6856 : }
6857 :
6858 185008 : if (*cp == '.')
6859 : {
6860 384 : have_dp = true;
6861 384 : cp++;
6862 : }
6863 :
6864 185008 : if (!isdigit((unsigned char) *cp))
6865 0 : goto invalid_syntax;
6866 :
6867 185008 : decdigits = (unsigned char *) palloc(strlen(cp) + DEC_DIGITS * 2);
6868 :
6869 : /* leading padding for digit alignment later */
6870 185008 : memset(decdigits, 0, DEC_DIGITS);
6871 185008 : i = DEC_DIGITS;
6872 :
6873 797030 : while (*cp)
6874 : {
6875 613386 : if (isdigit((unsigned char) *cp))
6876 : {
6877 593974 : decdigits[i++] = *cp++ - '0';
6878 593974 : if (!have_dp)
6879 509334 : dweight++;
6880 : else
6881 84640 : dscale++;
6882 : }
6883 19412 : else if (*cp == '.')
6884 : {
6885 17886 : if (have_dp)
6886 0 : goto invalid_syntax;
6887 17886 : have_dp = true;
6888 17886 : cp++;
6889 : /* decimal point must not be followed by underscore */
6890 17886 : if (*cp == '_')
6891 6 : goto invalid_syntax;
6892 : }
6893 1526 : else if (*cp == '_')
6894 : {
6895 : /* underscore must be followed by more digits */
6896 186 : cp++;
6897 186 : if (!isdigit((unsigned char) *cp))
6898 18 : goto invalid_syntax;
6899 : }
6900 : else
6901 1340 : break;
6902 : }
6903 :
6904 184984 : ddigits = i - DEC_DIGITS;
6905 : /* trailing padding for digit alignment later */
6906 184984 : memset(decdigits + i, 0, DEC_DIGITS - 1);
6907 :
6908 : /* Handle exponent, if any */
6909 184984 : if (*cp == 'e' || *cp == 'E')
6910 : {
6911 1292 : int64 exponent = 0;
6912 1292 : bool neg = false;
6913 :
6914 : /*
6915 : * At this point, dweight and dscale can't be more than about
6916 : * INT_MAX/2 due to the MaxAllocSize limit on string length, so
6917 : * constraining the exponent similarly should be enough to prevent
6918 : * integer overflow in this function. If the value is too large to
6919 : * fit in storage format, make_result() will complain about it later;
6920 : * for consistency use the same ereport errcode/text as make_result().
6921 : */
6922 :
6923 : /* exponent sign */
6924 1292 : cp++;
6925 1292 : if (*cp == '+')
6926 154 : cp++;
6927 1138 : else if (*cp == '-')
6928 : {
6929 490 : neg = true;
6930 490 : cp++;
6931 : }
6932 :
6933 : /* exponent digits */
6934 1292 : if (!isdigit((unsigned char) *cp))
6935 6 : goto invalid_syntax;
6936 :
6937 4544 : while (*cp)
6938 : {
6939 3276 : if (isdigit((unsigned char) *cp))
6940 : {
6941 3234 : exponent = exponent * 10 + (*cp++ - '0');
6942 3234 : if (exponent > PG_INT32_MAX / 2)
6943 6 : goto out_of_range;
6944 : }
6945 42 : else if (*cp == '_')
6946 : {
6947 : /* underscore must be followed by more digits */
6948 42 : cp++;
6949 42 : if (!isdigit((unsigned char) *cp))
6950 12 : goto invalid_syntax;
6951 : }
6952 : else
6953 0 : break;
6954 : }
6955 :
6956 1268 : if (neg)
6957 490 : exponent = -exponent;
6958 :
6959 1268 : dweight += (int) exponent;
6960 1268 : dscale -= (int) exponent;
6961 1268 : if (dscale < 0)
6962 574 : dscale = 0;
6963 : }
6964 :
6965 : /*
6966 : * Okay, convert pure-decimal representation to base NBASE. First we need
6967 : * to determine the converted weight and ndigits. offset is the number of
6968 : * decimal zeroes to insert before the first given digit to have a
6969 : * correctly aligned first NBASE digit.
6970 : */
6971 184960 : if (dweight >= 0)
6972 184188 : weight = (dweight + 1 + DEC_DIGITS - 1) / DEC_DIGITS - 1;
6973 : else
6974 772 : weight = -((-dweight - 1) / DEC_DIGITS + 1);
6975 184960 : offset = (weight + 1) * DEC_DIGITS - (dweight + 1);
6976 184960 : ndigits = (ddigits + offset + DEC_DIGITS - 1) / DEC_DIGITS;
6977 :
6978 184960 : alloc_var(dest, ndigits);
6979 184960 : dest->sign = sign;
6980 184960 : dest->weight = weight;
6981 184960 : dest->dscale = dscale;
6982 :
6983 184960 : i = DEC_DIGITS - offset;
6984 184960 : digits = dest->digits;
6985 :
6986 444360 : while (ndigits-- > 0)
6987 : {
6988 : #if DEC_DIGITS == 4
6989 259400 : *digits++ = ((decdigits[i] * 10 + decdigits[i + 1]) * 10 +
6990 259400 : decdigits[i + 2]) * 10 + decdigits[i + 3];
6991 : #elif DEC_DIGITS == 2
6992 : *digits++ = decdigits[i] * 10 + decdigits[i + 1];
6993 : #elif DEC_DIGITS == 1
6994 : *digits++ = decdigits[i];
6995 : #else
6996 : #error unsupported NBASE
6997 : #endif
6998 259400 : i += DEC_DIGITS;
6999 : }
7000 :
7001 184960 : pfree(decdigits);
7002 :
7003 : /* Strip any leading/trailing zeroes, and normalize weight if zero */
7004 184960 : strip_var(dest);
7005 :
7006 : /* Return end+1 position for caller */
7007 184960 : *endptr = cp;
7008 :
7009 184960 : return true;
7010 :
7011 6 : out_of_range:
7012 6 : ereturn(escontext, false,
7013 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
7014 : errmsg("value overflows numeric format")));
7015 :
7016 42 : invalid_syntax:
7017 42 : ereturn(escontext, false,
7018 : (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
7019 : errmsg("invalid input syntax for type %s: \"%s\"",
7020 : "numeric", str)));
7021 : }
7022 :
7023 :
7024 : /*
7025 : * Return the numeric value of a single hex digit.
7026 : */
7027 : static inline int
7028 708 : xdigit_value(char dig)
7029 : {
7030 894 : return dig >= '0' && dig <= '9' ? dig - '0' :
7031 294 : dig >= 'a' && dig <= 'f' ? dig - 'a' + 10 :
7032 108 : dig >= 'A' && dig <= 'F' ? dig - 'A' + 10 : -1;
7033 : }
7034 :
7035 : /*
7036 : * set_var_from_non_decimal_integer_str()
7037 : *
7038 : * Parse a string containing a non-decimal integer
7039 : *
7040 : * This function does not handle leading or trailing spaces. It returns
7041 : * the end+1 position parsed into *endptr, so that caller can check for
7042 : * trailing spaces/garbage if deemed necessary.
7043 : *
7044 : * cp is the place to actually start parsing; str is what to use in error
7045 : * reports. The number's sign and base prefix indicator (e.g., "0x") are
7046 : * assumed to have already been parsed, so cp should point to the number's
7047 : * first digit in the base specified.
7048 : *
7049 : * base is expected to be 2, 8 or 16.
7050 : *
7051 : * Returns true on success, false on failure (if escontext points to an
7052 : * ErrorSaveContext; otherwise errors are thrown).
7053 : */
7054 : static bool
7055 156 : set_var_from_non_decimal_integer_str(const char *str, const char *cp, int sign,
7056 : int base, NumericVar *dest,
7057 : const char **endptr, Node *escontext)
7058 : {
7059 156 : const char *firstdigit = cp;
7060 : int64 tmp;
7061 : int64 mul;
7062 : NumericVar tmp_var;
7063 :
7064 156 : init_var(&tmp_var);
7065 :
7066 156 : zero_var(dest);
7067 :
7068 : /*
7069 : * Process input digits in groups that fit in int64. Here "tmp" is the
7070 : * value of the digits in the group, and "mul" is base^n, where n is the
7071 : * number of digits in the group. Thus tmp < mul, and we must start a new
7072 : * group when mul * base threatens to overflow PG_INT64_MAX.
7073 : */
7074 156 : tmp = 0;
7075 156 : mul = 1;
7076 :
7077 156 : if (base == 16)
7078 : {
7079 828 : while (*cp)
7080 : {
7081 798 : if (isxdigit((unsigned char) *cp))
7082 : {
7083 708 : if (mul > PG_INT64_MAX / 16)
7084 : {
7085 : /* Add the contribution from this group of digits */
7086 30 : int64_to_numericvar(mul, &tmp_var);
7087 30 : mul_var(dest, &tmp_var, dest, 0);
7088 30 : int64_to_numericvar(tmp, &tmp_var);
7089 30 : add_var(dest, &tmp_var, dest);
7090 :
7091 : /* Result will overflow if weight overflows int16 */
7092 30 : if (dest->weight > NUMERIC_WEIGHT_MAX)
7093 0 : goto out_of_range;
7094 :
7095 : /* Begin a new group */
7096 30 : tmp = 0;
7097 30 : mul = 1;
7098 : }
7099 :
7100 708 : tmp = tmp * 16 + xdigit_value(*cp++);
7101 708 : mul = mul * 16;
7102 : }
7103 90 : else if (*cp == '_')
7104 : {
7105 : /* Underscore must be followed by more digits */
7106 66 : cp++;
7107 66 : if (!isxdigit((unsigned char) *cp))
7108 18 : goto invalid_syntax;
7109 : }
7110 : else
7111 24 : break;
7112 : }
7113 : }
7114 84 : else if (base == 8)
7115 : {
7116 636 : while (*cp)
7117 : {
7118 606 : if (*cp >= '0' && *cp <= '7')
7119 : {
7120 558 : if (mul > PG_INT64_MAX / 8)
7121 : {
7122 : /* Add the contribution from this group of digits */
7123 18 : int64_to_numericvar(mul, &tmp_var);
7124 18 : mul_var(dest, &tmp_var, dest, 0);
7125 18 : int64_to_numericvar(tmp, &tmp_var);
7126 18 : add_var(dest, &tmp_var, dest);
7127 :
7128 : /* Result will overflow if weight overflows int16 */
7129 18 : if (dest->weight > NUMERIC_WEIGHT_MAX)
7130 0 : goto out_of_range;
7131 :
7132 : /* Begin a new group */
7133 18 : tmp = 0;
7134 18 : mul = 1;
7135 : }
7136 :
7137 558 : tmp = tmp * 8 + (*cp++ - '0');
7138 558 : mul = mul * 8;
7139 : }
7140 48 : else if (*cp == '_')
7141 : {
7142 : /* Underscore must be followed by more digits */
7143 36 : cp++;
7144 36 : if (*cp < '0' || *cp > '7')
7145 0 : goto invalid_syntax;
7146 : }
7147 : else
7148 12 : break;
7149 : }
7150 : }
7151 42 : else if (base == 2)
7152 : {
7153 1560 : while (*cp)
7154 : {
7155 1530 : if (*cp >= '0' && *cp <= '1')
7156 : {
7157 1416 : if (mul > PG_INT64_MAX / 2)
7158 : {
7159 : /* Add the contribution from this group of digits */
7160 18 : int64_to_numericvar(mul, &tmp_var);
7161 18 : mul_var(dest, &tmp_var, dest, 0);
7162 18 : int64_to_numericvar(tmp, &tmp_var);
7163 18 : add_var(dest, &tmp_var, dest);
7164 :
7165 : /* Result will overflow if weight overflows int16 */
7166 18 : if (dest->weight > NUMERIC_WEIGHT_MAX)
7167 0 : goto out_of_range;
7168 :
7169 : /* Begin a new group */
7170 18 : tmp = 0;
7171 18 : mul = 1;
7172 : }
7173 :
7174 1416 : tmp = tmp * 2 + (*cp++ - '0');
7175 1416 : mul = mul * 2;
7176 : }
7177 114 : else if (*cp == '_')
7178 : {
7179 : /* Underscore must be followed by more digits */
7180 102 : cp++;
7181 102 : if (*cp < '0' || *cp > '1')
7182 0 : goto invalid_syntax;
7183 : }
7184 : else
7185 12 : break;
7186 : }
7187 : }
7188 : else
7189 : /* Should never happen; treat as invalid input */
7190 0 : goto invalid_syntax;
7191 :
7192 : /* Check that we got at least one digit */
7193 138 : if (unlikely(cp == firstdigit))
7194 0 : goto invalid_syntax;
7195 :
7196 : /* Add the contribution from the final group of digits */
7197 138 : int64_to_numericvar(mul, &tmp_var);
7198 138 : mul_var(dest, &tmp_var, dest, 0);
7199 138 : int64_to_numericvar(tmp, &tmp_var);
7200 138 : add_var(dest, &tmp_var, dest);
7201 :
7202 138 : if (dest->weight > NUMERIC_WEIGHT_MAX)
7203 0 : goto out_of_range;
7204 :
7205 138 : dest->sign = sign;
7206 :
7207 138 : free_var(&tmp_var);
7208 :
7209 : /* Return end+1 position for caller */
7210 138 : *endptr = cp;
7211 :
7212 138 : return true;
7213 :
7214 0 : out_of_range:
7215 0 : ereturn(escontext, false,
7216 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
7217 : errmsg("value overflows numeric format")));
7218 :
7219 18 : invalid_syntax:
7220 18 : ereturn(escontext, false,
7221 : (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
7222 : errmsg("invalid input syntax for type %s: \"%s\"",
7223 : "numeric", str)));
7224 : }
7225 :
7226 :
7227 : /*
7228 : * set_var_from_num() -
7229 : *
7230 : * Convert the packed db format into a variable
7231 : */
7232 : static void
7233 12952 : set_var_from_num(Numeric num, NumericVar *dest)
7234 : {
7235 : int ndigits;
7236 :
7237 12952 : ndigits = NUMERIC_NDIGITS(num);
7238 :
7239 12952 : alloc_var(dest, ndigits);
7240 :
7241 12952 : dest->weight = NUMERIC_WEIGHT(num);
7242 12952 : dest->sign = NUMERIC_SIGN(num);
7243 12952 : dest->dscale = NUMERIC_DSCALE(num);
7244 :
7245 12952 : memcpy(dest->digits, NUMERIC_DIGITS(num), ndigits * sizeof(NumericDigit));
7246 12952 : }
7247 :
7248 :
7249 : /*
7250 : * init_var_from_num() -
7251 : *
7252 : * Initialize a variable from packed db format. The digits array is not
7253 : * copied, which saves some cycles when the resulting var is not modified.
7254 : * Also, there's no need to call free_var(), as long as you don't assign any
7255 : * other value to it (with set_var_* functions, or by using the var as the
7256 : * destination of a function like add_var())
7257 : *
7258 : * CAUTION: Do not modify the digits buffer of a var initialized with this
7259 : * function, e.g by calling round_var() or trunc_var(), as the changes will
7260 : * propagate to the original Numeric! It's OK to use it as the destination
7261 : * argument of one of the calculational functions, though.
7262 : */
7263 : static void
7264 5862976 : init_var_from_num(Numeric num, NumericVar *dest)
7265 : {
7266 5862976 : dest->ndigits = NUMERIC_NDIGITS(num);
7267 5862976 : dest->weight = NUMERIC_WEIGHT(num);
7268 5862976 : dest->sign = NUMERIC_SIGN(num);
7269 5862976 : dest->dscale = NUMERIC_DSCALE(num);
7270 5862976 : dest->digits = NUMERIC_DIGITS(num);
7271 5862976 : dest->buf = NULL; /* digits array is not palloc'd */
7272 5862976 : }
7273 :
7274 :
7275 : /*
7276 : * set_var_from_var() -
7277 : *
7278 : * Copy one variable into another
7279 : */
7280 : static void
7281 35262 : set_var_from_var(const NumericVar *value, NumericVar *dest)
7282 : {
7283 : NumericDigit *newbuf;
7284 :
7285 35262 : newbuf = digitbuf_alloc(value->ndigits + 1);
7286 35262 : newbuf[0] = 0; /* spare digit for rounding */
7287 35262 : if (value->ndigits > 0) /* else value->digits might be null */
7288 34316 : memcpy(newbuf + 1, value->digits,
7289 34316 : value->ndigits * sizeof(NumericDigit));
7290 :
7291 35262 : digitbuf_free(dest->buf);
7292 :
7293 35262 : memmove(dest, value, sizeof(NumericVar));
7294 35262 : dest->buf = newbuf;
7295 35262 : dest->digits = newbuf + 1;
7296 35262 : }
7297 :
7298 :
7299 : /*
7300 : * get_str_from_var() -
7301 : *
7302 : * Convert a var to text representation (guts of numeric_out).
7303 : * The var is displayed to the number of digits indicated by its dscale.
7304 : * Returns a palloc'd string.
7305 : */
7306 : static char *
7307 884850 : get_str_from_var(const NumericVar *var)
7308 : {
7309 : int dscale;
7310 : char *str;
7311 : char *cp;
7312 : char *endcp;
7313 : int i;
7314 : int d;
7315 : NumericDigit dig;
7316 :
7317 : #if DEC_DIGITS > 1
7318 : NumericDigit d1;
7319 : #endif
7320 :
7321 884850 : dscale = var->dscale;
7322 :
7323 : /*
7324 : * Allocate space for the result.
7325 : *
7326 : * i is set to the # of decimal digits before decimal point. dscale is the
7327 : * # of decimal digits we will print after decimal point. We may generate
7328 : * as many as DEC_DIGITS-1 excess digits at the end, and in addition we
7329 : * need room for sign, decimal point, null terminator.
7330 : */
7331 884850 : i = (var->weight + 1) * DEC_DIGITS;
7332 884850 : if (i <= 0)
7333 137660 : i = 1;
7334 :
7335 884850 : str = palloc(i + dscale + DEC_DIGITS + 2);
7336 884850 : cp = str;
7337 :
7338 : /*
7339 : * Output a dash for negative values
7340 : */
7341 884850 : if (var->sign == NUMERIC_NEG)
7342 7330 : *cp++ = '-';
7343 :
7344 : /*
7345 : * Output all digits before the decimal point
7346 : */
7347 884850 : if (var->weight < 0)
7348 : {
7349 137660 : d = var->weight + 1;
7350 137660 : *cp++ = '0';
7351 : }
7352 : else
7353 : {
7354 1601810 : for (d = 0; d <= var->weight; d++)
7355 : {
7356 854620 : dig = (d < var->ndigits) ? var->digits[d] : 0;
7357 : /* In the first digit, suppress extra leading decimal zeroes */
7358 : #if DEC_DIGITS == 4
7359 : {
7360 854620 : bool putit = (d > 0);
7361 :
7362 854620 : d1 = dig / 1000;
7363 854620 : dig -= d1 * 1000;
7364 854620 : putit |= (d1 > 0);
7365 854620 : if (putit)
7366 169122 : *cp++ = d1 + '0';
7367 854620 : d1 = dig / 100;
7368 854620 : dig -= d1 * 100;
7369 854620 : putit |= (d1 > 0);
7370 854620 : if (putit)
7371 580018 : *cp++ = d1 + '0';
7372 854620 : d1 = dig / 10;
7373 854620 : dig -= d1 * 10;
7374 854620 : putit |= (d1 > 0);
7375 854620 : if (putit)
7376 712304 : *cp++ = d1 + '0';
7377 854620 : *cp++ = dig + '0';
7378 : }
7379 : #elif DEC_DIGITS == 2
7380 : d1 = dig / 10;
7381 : dig -= d1 * 10;
7382 : if (d1 > 0 || d > 0)
7383 : *cp++ = d1 + '0';
7384 : *cp++ = dig + '0';
7385 : #elif DEC_DIGITS == 1
7386 : *cp++ = dig + '0';
7387 : #else
7388 : #error unsupported NBASE
7389 : #endif
7390 : }
7391 : }
7392 :
7393 : /*
7394 : * If requested, output a decimal point and all the digits that follow it.
7395 : * We initially put out a multiple of DEC_DIGITS digits, then truncate if
7396 : * needed.
7397 : */
7398 884850 : if (dscale > 0)
7399 : {
7400 644678 : *cp++ = '.';
7401 644678 : endcp = cp + dscale;
7402 1901332 : for (i = 0; i < dscale; d++, i += DEC_DIGITS)
7403 : {
7404 1256654 : dig = (d >= 0 && d < var->ndigits) ? var->digits[d] : 0;
7405 : #if DEC_DIGITS == 4
7406 1256654 : d1 = dig / 1000;
7407 1256654 : dig -= d1 * 1000;
7408 1256654 : *cp++ = d1 + '0';
7409 1256654 : d1 = dig / 100;
7410 1256654 : dig -= d1 * 100;
7411 1256654 : *cp++ = d1 + '0';
7412 1256654 : d1 = dig / 10;
7413 1256654 : dig -= d1 * 10;
7414 1256654 : *cp++ = d1 + '0';
7415 1256654 : *cp++ = dig + '0';
7416 : #elif DEC_DIGITS == 2
7417 : d1 = dig / 10;
7418 : dig -= d1 * 10;
7419 : *cp++ = d1 + '0';
7420 : *cp++ = dig + '0';
7421 : #elif DEC_DIGITS == 1
7422 : *cp++ = dig + '0';
7423 : #else
7424 : #error unsupported NBASE
7425 : #endif
7426 : }
7427 644678 : cp = endcp;
7428 : }
7429 :
7430 : /*
7431 : * terminate the string and return it
7432 : */
7433 884850 : *cp = '\0';
7434 884850 : return str;
7435 : }
7436 :
7437 : /*
7438 : * get_str_from_var_sci() -
7439 : *
7440 : * Convert a var to a normalised scientific notation text representation.
7441 : * This function does the heavy lifting for numeric_out_sci().
7442 : *
7443 : * This notation has the general form a * 10^b, where a is known as the
7444 : * "significand" and b is known as the "exponent".
7445 : *
7446 : * Because we can't do superscript in ASCII (and because we want to copy
7447 : * printf's behaviour) we display the exponent using E notation, with a
7448 : * minimum of two exponent digits.
7449 : *
7450 : * For example, the value 1234 could be output as 1.2e+03.
7451 : *
7452 : * We assume that the exponent can fit into an int32.
7453 : *
7454 : * rscale is the number of decimal digits desired after the decimal point in
7455 : * the output, negative values will be treated as meaning zero.
7456 : *
7457 : * Returns a palloc'd string.
7458 : */
7459 : static char *
7460 228 : get_str_from_var_sci(const NumericVar *var, int rscale)
7461 : {
7462 : int32 exponent;
7463 : NumericVar tmp_var;
7464 : size_t len;
7465 : char *str;
7466 : char *sig_out;
7467 :
7468 228 : if (rscale < 0)
7469 0 : rscale = 0;
7470 :
7471 : /*
7472 : * Determine the exponent of this number in normalised form.
7473 : *
7474 : * This is the exponent required to represent the number with only one
7475 : * significant digit before the decimal place.
7476 : */
7477 228 : if (var->ndigits > 0)
7478 : {
7479 210 : exponent = (var->weight + 1) * DEC_DIGITS;
7480 :
7481 : /*
7482 : * Compensate for leading decimal zeroes in the first numeric digit by
7483 : * decrementing the exponent.
7484 : */
7485 210 : exponent -= DEC_DIGITS - (int) log10(var->digits[0]);
7486 : }
7487 : else
7488 : {
7489 : /*
7490 : * If var has no digits, then it must be zero.
7491 : *
7492 : * Zero doesn't technically have a meaningful exponent in normalised
7493 : * notation, but we just display the exponent as zero for consistency
7494 : * of output.
7495 : */
7496 18 : exponent = 0;
7497 : }
7498 :
7499 : /*
7500 : * Divide var by 10^exponent to get the significand, rounding to rscale
7501 : * decimal digits in the process.
7502 : */
7503 228 : init_var(&tmp_var);
7504 :
7505 228 : power_ten_int(exponent, &tmp_var);
7506 228 : div_var(var, &tmp_var, &tmp_var, rscale, true, true);
7507 228 : sig_out = get_str_from_var(&tmp_var);
7508 :
7509 228 : free_var(&tmp_var);
7510 :
7511 : /*
7512 : * Allocate space for the result.
7513 : *
7514 : * In addition to the significand, we need room for the exponent
7515 : * decoration ("e"), the sign of the exponent, up to 10 digits for the
7516 : * exponent itself, and of course the null terminator.
7517 : */
7518 228 : len = strlen(sig_out) + 13;
7519 228 : str = palloc(len);
7520 228 : snprintf(str, len, "%se%+03d", sig_out, exponent);
7521 :
7522 228 : pfree(sig_out);
7523 :
7524 228 : return str;
7525 : }
7526 :
7527 :
7528 : /*
7529 : * numericvar_serialize - serialize NumericVar to binary format
7530 : *
7531 : * At variable level, no checks are performed on the weight or dscale, allowing
7532 : * us to pass around intermediate values with higher precision than supported
7533 : * by the numeric type. Note: this is incompatible with numeric_send/recv(),
7534 : * which use 16-bit integers for these fields.
7535 : */
7536 : static void
7537 90 : numericvar_serialize(StringInfo buf, const NumericVar *var)
7538 : {
7539 : int i;
7540 :
7541 90 : pq_sendint32(buf, var->ndigits);
7542 90 : pq_sendint32(buf, var->weight);
7543 90 : pq_sendint32(buf, var->sign);
7544 90 : pq_sendint32(buf, var->dscale);
7545 637742 : for (i = 0; i < var->ndigits; i++)
7546 637652 : pq_sendint16(buf, var->digits[i]);
7547 90 : }
7548 :
7549 : /*
7550 : * numericvar_deserialize - deserialize binary format to NumericVar
7551 : */
7552 : static void
7553 90 : numericvar_deserialize(StringInfo buf, NumericVar *var)
7554 : {
7555 : int len,
7556 : i;
7557 :
7558 90 : len = pq_getmsgint(buf, sizeof(int32));
7559 :
7560 90 : alloc_var(var, len); /* sets var->ndigits */
7561 :
7562 90 : var->weight = pq_getmsgint(buf, sizeof(int32));
7563 90 : var->sign = pq_getmsgint(buf, sizeof(int32));
7564 90 : var->dscale = pq_getmsgint(buf, sizeof(int32));
7565 637742 : for (i = 0; i < len; i++)
7566 637652 : var->digits[i] = pq_getmsgint(buf, sizeof(int16));
7567 90 : }
7568 :
7569 :
7570 : /*
7571 : * duplicate_numeric() - copy a packed-format Numeric
7572 : *
7573 : * This will handle NaN and Infinity cases.
7574 : */
7575 : static Numeric
7576 28496 : duplicate_numeric(Numeric num)
7577 : {
7578 : Numeric res;
7579 :
7580 28496 : res = (Numeric) palloc(VARSIZE(num));
7581 28496 : memcpy(res, num, VARSIZE(num));
7582 28496 : return res;
7583 : }
7584 :
7585 : /*
7586 : * make_result_opt_error() -
7587 : *
7588 : * Create the packed db numeric format in palloc()'d memory from
7589 : * a variable. This will handle NaN and Infinity cases.
7590 : *
7591 : * If "have_error" isn't NULL, on overflow *have_error is set to true and
7592 : * NULL is returned. This is helpful when caller needs to handle errors.
7593 : */
7594 : static Numeric
7595 3810052 : make_result_opt_error(const NumericVar *var, bool *have_error)
7596 : {
7597 : Numeric result;
7598 3810052 : NumericDigit *digits = var->digits;
7599 3810052 : int weight = var->weight;
7600 3810052 : int sign = var->sign;
7601 : int n;
7602 : Size len;
7603 :
7604 3810052 : if (have_error)
7605 161966 : *have_error = false;
7606 :
7607 3810052 : if ((sign & NUMERIC_SIGN_MASK) == NUMERIC_SPECIAL)
7608 : {
7609 : /*
7610 : * Verify valid special value. This could be just an Assert, perhaps,
7611 : * but it seems worthwhile to expend a few cycles to ensure that we
7612 : * never write any nonzero reserved bits to disk.
7613 : */
7614 3282 : if (!(sign == NUMERIC_NAN ||
7615 : sign == NUMERIC_PINF ||
7616 : sign == NUMERIC_NINF))
7617 0 : elog(ERROR, "invalid numeric sign value 0x%x", sign);
7618 :
7619 3282 : result = (Numeric) palloc(NUMERIC_HDRSZ_SHORT);
7620 :
7621 3282 : SET_VARSIZE(result, NUMERIC_HDRSZ_SHORT);
7622 3282 : result->choice.n_header = sign;
7623 : /* the header word is all we need */
7624 :
7625 : dump_numeric("make_result()", result);
7626 3282 : return result;
7627 : }
7628 :
7629 3806770 : n = var->ndigits;
7630 :
7631 : /* truncate leading zeroes */
7632 3806806 : while (n > 0 && *digits == 0)
7633 : {
7634 36 : digits++;
7635 36 : weight--;
7636 36 : n--;
7637 : }
7638 : /* truncate trailing zeroes */
7639 3892106 : while (n > 0 && digits[n - 1] == 0)
7640 85336 : n--;
7641 :
7642 : /* If zero result, force to weight=0 and positive sign */
7643 3806770 : if (n == 0)
7644 : {
7645 132196 : weight = 0;
7646 132196 : sign = NUMERIC_POS;
7647 : }
7648 :
7649 : /* Build the result */
7650 3806770 : if (NUMERIC_CAN_BE_SHORT(var->dscale, weight))
7651 : {
7652 3804836 : len = NUMERIC_HDRSZ_SHORT + n * sizeof(NumericDigit);
7653 3804836 : result = (Numeric) palloc(len);
7654 3804836 : SET_VARSIZE(result, len);
7655 3804836 : result->choice.n_short.n_header =
7656 : (sign == NUMERIC_NEG ? (NUMERIC_SHORT | NUMERIC_SHORT_SIGN_MASK)
7657 : : NUMERIC_SHORT)
7658 3804836 : | (var->dscale << NUMERIC_SHORT_DSCALE_SHIFT)
7659 3804836 : | (weight < 0 ? NUMERIC_SHORT_WEIGHT_SIGN_MASK : 0)
7660 3804836 : | (weight & NUMERIC_SHORT_WEIGHT_MASK);
7661 : }
7662 : else
7663 : {
7664 1934 : len = NUMERIC_HDRSZ + n * sizeof(NumericDigit);
7665 1934 : result = (Numeric) palloc(len);
7666 1934 : SET_VARSIZE(result, len);
7667 1934 : result->choice.n_long.n_sign_dscale =
7668 1934 : sign | (var->dscale & NUMERIC_DSCALE_MASK);
7669 1934 : result->choice.n_long.n_weight = weight;
7670 : }
7671 :
7672 : Assert(NUMERIC_NDIGITS(result) == n);
7673 3806770 : if (n > 0)
7674 3674574 : memcpy(NUMERIC_DIGITS(result), digits, n * sizeof(NumericDigit));
7675 :
7676 : /* Check for overflow of int16 fields */
7677 3806770 : if (NUMERIC_WEIGHT(result) != weight ||
7678 3806740 : NUMERIC_DSCALE(result) != var->dscale)
7679 : {
7680 30 : if (have_error)
7681 : {
7682 18 : *have_error = true;
7683 18 : return NULL;
7684 : }
7685 : else
7686 : {
7687 12 : ereport(ERROR,
7688 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
7689 : errmsg("value overflows numeric format")));
7690 : }
7691 : }
7692 :
7693 : dump_numeric("make_result()", result);
7694 3806740 : return result;
7695 : }
7696 :
7697 :
7698 : /*
7699 : * make_result() -
7700 : *
7701 : * An interface to make_result_opt_error() without "have_error" argument.
7702 : */
7703 : static Numeric
7704 2268224 : make_result(const NumericVar *var)
7705 : {
7706 2268224 : return make_result_opt_error(var, NULL);
7707 : }
7708 :
7709 :
7710 : /*
7711 : * apply_typmod() -
7712 : *
7713 : * Do bounds checking and rounding according to the specified typmod.
7714 : * Note that this is only applied to normal finite values.
7715 : *
7716 : * Returns true on success, false on failure (if escontext points to an
7717 : * ErrorSaveContext; otherwise errors are thrown).
7718 : */
7719 : static bool
7720 166070 : apply_typmod(NumericVar *var, int32 typmod, Node *escontext)
7721 : {
7722 : int precision;
7723 : int scale;
7724 : int maxdigits;
7725 : int ddigits;
7726 : int i;
7727 :
7728 : /* Do nothing if we have an invalid typmod */
7729 166070 : if (!is_valid_numeric_typmod(typmod))
7730 136916 : return true;
7731 :
7732 29154 : precision = numeric_typmod_precision(typmod);
7733 29154 : scale = numeric_typmod_scale(typmod);
7734 29154 : maxdigits = precision - scale;
7735 :
7736 : /* Round to target scale (and set var->dscale) */
7737 29154 : round_var(var, scale);
7738 :
7739 : /* but don't allow var->dscale to be negative */
7740 29154 : if (var->dscale < 0)
7741 126 : var->dscale = 0;
7742 :
7743 : /*
7744 : * Check for overflow - note we can't do this before rounding, because
7745 : * rounding could raise the weight. Also note that the var's weight could
7746 : * be inflated by leading zeroes, which will be stripped before storage
7747 : * but perhaps might not have been yet. In any case, we must recognize a
7748 : * true zero, whose weight doesn't mean anything.
7749 : */
7750 29154 : ddigits = (var->weight + 1) * DEC_DIGITS;
7751 29154 : if (ddigits > maxdigits)
7752 : {
7753 : /* Determine true weight; and check for all-zero result */
7754 6422 : for (i = 0; i < var->ndigits; i++)
7755 : {
7756 6406 : NumericDigit dig = var->digits[i];
7757 :
7758 6406 : if (dig)
7759 : {
7760 : /* Adjust for any high-order decimal zero digits */
7761 : #if DEC_DIGITS == 4
7762 6406 : if (dig < 10)
7763 306 : ddigits -= 3;
7764 6100 : else if (dig < 100)
7765 624 : ddigits -= 2;
7766 5476 : else if (dig < 1000)
7767 5458 : ddigits -= 1;
7768 : #elif DEC_DIGITS == 2
7769 : if (dig < 10)
7770 : ddigits -= 1;
7771 : #elif DEC_DIGITS == 1
7772 : /* no adjustment */
7773 : #else
7774 : #error unsupported NBASE
7775 : #endif
7776 6406 : if (ddigits > maxdigits)
7777 84 : ereturn(escontext, false,
7778 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
7779 : errmsg("numeric field overflow"),
7780 : errdetail("A field with precision %d, scale %d must round to an absolute value less than %s%d.",
7781 : precision, scale,
7782 : /* Display 10^0 as 1 */
7783 : maxdigits ? "10^" : "",
7784 : maxdigits ? maxdigits : 1
7785 : )));
7786 6322 : break;
7787 : }
7788 0 : ddigits -= DEC_DIGITS;
7789 : }
7790 : }
7791 :
7792 29070 : return true;
7793 : }
7794 :
7795 : /*
7796 : * apply_typmod_special() -
7797 : *
7798 : * Do bounds checking according to the specified typmod, for an Inf or NaN.
7799 : * For convenience of most callers, the value is presented in packed form.
7800 : *
7801 : * Returns true on success, false on failure (if escontext points to an
7802 : * ErrorSaveContext; otherwise errors are thrown).
7803 : */
7804 : static bool
7805 1896 : apply_typmod_special(Numeric num, int32 typmod, Node *escontext)
7806 : {
7807 : int precision;
7808 : int scale;
7809 :
7810 : Assert(NUMERIC_IS_SPECIAL(num)); /* caller error if not */
7811 :
7812 : /*
7813 : * NaN is allowed regardless of the typmod; that's rather dubious perhaps,
7814 : * but it's a longstanding behavior. Inf is rejected if we have any
7815 : * typmod restriction, since an infinity shouldn't be claimed to fit in
7816 : * any finite number of digits.
7817 : */
7818 1896 : if (NUMERIC_IS_NAN(num))
7819 798 : return true;
7820 :
7821 : /* Do nothing if we have a default typmod (-1) */
7822 1098 : if (!is_valid_numeric_typmod(typmod))
7823 1080 : return true;
7824 :
7825 18 : precision = numeric_typmod_precision(typmod);
7826 18 : scale = numeric_typmod_scale(typmod);
7827 :
7828 18 : ereturn(escontext, false,
7829 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
7830 : errmsg("numeric field overflow"),
7831 : errdetail("A field with precision %d, scale %d cannot hold an infinite value.",
7832 : precision, scale)));
7833 : }
7834 :
7835 :
7836 : /*
7837 : * Convert numeric to int8, rounding if needed.
7838 : *
7839 : * If overflow, return false (no error is raised). Return true if okay.
7840 : */
7841 : static bool
7842 10386 : numericvar_to_int64(const NumericVar *var, int64 *result)
7843 : {
7844 : NumericDigit *digits;
7845 : int ndigits;
7846 : int weight;
7847 : int i;
7848 : int64 val;
7849 : bool neg;
7850 : NumericVar rounded;
7851 :
7852 : /* Round to nearest integer */
7853 10386 : init_var(&rounded);
7854 10386 : set_var_from_var(var, &rounded);
7855 10386 : round_var(&rounded, 0);
7856 :
7857 : /* Check for zero input */
7858 10386 : strip_var(&rounded);
7859 10386 : ndigits = rounded.ndigits;
7860 10386 : if (ndigits == 0)
7861 : {
7862 478 : *result = 0;
7863 478 : free_var(&rounded);
7864 478 : return true;
7865 : }
7866 :
7867 : /*
7868 : * For input like 10000000000, we must treat stripped digits as real. So
7869 : * the loop assumes there are weight+1 digits before the decimal point.
7870 : */
7871 9908 : weight = rounded.weight;
7872 : Assert(weight >= 0 && ndigits <= weight + 1);
7873 :
7874 : /*
7875 : * Construct the result. To avoid issues with converting a value
7876 : * corresponding to INT64_MIN (which can't be represented as a positive 64
7877 : * bit two's complement integer), accumulate value as a negative number.
7878 : */
7879 9908 : digits = rounded.digits;
7880 9908 : neg = (rounded.sign == NUMERIC_NEG);
7881 9908 : val = -digits[0];
7882 14108 : for (i = 1; i <= weight; i++)
7883 : {
7884 4248 : if (unlikely(pg_mul_s64_overflow(val, NBASE, &val)))
7885 : {
7886 30 : free_var(&rounded);
7887 30 : return false;
7888 : }
7889 :
7890 4218 : if (i < ndigits)
7891 : {
7892 3940 : if (unlikely(pg_sub_s64_overflow(val, digits[i], &val)))
7893 : {
7894 18 : free_var(&rounded);
7895 18 : return false;
7896 : }
7897 : }
7898 : }
7899 :
7900 9860 : free_var(&rounded);
7901 :
7902 9860 : if (!neg)
7903 : {
7904 9068 : if (unlikely(val == PG_INT64_MIN))
7905 24 : return false;
7906 9044 : val = -val;
7907 : }
7908 9836 : *result = val;
7909 :
7910 9836 : return true;
7911 : }
7912 :
7913 : /*
7914 : * Convert int8 value to numeric.
7915 : */
7916 : static void
7917 1900126 : int64_to_numericvar(int64 val, NumericVar *var)
7918 : {
7919 : uint64 uval,
7920 : newuval;
7921 : NumericDigit *ptr;
7922 : int ndigits;
7923 :
7924 : /* int64 can require at most 19 decimal digits; add one for safety */
7925 1900126 : alloc_var(var, 20 / DEC_DIGITS);
7926 1900126 : if (val < 0)
7927 : {
7928 1814 : var->sign = NUMERIC_NEG;
7929 1814 : uval = pg_abs_s64(val);
7930 : }
7931 : else
7932 : {
7933 1898312 : var->sign = NUMERIC_POS;
7934 1898312 : uval = val;
7935 : }
7936 1900126 : var->dscale = 0;
7937 1900126 : if (val == 0)
7938 : {
7939 30766 : var->ndigits = 0;
7940 30766 : var->weight = 0;
7941 30766 : return;
7942 : }
7943 1869360 : ptr = var->digits + var->ndigits;
7944 1869360 : ndigits = 0;
7945 : do
7946 : {
7947 2193114 : ptr--;
7948 2193114 : ndigits++;
7949 2193114 : newuval = uval / NBASE;
7950 2193114 : *ptr = uval - newuval * NBASE;
7951 2193114 : uval = newuval;
7952 2193114 : } while (uval);
7953 1869360 : var->digits = ptr;
7954 1869360 : var->ndigits = ndigits;
7955 1869360 : var->weight = ndigits - 1;
7956 : }
7957 :
7958 : /*
7959 : * Convert numeric to uint64, rounding if needed.
7960 : *
7961 : * If overflow, return false (no error is raised). Return true if okay.
7962 : */
7963 : static bool
7964 114 : numericvar_to_uint64(const NumericVar *var, uint64 *result)
7965 : {
7966 : NumericDigit *digits;
7967 : int ndigits;
7968 : int weight;
7969 : int i;
7970 : uint64 val;
7971 : NumericVar rounded;
7972 :
7973 : /* Round to nearest integer */
7974 114 : init_var(&rounded);
7975 114 : set_var_from_var(var, &rounded);
7976 114 : round_var(&rounded, 0);
7977 :
7978 : /* Check for zero input */
7979 114 : strip_var(&rounded);
7980 114 : ndigits = rounded.ndigits;
7981 114 : if (ndigits == 0)
7982 : {
7983 18 : *result = 0;
7984 18 : free_var(&rounded);
7985 18 : return true;
7986 : }
7987 :
7988 : /* Check for negative input */
7989 96 : if (rounded.sign == NUMERIC_NEG)
7990 : {
7991 12 : free_var(&rounded);
7992 12 : return false;
7993 : }
7994 :
7995 : /*
7996 : * For input like 10000000000, we must treat stripped digits as real. So
7997 : * the loop assumes there are weight+1 digits before the decimal point.
7998 : */
7999 84 : weight = rounded.weight;
8000 : Assert(weight >= 0 && ndigits <= weight + 1);
8001 :
8002 : /* Construct the result */
8003 84 : digits = rounded.digits;
8004 84 : val = digits[0];
8005 246 : for (i = 1; i <= weight; i++)
8006 : {
8007 174 : if (unlikely(pg_mul_u64_overflow(val, NBASE, &val)))
8008 : {
8009 0 : free_var(&rounded);
8010 0 : return false;
8011 : }
8012 :
8013 174 : if (i < ndigits)
8014 : {
8015 174 : if (unlikely(pg_add_u64_overflow(val, digits[i], &val)))
8016 : {
8017 12 : free_var(&rounded);
8018 12 : return false;
8019 : }
8020 : }
8021 : }
8022 :
8023 72 : free_var(&rounded);
8024 :
8025 72 : *result = val;
8026 :
8027 72 : return true;
8028 : }
8029 :
8030 : /*
8031 : * Convert 128 bit integer to numeric.
8032 : */
8033 : static void
8034 8796 : int128_to_numericvar(INT128 val, NumericVar *var)
8035 : {
8036 : int sign;
8037 : NumericDigit *ptr;
8038 : int ndigits;
8039 : int32 dig;
8040 :
8041 : /* int128 can require at most 39 decimal digits; add one for safety */
8042 8796 : alloc_var(var, 40 / DEC_DIGITS);
8043 8796 : sign = int128_sign(val);
8044 8796 : var->sign = sign < 0 ? NUMERIC_NEG : NUMERIC_POS;
8045 8796 : var->dscale = 0;
8046 8796 : if (sign == 0)
8047 : {
8048 214 : var->ndigits = 0;
8049 214 : var->weight = 0;
8050 214 : return;
8051 : }
8052 8582 : ptr = var->digits + var->ndigits;
8053 8582 : ndigits = 0;
8054 : do
8055 : {
8056 45238 : ptr--;
8057 45238 : ndigits++;
8058 45238 : int128_div_mod_int32(&val, NBASE, &dig);
8059 45238 : *ptr = (NumericDigit) abs(dig);
8060 45238 : } while (!int128_is_zero(val));
8061 8582 : var->digits = ptr;
8062 8582 : var->ndigits = ndigits;
8063 8582 : var->weight = ndigits - 1;
8064 : }
8065 :
8066 : /*
8067 : * Convert a NumericVar to float8; if out of range, return +/- HUGE_VAL
8068 : */
8069 : static double
8070 466 : numericvar_to_double_no_overflow(const NumericVar *var)
8071 : {
8072 : char *tmp;
8073 : double val;
8074 : char *endptr;
8075 :
8076 466 : tmp = get_str_from_var(var);
8077 :
8078 : /* unlike float8in, we ignore ERANGE from strtod */
8079 466 : val = strtod(tmp, &endptr);
8080 466 : if (*endptr != '\0')
8081 : {
8082 : /* shouldn't happen ... */
8083 0 : ereport(ERROR,
8084 : (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
8085 : errmsg("invalid input syntax for type %s: \"%s\"",
8086 : "double precision", tmp)));
8087 : }
8088 :
8089 466 : pfree(tmp);
8090 :
8091 466 : return val;
8092 : }
8093 :
8094 :
8095 : /*
8096 : * cmp_var() -
8097 : *
8098 : * Compare two values on variable level. We assume zeroes have been
8099 : * truncated to no digits.
8100 : */
8101 : static int
8102 170228 : cmp_var(const NumericVar *var1, const NumericVar *var2)
8103 : {
8104 340456 : return cmp_var_common(var1->digits, var1->ndigits,
8105 170228 : var1->weight, var1->sign,
8106 170228 : var2->digits, var2->ndigits,
8107 170228 : var2->weight, var2->sign);
8108 : }
8109 :
8110 : /*
8111 : * cmp_var_common() -
8112 : *
8113 : * Main routine of cmp_var(). This function can be used by both
8114 : * NumericVar and Numeric.
8115 : */
8116 : static int
8117 19507068 : cmp_var_common(const NumericDigit *var1digits, int var1ndigits,
8118 : int var1weight, int var1sign,
8119 : const NumericDigit *var2digits, int var2ndigits,
8120 : int var2weight, int var2sign)
8121 : {
8122 19507068 : if (var1ndigits == 0)
8123 : {
8124 531782 : if (var2ndigits == 0)
8125 434270 : return 0;
8126 97512 : if (var2sign == NUMERIC_NEG)
8127 4142 : return 1;
8128 93370 : return -1;
8129 : }
8130 18975286 : if (var2ndigits == 0)
8131 : {
8132 71956 : if (var1sign == NUMERIC_POS)
8133 65232 : return 1;
8134 6724 : return -1;
8135 : }
8136 :
8137 18903330 : if (var1sign == NUMERIC_POS)
8138 : {
8139 18823146 : if (var2sign == NUMERIC_NEG)
8140 24060 : return 1;
8141 18799086 : return cmp_abs_common(var1digits, var1ndigits, var1weight,
8142 : var2digits, var2ndigits, var2weight);
8143 : }
8144 :
8145 80184 : if (var2sign == NUMERIC_POS)
8146 22806 : return -1;
8147 :
8148 57378 : return cmp_abs_common(var2digits, var2ndigits, var2weight,
8149 : var1digits, var1ndigits, var1weight);
8150 : }
8151 :
8152 :
8153 : /*
8154 : * add_var() -
8155 : *
8156 : * Full version of add functionality on variable level (handling signs).
8157 : * result might point to one of the operands too without danger.
8158 : */
8159 : static void
8160 618100 : add_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
8161 : {
8162 : /*
8163 : * Decide on the signs of the two variables what to do
8164 : */
8165 618100 : if (var1->sign == NUMERIC_POS)
8166 : {
8167 616534 : if (var2->sign == NUMERIC_POS)
8168 : {
8169 : /*
8170 : * Both are positive result = +(ABS(var1) + ABS(var2))
8171 : */
8172 416170 : add_abs(var1, var2, result);
8173 416170 : result->sign = NUMERIC_POS;
8174 : }
8175 : else
8176 : {
8177 : /*
8178 : * var1 is positive, var2 is negative Must compare absolute values
8179 : */
8180 200364 : switch (cmp_abs(var1, var2))
8181 : {
8182 216 : case 0:
8183 : /* ----------
8184 : * ABS(var1) == ABS(var2)
8185 : * result = ZERO
8186 : * ----------
8187 : */
8188 216 : zero_var(result);
8189 216 : result->dscale = Max(var1->dscale, var2->dscale);
8190 216 : break;
8191 :
8192 186508 : case 1:
8193 : /* ----------
8194 : * ABS(var1) > ABS(var2)
8195 : * result = +(ABS(var1) - ABS(var2))
8196 : * ----------
8197 : */
8198 186508 : sub_abs(var1, var2, result);
8199 186508 : result->sign = NUMERIC_POS;
8200 186508 : break;
8201 :
8202 13640 : case -1:
8203 : /* ----------
8204 : * ABS(var1) < ABS(var2)
8205 : * result = -(ABS(var2) - ABS(var1))
8206 : * ----------
8207 : */
8208 13640 : sub_abs(var2, var1, result);
8209 13640 : result->sign = NUMERIC_NEG;
8210 13640 : break;
8211 : }
8212 : }
8213 : }
8214 : else
8215 : {
8216 1566 : if (var2->sign == NUMERIC_POS)
8217 : {
8218 : /* ----------
8219 : * var1 is negative, var2 is positive
8220 : * Must compare absolute values
8221 : * ----------
8222 : */
8223 468 : switch (cmp_abs(var1, var2))
8224 : {
8225 30 : case 0:
8226 : /* ----------
8227 : * ABS(var1) == ABS(var2)
8228 : * result = ZERO
8229 : * ----------
8230 : */
8231 30 : zero_var(result);
8232 30 : result->dscale = Max(var1->dscale, var2->dscale);
8233 30 : break;
8234 :
8235 294 : case 1:
8236 : /* ----------
8237 : * ABS(var1) > ABS(var2)
8238 : * result = -(ABS(var1) - ABS(var2))
8239 : * ----------
8240 : */
8241 294 : sub_abs(var1, var2, result);
8242 294 : result->sign = NUMERIC_NEG;
8243 294 : break;
8244 :
8245 144 : case -1:
8246 : /* ----------
8247 : * ABS(var1) < ABS(var2)
8248 : * result = +(ABS(var2) - ABS(var1))
8249 : * ----------
8250 : */
8251 144 : sub_abs(var2, var1, result);
8252 144 : result->sign = NUMERIC_POS;
8253 144 : break;
8254 : }
8255 : }
8256 : else
8257 : {
8258 : /* ----------
8259 : * Both are negative
8260 : * result = -(ABS(var1) + ABS(var2))
8261 : * ----------
8262 : */
8263 1098 : add_abs(var1, var2, result);
8264 1098 : result->sign = NUMERIC_NEG;
8265 : }
8266 : }
8267 618100 : }
8268 :
8269 :
8270 : /*
8271 : * sub_var() -
8272 : *
8273 : * Full version of sub functionality on variable level (handling signs).
8274 : * result might point to one of the operands too without danger.
8275 : */
8276 : static void
8277 533012 : sub_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
8278 : {
8279 : /*
8280 : * Decide on the signs of the two variables what to do
8281 : */
8282 533012 : if (var1->sign == NUMERIC_POS)
8283 : {
8284 532102 : if (var2->sign == NUMERIC_NEG)
8285 : {
8286 : /* ----------
8287 : * var1 is positive, var2 is negative
8288 : * result = +(ABS(var1) + ABS(var2))
8289 : * ----------
8290 : */
8291 28590 : add_abs(var1, var2, result);
8292 28590 : result->sign = NUMERIC_POS;
8293 : }
8294 : else
8295 : {
8296 : /* ----------
8297 : * Both are positive
8298 : * Must compare absolute values
8299 : * ----------
8300 : */
8301 503512 : switch (cmp_abs(var1, var2))
8302 : {
8303 49108 : case 0:
8304 : /* ----------
8305 : * ABS(var1) == ABS(var2)
8306 : * result = ZERO
8307 : * ----------
8308 : */
8309 49108 : zero_var(result);
8310 49108 : result->dscale = Max(var1->dscale, var2->dscale);
8311 49108 : break;
8312 :
8313 443642 : case 1:
8314 : /* ----------
8315 : * ABS(var1) > ABS(var2)
8316 : * result = +(ABS(var1) - ABS(var2))
8317 : * ----------
8318 : */
8319 443642 : sub_abs(var1, var2, result);
8320 443642 : result->sign = NUMERIC_POS;
8321 443642 : break;
8322 :
8323 10762 : case -1:
8324 : /* ----------
8325 : * ABS(var1) < ABS(var2)
8326 : * result = -(ABS(var2) - ABS(var1))
8327 : * ----------
8328 : */
8329 10762 : sub_abs(var2, var1, result);
8330 10762 : result->sign = NUMERIC_NEG;
8331 10762 : break;
8332 : }
8333 : }
8334 : }
8335 : else
8336 : {
8337 910 : if (var2->sign == NUMERIC_NEG)
8338 : {
8339 : /* ----------
8340 : * Both are negative
8341 : * Must compare absolute values
8342 : * ----------
8343 : */
8344 454 : switch (cmp_abs(var1, var2))
8345 : {
8346 166 : case 0:
8347 : /* ----------
8348 : * ABS(var1) == ABS(var2)
8349 : * result = ZERO
8350 : * ----------
8351 : */
8352 166 : zero_var(result);
8353 166 : result->dscale = Max(var1->dscale, var2->dscale);
8354 166 : break;
8355 :
8356 240 : case 1:
8357 : /* ----------
8358 : * ABS(var1) > ABS(var2)
8359 : * result = -(ABS(var1) - ABS(var2))
8360 : * ----------
8361 : */
8362 240 : sub_abs(var1, var2, result);
8363 240 : result->sign = NUMERIC_NEG;
8364 240 : break;
8365 :
8366 48 : case -1:
8367 : /* ----------
8368 : * ABS(var1) < ABS(var2)
8369 : * result = +(ABS(var2) - ABS(var1))
8370 : * ----------
8371 : */
8372 48 : sub_abs(var2, var1, result);
8373 48 : result->sign = NUMERIC_POS;
8374 48 : break;
8375 : }
8376 : }
8377 : else
8378 : {
8379 : /* ----------
8380 : * var1 is negative, var2 is positive
8381 : * result = -(ABS(var1) + ABS(var2))
8382 : * ----------
8383 : */
8384 456 : add_abs(var1, var2, result);
8385 456 : result->sign = NUMERIC_NEG;
8386 : }
8387 : }
8388 533012 : }
8389 :
8390 :
8391 : /*
8392 : * mul_var() -
8393 : *
8394 : * Multiplication on variable level. Product of var1 * var2 is stored
8395 : * in result. Result is rounded to no more than rscale fractional digits.
8396 : */
8397 : static void
8398 1189790 : mul_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result,
8399 : int rscale)
8400 : {
8401 : int res_ndigits;
8402 : int res_ndigitpairs;
8403 : int res_sign;
8404 : int res_weight;
8405 : int pair_offset;
8406 : int maxdigits;
8407 : int maxdigitpairs;
8408 : uint64 *dig,
8409 : *dig_i1_off;
8410 : uint64 maxdig;
8411 : uint64 carry;
8412 : uint64 newdig;
8413 : int var1ndigits;
8414 : int var2ndigits;
8415 : int var1ndigitpairs;
8416 : int var2ndigitpairs;
8417 : NumericDigit *var1digits;
8418 : NumericDigit *var2digits;
8419 : uint32 var1digitpair;
8420 : uint32 *var2digitpairs;
8421 : NumericDigit *res_digits;
8422 : int i,
8423 : i1,
8424 : i2,
8425 : i2limit;
8426 :
8427 : /*
8428 : * Arrange for var1 to be the shorter of the two numbers. This improves
8429 : * performance because the inner multiplication loop is much simpler than
8430 : * the outer loop, so it's better to have a smaller number of iterations
8431 : * of the outer loop. This also reduces the number of times that the
8432 : * accumulator array needs to be normalized.
8433 : */
8434 1189790 : if (var1->ndigits > var2->ndigits)
8435 : {
8436 15210 : const NumericVar *tmp = var1;
8437 :
8438 15210 : var1 = var2;
8439 15210 : var2 = tmp;
8440 : }
8441 :
8442 : /* copy these values into local vars for speed in inner loop */
8443 1189790 : var1ndigits = var1->ndigits;
8444 1189790 : var2ndigits = var2->ndigits;
8445 1189790 : var1digits = var1->digits;
8446 1189790 : var2digits = var2->digits;
8447 :
8448 1189790 : if (var1ndigits == 0)
8449 : {
8450 : /* one or both inputs is zero; so is result */
8451 2894 : zero_var(result);
8452 2894 : result->dscale = rscale;
8453 2894 : return;
8454 : }
8455 :
8456 : /*
8457 : * If var1 has 1-6 digits and the exact result was requested, delegate to
8458 : * mul_var_short() which uses a faster direct multiplication algorithm.
8459 : */
8460 1186896 : if (var1ndigits <= 6 && rscale == var1->dscale + var2->dscale)
8461 : {
8462 1158420 : mul_var_short(var1, var2, result);
8463 1158420 : return;
8464 : }
8465 :
8466 : /* Determine result sign */
8467 28476 : if (var1->sign == var2->sign)
8468 26994 : res_sign = NUMERIC_POS;
8469 : else
8470 1482 : res_sign = NUMERIC_NEG;
8471 :
8472 : /*
8473 : * Determine the number of result digits to compute and the (maximum
8474 : * possible) result weight. If the exact result would have more than
8475 : * rscale fractional digits, truncate the computation with
8476 : * MUL_GUARD_DIGITS guard digits, i.e., ignore input digits that would
8477 : * only contribute to the right of that. (This will give the exact
8478 : * rounded-to-rscale answer unless carries out of the ignored positions
8479 : * would have propagated through more than MUL_GUARD_DIGITS digits.)
8480 : *
8481 : * Note: an exact computation could not produce more than var1ndigits +
8482 : * var2ndigits digits, but we allocate at least one extra output digit in
8483 : * case rscale-driven rounding produces a carry out of the highest exact
8484 : * digit.
8485 : *
8486 : * The computation itself is done using base-NBASE^2 arithmetic, so we
8487 : * actually process the input digits in pairs, producing a base-NBASE^2
8488 : * intermediate result. This significantly improves performance, since
8489 : * schoolbook multiplication is O(N^2) in the number of input digits, and
8490 : * working in base NBASE^2 effectively halves "N".
8491 : *
8492 : * Note: in a truncated computation, we must compute at least one extra
8493 : * output digit to ensure that all the guard digits are fully computed.
8494 : */
8495 : /* digit pairs in each input */
8496 28476 : var1ndigitpairs = (var1ndigits + 1) / 2;
8497 28476 : var2ndigitpairs = (var2ndigits + 1) / 2;
8498 :
8499 : /* digits in exact result */
8500 28476 : res_ndigits = var1ndigits + var2ndigits;
8501 :
8502 : /* digit pairs in exact result with at least one extra output digit */
8503 28476 : res_ndigitpairs = res_ndigits / 2 + 1;
8504 :
8505 : /* pair offset to align result to end of dig[] */
8506 28476 : pair_offset = res_ndigitpairs - var1ndigitpairs - var2ndigitpairs + 1;
8507 :
8508 : /* maximum possible result weight (odd-length inputs shifted up below) */
8509 28476 : res_weight = var1->weight + var2->weight + 1 + 2 * res_ndigitpairs -
8510 28476 : res_ndigits - (var1ndigits & 1) - (var2ndigits & 1);
8511 :
8512 : /* rscale-based truncation with at least one extra output digit */
8513 28476 : maxdigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS +
8514 : MUL_GUARD_DIGITS;
8515 28476 : maxdigitpairs = maxdigits / 2 + 1;
8516 :
8517 28476 : res_ndigitpairs = Min(res_ndigitpairs, maxdigitpairs);
8518 28476 : res_ndigits = 2 * res_ndigitpairs;
8519 :
8520 : /*
8521 : * In the computation below, digit pair i1 of var1 and digit pair i2 of
8522 : * var2 are multiplied and added to digit i1+i2+pair_offset of dig[]. Thus
8523 : * input digit pairs with index >= res_ndigitpairs - pair_offset don't
8524 : * contribute to the result, and can be ignored.
8525 : */
8526 28476 : if (res_ndigitpairs <= pair_offset)
8527 : {
8528 : /* All input digits will be ignored; so result is zero */
8529 12 : zero_var(result);
8530 12 : result->dscale = rscale;
8531 12 : return;
8532 : }
8533 28464 : var1ndigitpairs = Min(var1ndigitpairs, res_ndigitpairs - pair_offset);
8534 28464 : var2ndigitpairs = Min(var2ndigitpairs, res_ndigitpairs - pair_offset);
8535 :
8536 : /*
8537 : * We do the arithmetic in an array "dig[]" of unsigned 64-bit integers.
8538 : * Since PG_UINT64_MAX is much larger than NBASE^4, this gives us a lot of
8539 : * headroom to avoid normalizing carries immediately.
8540 : *
8541 : * maxdig tracks the maximum possible value of any dig[] entry; when this
8542 : * threatens to exceed PG_UINT64_MAX, we take the time to propagate
8543 : * carries. Furthermore, we need to ensure that overflow doesn't occur
8544 : * during the carry propagation passes either. The carry values could be
8545 : * as much as PG_UINT64_MAX / NBASE^2, so really we must normalize when
8546 : * digits threaten to exceed PG_UINT64_MAX - PG_UINT64_MAX / NBASE^2.
8547 : *
8548 : * To avoid overflow in maxdig itself, it actually represents the maximum
8549 : * possible value divided by NBASE^2-1, i.e., at the top of the loop it is
8550 : * known that no dig[] entry exceeds maxdig * (NBASE^2-1).
8551 : *
8552 : * The conversion of var1 to base NBASE^2 is done on the fly, as each new
8553 : * digit is required. The digits of var2 are converted upfront, and
8554 : * stored at the end of dig[]. To avoid loss of precision, the input
8555 : * digits are aligned with the start of digit pair array, effectively
8556 : * shifting them up (multiplying by NBASE) if the inputs have an odd
8557 : * number of NBASE digits.
8558 : */
8559 28464 : dig = (uint64 *) palloc(res_ndigitpairs * sizeof(uint64) +
8560 : var2ndigitpairs * sizeof(uint32));
8561 :
8562 : /* convert var2 to base NBASE^2, shifting up if its length is odd */
8563 28464 : var2digitpairs = (uint32 *) (dig + res_ndigitpairs);
8564 :
8565 1547190 : for (i2 = 0; i2 < var2ndigitpairs - 1; i2++)
8566 1518726 : var2digitpairs[i2] = var2digits[2 * i2] * NBASE + var2digits[2 * i2 + 1];
8567 :
8568 28464 : if (2 * i2 + 1 < var2ndigits)
8569 20448 : var2digitpairs[i2] = var2digits[2 * i2] * NBASE + var2digits[2 * i2 + 1];
8570 : else
8571 8016 : var2digitpairs[i2] = var2digits[2 * i2] * NBASE;
8572 :
8573 : /*
8574 : * Start by multiplying var2 by the least significant contributing digit
8575 : * pair from var1, storing the results at the end of dig[], and filling
8576 : * the leading digits with zeros.
8577 : *
8578 : * The loop here is the same as the inner loop below, except that we set
8579 : * the results in dig[], rather than adding to them. This is the
8580 : * performance bottleneck for multiplication, so we want to keep it simple
8581 : * enough so that it can be auto-vectorized. Accordingly, process the
8582 : * digits left-to-right even though schoolbook multiplication would
8583 : * suggest right-to-left. Since we aren't propagating carries in this
8584 : * loop, the order does not matter.
8585 : */
8586 28464 : i1 = var1ndigitpairs - 1;
8587 28464 : if (2 * i1 + 1 < var1ndigits)
8588 12720 : var1digitpair = var1digits[2 * i1] * NBASE + var1digits[2 * i1 + 1];
8589 : else
8590 15744 : var1digitpair = var1digits[2 * i1] * NBASE;
8591 28464 : maxdig = var1digitpair;
8592 :
8593 28464 : i2limit = Min(var2ndigitpairs, res_ndigitpairs - i1 - pair_offset);
8594 28464 : dig_i1_off = &dig[i1 + pair_offset];
8595 :
8596 28464 : memset(dig, 0, (i1 + pair_offset) * sizeof(uint64));
8597 1376622 : for (i2 = 0; i2 < i2limit; i2++)
8598 1348158 : dig_i1_off[i2] = (uint64) var1digitpair * var2digitpairs[i2];
8599 :
8600 : /*
8601 : * Next, multiply var2 by the remaining digit pairs from var1, adding the
8602 : * results to dig[] at the appropriate offsets, and normalizing whenever
8603 : * there is a risk of any dig[] entry overflowing.
8604 : */
8605 1501710 : for (i1 = i1 - 1; i1 >= 0; i1--)
8606 : {
8607 1473246 : var1digitpair = var1digits[2 * i1] * NBASE + var1digits[2 * i1 + 1];
8608 1473246 : if (var1digitpair == 0)
8609 1179516 : continue;
8610 :
8611 : /* Time to normalize? */
8612 293730 : maxdig += var1digitpair;
8613 293730 : if (maxdig > (PG_UINT64_MAX - PG_UINT64_MAX / NBASE_SQR) / (NBASE_SQR - 1))
8614 : {
8615 : /* Yes, do it (to base NBASE^2) */
8616 30 : carry = 0;
8617 119964 : for (i = res_ndigitpairs - 1; i >= 0; i--)
8618 : {
8619 119934 : newdig = dig[i] + carry;
8620 119934 : if (newdig >= NBASE_SQR)
8621 : {
8622 115242 : carry = newdig / NBASE_SQR;
8623 115242 : newdig -= carry * NBASE_SQR;
8624 : }
8625 : else
8626 4692 : carry = 0;
8627 119934 : dig[i] = newdig;
8628 : }
8629 : Assert(carry == 0);
8630 : /* Reset maxdig to indicate new worst-case */
8631 30 : maxdig = 1 + var1digitpair;
8632 : }
8633 :
8634 : /* Multiply and add */
8635 293730 : i2limit = Min(var2ndigitpairs, res_ndigitpairs - i1 - pair_offset);
8636 293730 : dig_i1_off = &dig[i1 + pair_offset];
8637 :
8638 124047846 : for (i2 = 0; i2 < i2limit; i2++)
8639 123754116 : dig_i1_off[i2] += (uint64) var1digitpair * var2digitpairs[i2];
8640 : }
8641 :
8642 : /*
8643 : * Now we do a final carry propagation pass to normalize back to base
8644 : * NBASE^2, and construct the base-NBASE result digits. Note that this is
8645 : * still done at full precision w/guard digits.
8646 : */
8647 28464 : alloc_var(result, res_ndigits);
8648 28464 : res_digits = result->digits;
8649 28464 : carry = 0;
8650 2882922 : for (i = res_ndigitpairs - 1; i >= 0; i--)
8651 : {
8652 2854458 : newdig = dig[i] + carry;
8653 2854458 : if (newdig >= NBASE_SQR)
8654 : {
8655 406914 : carry = newdig / NBASE_SQR;
8656 406914 : newdig -= carry * NBASE_SQR;
8657 : }
8658 : else
8659 2447544 : carry = 0;
8660 2854458 : res_digits[2 * i + 1] = (NumericDigit) ((uint32) newdig % NBASE);
8661 2854458 : res_digits[2 * i] = (NumericDigit) ((uint32) newdig / NBASE);
8662 : }
8663 : Assert(carry == 0);
8664 :
8665 28464 : pfree(dig);
8666 :
8667 : /*
8668 : * Finally, round the result to the requested precision.
8669 : */
8670 28464 : result->weight = res_weight;
8671 28464 : result->sign = res_sign;
8672 :
8673 : /* Round to target rscale (and set result->dscale) */
8674 28464 : round_var(result, rscale);
8675 :
8676 : /* Strip leading and trailing zeroes */
8677 28464 : strip_var(result);
8678 : }
8679 :
8680 :
8681 : /*
8682 : * mul_var_short() -
8683 : *
8684 : * Special-case multiplication function used when var1 has 1-6 digits, var2
8685 : * has at least as many digits as var1, and the exact product var1 * var2 is
8686 : * requested.
8687 : */
8688 : static void
8689 1158420 : mul_var_short(const NumericVar *var1, const NumericVar *var2,
8690 : NumericVar *result)
8691 : {
8692 1158420 : int var1ndigits = var1->ndigits;
8693 1158420 : int var2ndigits = var2->ndigits;
8694 1158420 : NumericDigit *var1digits = var1->digits;
8695 1158420 : NumericDigit *var2digits = var2->digits;
8696 : int res_sign;
8697 : int res_weight;
8698 : int res_ndigits;
8699 : NumericDigit *res_buf;
8700 : NumericDigit *res_digits;
8701 1158420 : uint32 carry = 0;
8702 : uint32 term;
8703 :
8704 : /* Check preconditions */
8705 : Assert(var1ndigits >= 1);
8706 : Assert(var1ndigits <= 6);
8707 : Assert(var2ndigits >= var1ndigits);
8708 :
8709 : /*
8710 : * Determine the result sign, weight, and number of digits to calculate.
8711 : * The weight figured here is correct if the product has no leading zero
8712 : * digits; otherwise strip_var() will fix things up. Note that, unlike
8713 : * mul_var(), we do not need to allocate an extra output digit, because we
8714 : * are not rounding here.
8715 : */
8716 1158420 : if (var1->sign == var2->sign)
8717 1157228 : res_sign = NUMERIC_POS;
8718 : else
8719 1192 : res_sign = NUMERIC_NEG;
8720 1158420 : res_weight = var1->weight + var2->weight + 1;
8721 1158420 : res_ndigits = var1ndigits + var2ndigits;
8722 :
8723 : /* Allocate result digit array */
8724 1158420 : res_buf = digitbuf_alloc(res_ndigits + 1);
8725 1158420 : res_buf[0] = 0; /* spare digit for later rounding */
8726 1158420 : res_digits = res_buf + 1;
8727 :
8728 : /*
8729 : * Compute the result digits in reverse, in one pass, propagating the
8730 : * carry up as we go. The i'th result digit consists of the sum of the
8731 : * products var1digits[i1] * var2digits[i2] for which i = i1 + i2 + 1.
8732 : */
8733 : #define PRODSUM1(v1,i1,v2,i2) ((v1)[(i1)] * (v2)[(i2)])
8734 : #define PRODSUM2(v1,i1,v2,i2) (PRODSUM1(v1,i1,v2,i2) + (v1)[(i1)+1] * (v2)[(i2)-1])
8735 : #define PRODSUM3(v1,i1,v2,i2) (PRODSUM2(v1,i1,v2,i2) + (v1)[(i1)+2] * (v2)[(i2)-2])
8736 : #define PRODSUM4(v1,i1,v2,i2) (PRODSUM3(v1,i1,v2,i2) + (v1)[(i1)+3] * (v2)[(i2)-3])
8737 : #define PRODSUM5(v1,i1,v2,i2) (PRODSUM4(v1,i1,v2,i2) + (v1)[(i1)+4] * (v2)[(i2)-4])
8738 : #define PRODSUM6(v1,i1,v2,i2) (PRODSUM5(v1,i1,v2,i2) + (v1)[(i1)+5] * (v2)[(i2)-5])
8739 :
8740 1158420 : switch (var1ndigits)
8741 : {
8742 1152714 : case 1:
8743 : /* ---------
8744 : * 1-digit case:
8745 : * var1ndigits = 1
8746 : * var2ndigits >= 1
8747 : * res_ndigits = var2ndigits + 1
8748 : * ----------
8749 : */
8750 3605228 : for (int i = var2ndigits - 1; i >= 0; i--)
8751 : {
8752 2452514 : term = PRODSUM1(var1digits, 0, var2digits, i) + carry;
8753 2452514 : res_digits[i + 1] = (NumericDigit) (term % NBASE);
8754 2452514 : carry = term / NBASE;
8755 : }
8756 1152714 : res_digits[0] = (NumericDigit) carry;
8757 1152714 : break;
8758 :
8759 756 : case 2:
8760 : /* ---------
8761 : * 2-digit case:
8762 : * var1ndigits = 2
8763 : * var2ndigits >= 2
8764 : * res_ndigits = var2ndigits + 2
8765 : * ----------
8766 : */
8767 : /* last result digit and carry */
8768 756 : term = PRODSUM1(var1digits, 1, var2digits, var2ndigits - 1);
8769 756 : res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
8770 756 : carry = term / NBASE;
8771 :
8772 : /* remaining digits, except for the first two */
8773 2304 : for (int i = var2ndigits - 1; i >= 1; i--)
8774 : {
8775 1548 : term = PRODSUM2(var1digits, 0, var2digits, i) + carry;
8776 1548 : res_digits[i + 1] = (NumericDigit) (term % NBASE);
8777 1548 : carry = term / NBASE;
8778 : }
8779 756 : break;
8780 :
8781 204 : case 3:
8782 : /* ---------
8783 : * 3-digit case:
8784 : * var1ndigits = 3
8785 : * var2ndigits >= 3
8786 : * res_ndigits = var2ndigits + 3
8787 : * ----------
8788 : */
8789 : /* last two result digits */
8790 204 : term = PRODSUM1(var1digits, 2, var2digits, var2ndigits - 1);
8791 204 : res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
8792 204 : carry = term / NBASE;
8793 :
8794 204 : term = PRODSUM2(var1digits, 1, var2digits, var2ndigits - 1) + carry;
8795 204 : res_digits[res_ndigits - 2] = (NumericDigit) (term % NBASE);
8796 204 : carry = term / NBASE;
8797 :
8798 : /* remaining digits, except for the first three */
8799 546 : for (int i = var2ndigits - 1; i >= 2; i--)
8800 : {
8801 342 : term = PRODSUM3(var1digits, 0, var2digits, i) + carry;
8802 342 : res_digits[i + 1] = (NumericDigit) (term % NBASE);
8803 342 : carry = term / NBASE;
8804 : }
8805 204 : break;
8806 :
8807 4038 : case 4:
8808 : /* ---------
8809 : * 4-digit case:
8810 : * var1ndigits = 4
8811 : * var2ndigits >= 4
8812 : * res_ndigits = var2ndigits + 4
8813 : * ----------
8814 : */
8815 : /* last three result digits */
8816 4038 : term = PRODSUM1(var1digits, 3, var2digits, var2ndigits - 1);
8817 4038 : res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
8818 4038 : carry = term / NBASE;
8819 :
8820 4038 : term = PRODSUM2(var1digits, 2, var2digits, var2ndigits - 1) + carry;
8821 4038 : res_digits[res_ndigits - 2] = (NumericDigit) (term % NBASE);
8822 4038 : carry = term / NBASE;
8823 :
8824 4038 : term = PRODSUM3(var1digits, 1, var2digits, var2ndigits - 1) + carry;
8825 4038 : res_digits[res_ndigits - 3] = (NumericDigit) (term % NBASE);
8826 4038 : carry = term / NBASE;
8827 :
8828 : /* remaining digits, except for the first four */
8829 11268 : for (int i = var2ndigits - 1; i >= 3; i--)
8830 : {
8831 7230 : term = PRODSUM4(var1digits, 0, var2digits, i) + carry;
8832 7230 : res_digits[i + 1] = (NumericDigit) (term % NBASE);
8833 7230 : carry = term / NBASE;
8834 : }
8835 4038 : break;
8836 :
8837 114 : case 5:
8838 : /* ---------
8839 : * 5-digit case:
8840 : * var1ndigits = 5
8841 : * var2ndigits >= 5
8842 : * res_ndigits = var2ndigits + 5
8843 : * ----------
8844 : */
8845 : /* last four result digits */
8846 114 : term = PRODSUM1(var1digits, 4, var2digits, var2ndigits - 1);
8847 114 : res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
8848 114 : carry = term / NBASE;
8849 :
8850 114 : term = PRODSUM2(var1digits, 3, var2digits, var2ndigits - 1) + carry;
8851 114 : res_digits[res_ndigits - 2] = (NumericDigit) (term % NBASE);
8852 114 : carry = term / NBASE;
8853 :
8854 114 : term = PRODSUM3(var1digits, 2, var2digits, var2ndigits - 1) + carry;
8855 114 : res_digits[res_ndigits - 3] = (NumericDigit) (term % NBASE);
8856 114 : carry = term / NBASE;
8857 :
8858 114 : term = PRODSUM4(var1digits, 1, var2digits, var2ndigits - 1) + carry;
8859 114 : res_digits[res_ndigits - 4] = (NumericDigit) (term % NBASE);
8860 114 : carry = term / NBASE;
8861 :
8862 : /* remaining digits, except for the first five */
8863 300 : for (int i = var2ndigits - 1; i >= 4; i--)
8864 : {
8865 186 : term = PRODSUM5(var1digits, 0, var2digits, i) + carry;
8866 186 : res_digits[i + 1] = (NumericDigit) (term % NBASE);
8867 186 : carry = term / NBASE;
8868 : }
8869 114 : break;
8870 :
8871 594 : case 6:
8872 : /* ---------
8873 : * 6-digit case:
8874 : * var1ndigits = 6
8875 : * var2ndigits >= 6
8876 : * res_ndigits = var2ndigits + 6
8877 : * ----------
8878 : */
8879 : /* last five result digits */
8880 594 : term = PRODSUM1(var1digits, 5, var2digits, var2ndigits - 1);
8881 594 : res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
8882 594 : carry = term / NBASE;
8883 :
8884 594 : term = PRODSUM2(var1digits, 4, var2digits, var2ndigits - 1) + carry;
8885 594 : res_digits[res_ndigits - 2] = (NumericDigit) (term % NBASE);
8886 594 : carry = term / NBASE;
8887 :
8888 594 : term = PRODSUM3(var1digits, 3, var2digits, var2ndigits - 1) + carry;
8889 594 : res_digits[res_ndigits - 3] = (NumericDigit) (term % NBASE);
8890 594 : carry = term / NBASE;
8891 :
8892 594 : term = PRODSUM4(var1digits, 2, var2digits, var2ndigits - 1) + carry;
8893 594 : res_digits[res_ndigits - 4] = (NumericDigit) (term % NBASE);
8894 594 : carry = term / NBASE;
8895 :
8896 594 : term = PRODSUM5(var1digits, 1, var2digits, var2ndigits - 1) + carry;
8897 594 : res_digits[res_ndigits - 5] = (NumericDigit) (term % NBASE);
8898 594 : carry = term / NBASE;
8899 :
8900 : /* remaining digits, except for the first six */
8901 1656 : for (int i = var2ndigits - 1; i >= 5; i--)
8902 : {
8903 1062 : term = PRODSUM6(var1digits, 0, var2digits, i) + carry;
8904 1062 : res_digits[i + 1] = (NumericDigit) (term % NBASE);
8905 1062 : carry = term / NBASE;
8906 : }
8907 594 : break;
8908 : }
8909 :
8910 : /*
8911 : * Finally, for var1ndigits > 1, compute the remaining var1ndigits most
8912 : * significant result digits.
8913 : */
8914 1158420 : switch (var1ndigits)
8915 : {
8916 594 : case 6:
8917 594 : term = PRODSUM5(var1digits, 0, var2digits, 4) + carry;
8918 594 : res_digits[5] = (NumericDigit) (term % NBASE);
8919 594 : carry = term / NBASE;
8920 : /* FALLTHROUGH */
8921 708 : case 5:
8922 708 : term = PRODSUM4(var1digits, 0, var2digits, 3) + carry;
8923 708 : res_digits[4] = (NumericDigit) (term % NBASE);
8924 708 : carry = term / NBASE;
8925 : /* FALLTHROUGH */
8926 4746 : case 4:
8927 4746 : term = PRODSUM3(var1digits, 0, var2digits, 2) + carry;
8928 4746 : res_digits[3] = (NumericDigit) (term % NBASE);
8929 4746 : carry = term / NBASE;
8930 : /* FALLTHROUGH */
8931 4950 : case 3:
8932 4950 : term = PRODSUM2(var1digits, 0, var2digits, 1) + carry;
8933 4950 : res_digits[2] = (NumericDigit) (term % NBASE);
8934 4950 : carry = term / NBASE;
8935 : /* FALLTHROUGH */
8936 5706 : case 2:
8937 5706 : term = PRODSUM1(var1digits, 0, var2digits, 0) + carry;
8938 5706 : res_digits[1] = (NumericDigit) (term % NBASE);
8939 5706 : res_digits[0] = (NumericDigit) (term / NBASE);
8940 5706 : break;
8941 : }
8942 :
8943 : /* Store the product in result */
8944 1158420 : digitbuf_free(result->buf);
8945 1158420 : result->ndigits = res_ndigits;
8946 1158420 : result->buf = res_buf;
8947 1158420 : result->digits = res_digits;
8948 1158420 : result->weight = res_weight;
8949 1158420 : result->sign = res_sign;
8950 1158420 : result->dscale = var1->dscale + var2->dscale;
8951 :
8952 : /* Strip leading and trailing zeroes */
8953 1158420 : strip_var(result);
8954 1158420 : }
8955 :
8956 :
8957 : /*
8958 : * div_var() -
8959 : *
8960 : * Compute the quotient var1 / var2 to rscale fractional digits.
8961 : *
8962 : * If "round" is true, the result is rounded at the rscale'th digit; if
8963 : * false, it is truncated (towards zero) at that digit.
8964 : *
8965 : * If "exact" is true, the exact result is computed to the specified rscale;
8966 : * if false, successive quotient digits are approximated up to rscale plus
8967 : * DIV_GUARD_DIGITS extra digits, ignoring all contributions from digits to
8968 : * the right of that, before rounding or truncating to the specified rscale.
8969 : * This can be significantly faster, and usually gives the same result as the
8970 : * exact computation, but it may occasionally be off by one in the final
8971 : * digit, if contributions from the ignored digits would have propagated
8972 : * through the guard digits. This is good enough for the transcendental
8973 : * functions, where small errors are acceptable.
8974 : */
8975 : static void
8976 571188 : div_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result,
8977 : int rscale, bool round, bool exact)
8978 : {
8979 571188 : int var1ndigits = var1->ndigits;
8980 571188 : int var2ndigits = var2->ndigits;
8981 : int res_sign;
8982 : int res_weight;
8983 : int res_ndigits;
8984 : int var1ndigitpairs;
8985 : int var2ndigitpairs;
8986 : int res_ndigitpairs;
8987 : int div_ndigitpairs;
8988 : int64 *dividend;
8989 : int32 *divisor;
8990 : double fdivisor,
8991 : fdivisorinverse,
8992 : fdividend,
8993 : fquotient;
8994 : int64 maxdiv;
8995 : int qi;
8996 : int32 qdigit;
8997 : int64 carry;
8998 : int64 newdig;
8999 : int64 *remainder;
9000 : NumericDigit *res_digits;
9001 : int i;
9002 :
9003 : /*
9004 : * First of all division by zero check; we must not be handed an
9005 : * unnormalized divisor.
9006 : */
9007 571188 : if (var2ndigits == 0 || var2->digits[0] == 0)
9008 62 : ereport(ERROR,
9009 : (errcode(ERRCODE_DIVISION_BY_ZERO),
9010 : errmsg("division by zero")));
9011 :
9012 : /*
9013 : * If the divisor has just one or two digits, delegate to div_var_int(),
9014 : * which uses fast short division.
9015 : *
9016 : * Similarly, on platforms with 128-bit integer support, delegate to
9017 : * div_var_int64() for divisors with three or four digits.
9018 : */
9019 571126 : if (var2ndigits <= 2)
9020 : {
9021 : int idivisor;
9022 : int idivisor_weight;
9023 :
9024 565120 : idivisor = var2->digits[0];
9025 565120 : idivisor_weight = var2->weight;
9026 565120 : if (var2ndigits == 2)
9027 : {
9028 3902 : idivisor = idivisor * NBASE + var2->digits[1];
9029 3902 : idivisor_weight--;
9030 : }
9031 565120 : if (var2->sign == NUMERIC_NEG)
9032 654 : idivisor = -idivisor;
9033 :
9034 565120 : div_var_int(var1, idivisor, idivisor_weight, result, rscale, round);
9035 565120 : return;
9036 : }
9037 : #ifdef HAVE_INT128
9038 6006 : if (var2ndigits <= 4)
9039 : {
9040 : int64 idivisor;
9041 : int idivisor_weight;
9042 :
9043 528 : idivisor = var2->digits[0];
9044 528 : idivisor_weight = var2->weight;
9045 1968 : for (i = 1; i < var2ndigits; i++)
9046 : {
9047 1440 : idivisor = idivisor * NBASE + var2->digits[i];
9048 1440 : idivisor_weight--;
9049 : }
9050 528 : if (var2->sign == NUMERIC_NEG)
9051 120 : idivisor = -idivisor;
9052 :
9053 528 : div_var_int64(var1, idivisor, idivisor_weight, result, rscale, round);
9054 528 : return;
9055 : }
9056 : #endif
9057 :
9058 : /*
9059 : * Otherwise, perform full long division.
9060 : */
9061 :
9062 : /* Result zero check */
9063 5478 : if (var1ndigits == 0)
9064 : {
9065 36 : zero_var(result);
9066 36 : result->dscale = rscale;
9067 36 : return;
9068 : }
9069 :
9070 : /*
9071 : * The approximate computation can be significantly faster than the exact
9072 : * one, since the working dividend is var2ndigitpairs base-NBASE^2 digits
9073 : * shorter below. However, that comes with the tradeoff of computing
9074 : * DIV_GUARD_DIGITS extra base-NBASE result digits. Ignoring all other
9075 : * overheads, that suggests that, in theory, the approximate computation
9076 : * will only be faster than the exact one when var2ndigits is greater than
9077 : * 2 * (DIV_GUARD_DIGITS + 1), independent of the size of var1.
9078 : *
9079 : * Thus, we're better off doing an exact computation when var2 is shorter
9080 : * than this. Empirically, it has been found that the exact threshold is
9081 : * a little higher, due to other overheads in the outer division loop.
9082 : */
9083 5442 : if (var2ndigits <= 2 * (DIV_GUARD_DIGITS + 2))
9084 3708 : exact = true;
9085 :
9086 : /*
9087 : * Determine the result sign, weight and number of digits to calculate.
9088 : * The weight figured here is correct if the emitted quotient has no
9089 : * leading zero digits; otherwise strip_var() will fix things up.
9090 : */
9091 5442 : if (var1->sign == var2->sign)
9092 5310 : res_sign = NUMERIC_POS;
9093 : else
9094 132 : res_sign = NUMERIC_NEG;
9095 5442 : res_weight = var1->weight - var2->weight + 1;
9096 : /* The number of accurate result digits we need to produce: */
9097 5442 : res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
9098 : /* ... but always at least 1 */
9099 5442 : res_ndigits = Max(res_ndigits, 1);
9100 : /* If rounding needed, figure one more digit to ensure correct result */
9101 5442 : if (round)
9102 906 : res_ndigits++;
9103 : /* Add guard digits for roundoff error when producing approx result */
9104 5442 : if (!exact)
9105 1722 : res_ndigits += DIV_GUARD_DIGITS;
9106 :
9107 : /*
9108 : * The computation itself is done using base-NBASE^2 arithmetic, so we
9109 : * actually process the input digits in pairs, producing a base-NBASE^2
9110 : * intermediate result. This significantly improves performance, since
9111 : * the computation is O(N^2) in the number of input digits, and working in
9112 : * base NBASE^2 effectively halves "N".
9113 : */
9114 5442 : var1ndigitpairs = (var1ndigits + 1) / 2;
9115 5442 : var2ndigitpairs = (var2ndigits + 1) / 2;
9116 5442 : res_ndigitpairs = (res_ndigits + 1) / 2;
9117 5442 : res_ndigits = 2 * res_ndigitpairs;
9118 :
9119 : /*
9120 : * We do the arithmetic in an array "dividend[]" of signed 64-bit
9121 : * integers. Since PG_INT64_MAX is much larger than NBASE^4, this gives
9122 : * us a lot of headroom to avoid normalizing carries immediately.
9123 : *
9124 : * When performing an exact computation, the working dividend requires
9125 : * res_ndigitpairs + var2ndigitpairs digits. If var1 is larger than that,
9126 : * the extra digits do not contribute to the result, and are ignored.
9127 : *
9128 : * When performing an approximate computation, the working dividend only
9129 : * requires res_ndigitpairs digits (which includes the extra guard
9130 : * digits). All input digits beyond that are ignored.
9131 : */
9132 5442 : if (exact)
9133 : {
9134 3720 : div_ndigitpairs = res_ndigitpairs + var2ndigitpairs;
9135 3720 : var1ndigitpairs = Min(var1ndigitpairs, div_ndigitpairs);
9136 : }
9137 : else
9138 : {
9139 1722 : div_ndigitpairs = res_ndigitpairs;
9140 1722 : var1ndigitpairs = Min(var1ndigitpairs, div_ndigitpairs);
9141 1722 : var2ndigitpairs = Min(var2ndigitpairs, div_ndigitpairs);
9142 : }
9143 :
9144 : /*
9145 : * Allocate room for the working dividend (div_ndigitpairs 64-bit digits)
9146 : * plus the divisor (var2ndigitpairs 32-bit base-NBASE^2 digits).
9147 : *
9148 : * For convenience, we allocate one extra dividend digit, which is set to
9149 : * zero and not counted in div_ndigitpairs, so that the main loop below
9150 : * can safely read and write the (qi+1)'th digit in the approximate case.
9151 : */
9152 5442 : dividend = (int64 *) palloc((div_ndigitpairs + 1) * sizeof(int64) +
9153 : var2ndigitpairs * sizeof(int32));
9154 5442 : divisor = (int32 *) (dividend + div_ndigitpairs + 1);
9155 :
9156 : /* load var1 into dividend[0 .. var1ndigitpairs-1], zeroing the rest */
9157 49458 : for (i = 0; i < var1ndigitpairs - 1; i++)
9158 44016 : dividend[i] = var1->digits[2 * i] * NBASE + var1->digits[2 * i + 1];
9159 :
9160 5442 : if (2 * i + 1 < var1ndigits)
9161 3282 : dividend[i] = var1->digits[2 * i] * NBASE + var1->digits[2 * i + 1];
9162 : else
9163 2160 : dividend[i] = var1->digits[2 * i] * NBASE;
9164 :
9165 5442 : memset(dividend + i + 1, 0, (div_ndigitpairs - i) * sizeof(int64));
9166 :
9167 : /* load var2 into divisor[0 .. var2ndigitpairs-1] */
9168 39840 : for (i = 0; i < var2ndigitpairs - 1; i++)
9169 34398 : divisor[i] = var2->digits[2 * i] * NBASE + var2->digits[2 * i + 1];
9170 :
9171 5442 : if (2 * i + 1 < var2ndigits)
9172 2922 : divisor[i] = var2->digits[2 * i] * NBASE + var2->digits[2 * i + 1];
9173 : else
9174 2520 : divisor[i] = var2->digits[2 * i] * NBASE;
9175 :
9176 : /*
9177 : * We estimate each quotient digit using floating-point arithmetic, taking
9178 : * the first 2 base-NBASE^2 digits of the (current) dividend and divisor.
9179 : * This must be float to avoid overflow.
9180 : *
9181 : * Since the floating-point dividend and divisor use 4 base-NBASE input
9182 : * digits, they include roughly 40-53 bits of information from their
9183 : * respective inputs (assuming NBASE is 10000), which fits well in IEEE
9184 : * double-precision variables. The relative error in the floating-point
9185 : * quotient digit will then be less than around 2/NBASE^3, so the
9186 : * estimated base-NBASE^2 quotient digit will typically be correct, and
9187 : * should not be off by more than one from the correct value.
9188 : */
9189 5442 : fdivisor = (double) divisor[0] * NBASE_SQR;
9190 5442 : if (var2ndigitpairs > 1)
9191 5442 : fdivisor += (double) divisor[1];
9192 5442 : fdivisorinverse = 1.0 / fdivisor;
9193 :
9194 : /*
9195 : * maxdiv tracks the maximum possible absolute value of any dividend[]
9196 : * entry; when this threatens to exceed PG_INT64_MAX, we take the time to
9197 : * propagate carries. Furthermore, we need to ensure that overflow
9198 : * doesn't occur during the carry propagation passes either. The carry
9199 : * values may have an absolute value as high as PG_INT64_MAX/NBASE^2 + 1,
9200 : * so really we must normalize when digits threaten to exceed PG_INT64_MAX
9201 : * - PG_INT64_MAX/NBASE^2 - 1.
9202 : *
9203 : * To avoid overflow in maxdiv itself, it represents the max absolute
9204 : * value divided by NBASE^2-1, i.e., at the top of the loop it is known
9205 : * that no dividend[] entry has an absolute value exceeding maxdiv *
9206 : * (NBASE^2-1).
9207 : *
9208 : * Actually, though, that holds good only for dividend[] entries after
9209 : * dividend[qi]; the adjustment done at the bottom of the loop may cause
9210 : * dividend[qi + 1] to exceed the maxdiv limit, so that dividend[qi] in
9211 : * the next iteration is beyond the limit. This does not cause problems,
9212 : * as explained below.
9213 : */
9214 5442 : maxdiv = 1;
9215 :
9216 : /*
9217 : * Outer loop computes next quotient digit, which goes in dividend[qi].
9218 : */
9219 49542 : for (qi = 0; qi < res_ndigitpairs; qi++)
9220 : {
9221 : /* Approximate the current dividend value */
9222 44100 : fdividend = (double) dividend[qi] * NBASE_SQR;
9223 44100 : fdividend += (double) dividend[qi + 1];
9224 :
9225 : /* Compute the (approximate) quotient digit */
9226 44100 : fquotient = fdividend * fdivisorinverse;
9227 44100 : qdigit = (fquotient >= 0.0) ? ((int32) fquotient) :
9228 6 : (((int32) fquotient) - 1); /* truncate towards -infinity */
9229 :
9230 44100 : if (qdigit != 0)
9231 : {
9232 : /* Do we need to normalize now? */
9233 40506 : maxdiv += i64abs(qdigit);
9234 40506 : if (maxdiv > (PG_INT64_MAX - PG_INT64_MAX / NBASE_SQR - 1) / (NBASE_SQR - 1))
9235 : {
9236 : /*
9237 : * Yes, do it. Note that if var2ndigitpairs is much smaller
9238 : * than div_ndigitpairs, we can save a significant amount of
9239 : * effort here by noting that we only need to normalise those
9240 : * dividend[] entries touched where prior iterations
9241 : * subtracted multiples of the divisor.
9242 : */
9243 6 : carry = 0;
9244 6750 : for (i = Min(qi + var2ndigitpairs - 2, div_ndigitpairs - 1); i > qi; i--)
9245 : {
9246 6744 : newdig = dividend[i] + carry;
9247 6744 : if (newdig < 0)
9248 : {
9249 6744 : carry = -((-newdig - 1) / NBASE_SQR) - 1;
9250 6744 : newdig -= carry * NBASE_SQR;
9251 : }
9252 0 : else if (newdig >= NBASE_SQR)
9253 : {
9254 0 : carry = newdig / NBASE_SQR;
9255 0 : newdig -= carry * NBASE_SQR;
9256 : }
9257 : else
9258 0 : carry = 0;
9259 6744 : dividend[i] = newdig;
9260 : }
9261 6 : dividend[qi] += carry;
9262 :
9263 : /*
9264 : * All the dividend[] digits except possibly dividend[qi] are
9265 : * now in the range 0..NBASE^2-1. We do not need to consider
9266 : * dividend[qi] in the maxdiv value anymore, so we can reset
9267 : * maxdiv to 1.
9268 : */
9269 6 : maxdiv = 1;
9270 :
9271 : /*
9272 : * Recompute the quotient digit since new info may have
9273 : * propagated into the top two dividend digits.
9274 : */
9275 6 : fdividend = (double) dividend[qi] * NBASE_SQR;
9276 6 : fdividend += (double) dividend[qi + 1];
9277 6 : fquotient = fdividend * fdivisorinverse;
9278 6 : qdigit = (fquotient >= 0.0) ? ((int32) fquotient) :
9279 0 : (((int32) fquotient) - 1); /* truncate towards -infinity */
9280 :
9281 6 : maxdiv += i64abs(qdigit);
9282 : }
9283 :
9284 : /*
9285 : * Subtract off the appropriate multiple of the divisor.
9286 : *
9287 : * The digits beyond dividend[qi] cannot overflow, because we know
9288 : * they will fall within the maxdiv limit. As for dividend[qi]
9289 : * itself, note that qdigit is approximately trunc(dividend[qi] /
9290 : * divisor[0]), which would make the new value simply dividend[qi]
9291 : * mod divisor[0]. The lower-order terms in qdigit can change
9292 : * this result by not more than about twice PG_INT64_MAX/NBASE^2,
9293 : * so overflow is impossible.
9294 : *
9295 : * This inner loop is the performance bottleneck for division, so
9296 : * code it in the same way as the inner loop of mul_var() so that
9297 : * it can be auto-vectorized.
9298 : */
9299 40506 : if (qdigit != 0)
9300 : {
9301 40506 : int istop = Min(var2ndigitpairs, div_ndigitpairs - qi);
9302 40506 : int64 *dividend_qi = ÷nd[qi];
9303 :
9304 7861254 : for (i = 0; i < istop; i++)
9305 7820748 : dividend_qi[i] -= (int64) qdigit * divisor[i];
9306 : }
9307 : }
9308 :
9309 : /*
9310 : * The dividend digit we are about to replace might still be nonzero.
9311 : * Fold it into the next digit position.
9312 : *
9313 : * There is no risk of overflow here, although proving that requires
9314 : * some care. Much as with the argument for dividend[qi] not
9315 : * overflowing, if we consider the first two terms in the numerator
9316 : * and denominator of qdigit, we can see that the final value of
9317 : * dividend[qi + 1] will be approximately a remainder mod
9318 : * (divisor[0]*NBASE^2 + divisor[1]). Accounting for the lower-order
9319 : * terms is a bit complicated but ends up adding not much more than
9320 : * PG_INT64_MAX/NBASE^2 to the possible range. Thus, dividend[qi + 1]
9321 : * cannot overflow here, and in its role as dividend[qi] in the next
9322 : * loop iteration, it can't be large enough to cause overflow in the
9323 : * carry propagation step (if any), either.
9324 : *
9325 : * But having said that: dividend[qi] can be more than
9326 : * PG_INT64_MAX/NBASE^2, as noted above, which means that the product
9327 : * dividend[qi] * NBASE^2 *can* overflow. When that happens, adding
9328 : * it to dividend[qi + 1] will always cause a canceling overflow so
9329 : * that the end result is correct. We could avoid the intermediate
9330 : * overflow by doing the multiplication and addition using unsigned
9331 : * int64 arithmetic, which is modulo 2^64, but so far there appears no
9332 : * need.
9333 : */
9334 44100 : dividend[qi + 1] += dividend[qi] * NBASE_SQR;
9335 :
9336 44100 : dividend[qi] = qdigit;
9337 : }
9338 :
9339 : /*
9340 : * If an exact result was requested, use the remainder to correct the
9341 : * approximate quotient. The remainder is in dividend[], immediately
9342 : * after the quotient digits. Note, however, that although the remainder
9343 : * starts at dividend[qi = res_ndigitpairs], the first digit is the result
9344 : * of folding two remainder digits into one above, and the remainder
9345 : * currently only occupies var2ndigitpairs - 1 digits (the last digit of
9346 : * the working dividend was untouched by the computation above). Thus we
9347 : * expand the remainder down by one base-NBASE^2 digit when we normalize
9348 : * it, so that it completely fills the last var2ndigitpairs digits of the
9349 : * dividend array.
9350 : */
9351 5442 : if (exact)
9352 : {
9353 : /* Normalize the remainder, expanding it down by one digit */
9354 3720 : remainder = ÷nd[qi];
9355 3720 : carry = 0;
9356 20214 : for (i = var2ndigitpairs - 2; i >= 0; i--)
9357 : {
9358 16494 : newdig = remainder[i] + carry;
9359 16494 : if (newdig < 0)
9360 : {
9361 12732 : carry = -((-newdig - 1) / NBASE_SQR) - 1;
9362 12732 : newdig -= carry * NBASE_SQR;
9363 : }
9364 3762 : else if (newdig >= NBASE_SQR)
9365 : {
9366 3684 : carry = newdig / NBASE_SQR;
9367 3684 : newdig -= carry * NBASE_SQR;
9368 : }
9369 : else
9370 78 : carry = 0;
9371 16494 : remainder[i + 1] = newdig;
9372 : }
9373 3720 : remainder[0] = carry;
9374 :
9375 3720 : if (remainder[0] < 0)
9376 : {
9377 : /*
9378 : * The remainder is negative, so the approximate quotient is too
9379 : * large. Correct by reducing the quotient by one and adding the
9380 : * divisor to the remainder until the remainder is positive. We
9381 : * expect the quotient to be off by at most one, which has been
9382 : * borne out in all testing, but not conclusively proven, so we
9383 : * allow for larger corrections, just in case.
9384 : */
9385 : do
9386 : {
9387 : /* Add the divisor to the remainder */
9388 6 : carry = 0;
9389 78 : for (i = var2ndigitpairs - 1; i > 0; i--)
9390 : {
9391 72 : newdig = remainder[i] + divisor[i] + carry;
9392 72 : if (newdig >= NBASE_SQR)
9393 : {
9394 0 : remainder[i] = newdig - NBASE_SQR;
9395 0 : carry = 1;
9396 : }
9397 : else
9398 : {
9399 72 : remainder[i] = newdig;
9400 72 : carry = 0;
9401 : }
9402 : }
9403 6 : remainder[0] += divisor[0] + carry;
9404 :
9405 : /* Subtract 1 from the quotient (propagating carries later) */
9406 6 : dividend[qi - 1]--;
9407 :
9408 6 : } while (remainder[0] < 0);
9409 : }
9410 : else
9411 : {
9412 : /*
9413 : * The remainder is nonnegative. If it's greater than or equal to
9414 : * the divisor, then the approximate quotient is too small and
9415 : * must be corrected. As above, we don't expect to have to apply
9416 : * more than one correction, but allow for it just in case.
9417 : */
9418 : while (true)
9419 6 : {
9420 3720 : bool less = false;
9421 :
9422 : /* Is remainder < divisor? */
9423 3738 : for (i = 0; i < var2ndigitpairs; i++)
9424 : {
9425 3732 : if (remainder[i] < divisor[i])
9426 : {
9427 3714 : less = true;
9428 3714 : break;
9429 : }
9430 18 : if (remainder[i] > divisor[i])
9431 0 : break; /* remainder > divisor */
9432 : }
9433 3720 : if (less)
9434 3714 : break; /* quotient is correct */
9435 :
9436 : /* Subtract the divisor from the remainder */
9437 6 : carry = 0;
9438 18 : for (i = var2ndigitpairs - 1; i > 0; i--)
9439 : {
9440 12 : newdig = remainder[i] - divisor[i] + carry;
9441 12 : if (newdig < 0)
9442 : {
9443 0 : remainder[i] = newdig + NBASE_SQR;
9444 0 : carry = -1;
9445 : }
9446 : else
9447 : {
9448 12 : remainder[i] = newdig;
9449 12 : carry = 0;
9450 : }
9451 : }
9452 6 : remainder[0] = remainder[0] - divisor[0] + carry;
9453 :
9454 : /* Add 1 to the quotient (propagating carries later) */
9455 6 : dividend[qi - 1]++;
9456 : }
9457 : }
9458 : }
9459 :
9460 : /*
9461 : * Because the quotient digits were estimates that might have been off by
9462 : * one (and we didn't bother propagating carries when adjusting the
9463 : * quotient above), some quotient digits might be out of range, so do a
9464 : * final carry propagation pass to normalize back to base NBASE^2, and
9465 : * construct the base-NBASE result digits. Note that this is still done
9466 : * at full precision w/guard digits.
9467 : */
9468 5442 : alloc_var(result, res_ndigits);
9469 5442 : res_digits = result->digits;
9470 5442 : carry = 0;
9471 49542 : for (i = res_ndigitpairs - 1; i >= 0; i--)
9472 : {
9473 44100 : newdig = dividend[i] + carry;
9474 44100 : if (newdig < 0)
9475 : {
9476 6 : carry = -((-newdig - 1) / NBASE_SQR) - 1;
9477 6 : newdig -= carry * NBASE_SQR;
9478 : }
9479 44094 : else if (newdig >= NBASE_SQR)
9480 : {
9481 0 : carry = newdig / NBASE_SQR;
9482 0 : newdig -= carry * NBASE_SQR;
9483 : }
9484 : else
9485 44094 : carry = 0;
9486 44100 : res_digits[2 * i + 1] = (NumericDigit) ((uint32) newdig % NBASE);
9487 44100 : res_digits[2 * i] = (NumericDigit) ((uint32) newdig / NBASE);
9488 : }
9489 : Assert(carry == 0);
9490 :
9491 5442 : pfree(dividend);
9492 :
9493 : /*
9494 : * Finally, round or truncate the result to the requested precision.
9495 : */
9496 5442 : result->weight = res_weight;
9497 5442 : result->sign = res_sign;
9498 :
9499 : /* Round or truncate to target rscale (and set result->dscale) */
9500 5442 : if (round)
9501 906 : round_var(result, rscale);
9502 : else
9503 4536 : trunc_var(result, rscale);
9504 :
9505 : /* Strip leading and trailing zeroes */
9506 5442 : strip_var(result);
9507 : }
9508 :
9509 :
9510 : /*
9511 : * div_var_int() -
9512 : *
9513 : * Divide a numeric variable by a 32-bit integer with the specified weight.
9514 : * The quotient var / (ival * NBASE^ival_weight) is stored in result.
9515 : */
9516 : static void
9517 584278 : div_var_int(const NumericVar *var, int ival, int ival_weight,
9518 : NumericVar *result, int rscale, bool round)
9519 : {
9520 584278 : NumericDigit *var_digits = var->digits;
9521 584278 : int var_ndigits = var->ndigits;
9522 : int res_sign;
9523 : int res_weight;
9524 : int res_ndigits;
9525 : NumericDigit *res_buf;
9526 : NumericDigit *res_digits;
9527 : uint32 divisor;
9528 : int i;
9529 :
9530 : /* Guard against division by zero */
9531 584278 : if (ival == 0)
9532 0 : ereport(ERROR,
9533 : errcode(ERRCODE_DIVISION_BY_ZERO),
9534 : errmsg("division by zero"));
9535 :
9536 : /* Result zero check */
9537 584278 : if (var_ndigits == 0)
9538 : {
9539 2300 : zero_var(result);
9540 2300 : result->dscale = rscale;
9541 2300 : return;
9542 : }
9543 :
9544 : /*
9545 : * Determine the result sign, weight and number of digits to calculate.
9546 : * The weight figured here is correct if the emitted quotient has no
9547 : * leading zero digits; otherwise strip_var() will fix things up.
9548 : */
9549 581978 : if (var->sign == NUMERIC_POS)
9550 578990 : res_sign = ival > 0 ? NUMERIC_POS : NUMERIC_NEG;
9551 : else
9552 2988 : res_sign = ival > 0 ? NUMERIC_NEG : NUMERIC_POS;
9553 581978 : res_weight = var->weight - ival_weight;
9554 : /* The number of accurate result digits we need to produce: */
9555 581978 : res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
9556 : /* ... but always at least 1 */
9557 581978 : res_ndigits = Max(res_ndigits, 1);
9558 : /* If rounding needed, figure one more digit to ensure correct result */
9559 581978 : if (round)
9560 166686 : res_ndigits++;
9561 :
9562 581978 : res_buf = digitbuf_alloc(res_ndigits + 1);
9563 581978 : res_buf[0] = 0; /* spare digit for later rounding */
9564 581978 : res_digits = res_buf + 1;
9565 :
9566 : /*
9567 : * Now compute the quotient digits. This is the short division algorithm
9568 : * described in Knuth volume 2, section 4.3.1 exercise 16, except that we
9569 : * allow the divisor to exceed the internal base.
9570 : *
9571 : * In this algorithm, the carry from one digit to the next is at most
9572 : * divisor - 1. Therefore, while processing the next digit, carry may
9573 : * become as large as divisor * NBASE - 1, and so it requires a 64-bit
9574 : * integer if this exceeds UINT_MAX.
9575 : */
9576 581978 : divisor = abs(ival);
9577 :
9578 581978 : if (divisor <= UINT_MAX / NBASE)
9579 : {
9580 : /* carry cannot overflow 32 bits */
9581 578676 : uint32 carry = 0;
9582 :
9583 2844902 : for (i = 0; i < res_ndigits; i++)
9584 : {
9585 2266226 : carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
9586 2266226 : res_digits[i] = (NumericDigit) (carry / divisor);
9587 2266226 : carry = carry % divisor;
9588 : }
9589 : }
9590 : else
9591 : {
9592 : /* carry may exceed 32 bits */
9593 3302 : uint64 carry = 0;
9594 :
9595 10572 : for (i = 0; i < res_ndigits; i++)
9596 : {
9597 7270 : carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
9598 7270 : res_digits[i] = (NumericDigit) (carry / divisor);
9599 7270 : carry = carry % divisor;
9600 : }
9601 : }
9602 :
9603 : /* Store the quotient in result */
9604 581978 : digitbuf_free(result->buf);
9605 581978 : result->ndigits = res_ndigits;
9606 581978 : result->buf = res_buf;
9607 581978 : result->digits = res_digits;
9608 581978 : result->weight = res_weight;
9609 581978 : result->sign = res_sign;
9610 :
9611 : /* Round or truncate to target rscale (and set result->dscale) */
9612 581978 : if (round)
9613 166686 : round_var(result, rscale);
9614 : else
9615 415292 : trunc_var(result, rscale);
9616 :
9617 : /* Strip leading/trailing zeroes */
9618 581978 : strip_var(result);
9619 : }
9620 :
9621 :
9622 : #ifdef HAVE_INT128
9623 : /*
9624 : * div_var_int64() -
9625 : *
9626 : * Divide a numeric variable by a 64-bit integer with the specified weight.
9627 : * The quotient var / (ival * NBASE^ival_weight) is stored in result.
9628 : *
9629 : * This duplicates the logic in div_var_int(), so any changes made there
9630 : * should be made here too.
9631 : */
9632 : static void
9633 528 : div_var_int64(const NumericVar *var, int64 ival, int ival_weight,
9634 : NumericVar *result, int rscale, bool round)
9635 : {
9636 528 : NumericDigit *var_digits = var->digits;
9637 528 : int var_ndigits = var->ndigits;
9638 : int res_sign;
9639 : int res_weight;
9640 : int res_ndigits;
9641 : NumericDigit *res_buf;
9642 : NumericDigit *res_digits;
9643 : uint64 divisor;
9644 : int i;
9645 :
9646 : /* Guard against division by zero */
9647 528 : if (ival == 0)
9648 0 : ereport(ERROR,
9649 : errcode(ERRCODE_DIVISION_BY_ZERO),
9650 : errmsg("division by zero"));
9651 :
9652 : /* Result zero check */
9653 528 : if (var_ndigits == 0)
9654 : {
9655 96 : zero_var(result);
9656 96 : result->dscale = rscale;
9657 96 : return;
9658 : }
9659 :
9660 : /*
9661 : * Determine the result sign, weight and number of digits to calculate.
9662 : * The weight figured here is correct if the emitted quotient has no
9663 : * leading zero digits; otherwise strip_var() will fix things up.
9664 : */
9665 432 : if (var->sign == NUMERIC_POS)
9666 258 : res_sign = ival > 0 ? NUMERIC_POS : NUMERIC_NEG;
9667 : else
9668 174 : res_sign = ival > 0 ? NUMERIC_NEG : NUMERIC_POS;
9669 432 : res_weight = var->weight - ival_weight;
9670 : /* The number of accurate result digits we need to produce: */
9671 432 : res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
9672 : /* ... but always at least 1 */
9673 432 : res_ndigits = Max(res_ndigits, 1);
9674 : /* If rounding needed, figure one more digit to ensure correct result */
9675 432 : if (round)
9676 426 : res_ndigits++;
9677 :
9678 432 : res_buf = digitbuf_alloc(res_ndigits + 1);
9679 432 : res_buf[0] = 0; /* spare digit for later rounding */
9680 432 : res_digits = res_buf + 1;
9681 :
9682 : /*
9683 : * Now compute the quotient digits. This is the short division algorithm
9684 : * described in Knuth volume 2, section 4.3.1 exercise 16, except that we
9685 : * allow the divisor to exceed the internal base.
9686 : *
9687 : * In this algorithm, the carry from one digit to the next is at most
9688 : * divisor - 1. Therefore, while processing the next digit, carry may
9689 : * become as large as divisor * NBASE - 1, and so it requires a 128-bit
9690 : * integer if this exceeds PG_UINT64_MAX.
9691 : */
9692 432 : divisor = i64abs(ival);
9693 :
9694 432 : if (divisor <= PG_UINT64_MAX / NBASE)
9695 : {
9696 : /* carry cannot overflow 64 bits */
9697 336 : uint64 carry = 0;
9698 :
9699 3414 : for (i = 0; i < res_ndigits; i++)
9700 : {
9701 3078 : carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
9702 3078 : res_digits[i] = (NumericDigit) (carry / divisor);
9703 3078 : carry = carry % divisor;
9704 : }
9705 : }
9706 : else
9707 : {
9708 : /* carry may exceed 64 bits */
9709 96 : uint128 carry = 0;
9710 :
9711 1032 : for (i = 0; i < res_ndigits; i++)
9712 : {
9713 936 : carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
9714 936 : res_digits[i] = (NumericDigit) (carry / divisor);
9715 936 : carry = carry % divisor;
9716 : }
9717 : }
9718 :
9719 : /* Store the quotient in result */
9720 432 : digitbuf_free(result->buf);
9721 432 : result->ndigits = res_ndigits;
9722 432 : result->buf = res_buf;
9723 432 : result->digits = res_digits;
9724 432 : result->weight = res_weight;
9725 432 : result->sign = res_sign;
9726 :
9727 : /* Round or truncate to target rscale (and set result->dscale) */
9728 432 : if (round)
9729 426 : round_var(result, rscale);
9730 : else
9731 6 : trunc_var(result, rscale);
9732 :
9733 : /* Strip leading/trailing zeroes */
9734 432 : strip_var(result);
9735 : }
9736 : #endif
9737 :
9738 :
9739 : /*
9740 : * Default scale selection for division
9741 : *
9742 : * Returns the appropriate result scale for the division result.
9743 : */
9744 : static int
9745 149620 : select_div_scale(const NumericVar *var1, const NumericVar *var2)
9746 : {
9747 : int weight1,
9748 : weight2,
9749 : qweight,
9750 : i;
9751 : NumericDigit firstdigit1,
9752 : firstdigit2;
9753 : int rscale;
9754 :
9755 : /*
9756 : * The result scale of a division isn't specified in any SQL standard. For
9757 : * PostgreSQL we select a result scale that will give at least
9758 : * NUMERIC_MIN_SIG_DIGITS significant digits, so that numeric gives a
9759 : * result no less accurate than float8; but use a scale not less than
9760 : * either input's display scale.
9761 : */
9762 :
9763 : /* Get the actual (normalized) weight and first digit of each input */
9764 :
9765 149620 : weight1 = 0; /* values to use if var1 is zero */
9766 149620 : firstdigit1 = 0;
9767 149620 : for (i = 0; i < var1->ndigits; i++)
9768 : {
9769 147920 : firstdigit1 = var1->digits[i];
9770 147920 : if (firstdigit1 != 0)
9771 : {
9772 147920 : weight1 = var1->weight - i;
9773 147920 : break;
9774 : }
9775 : }
9776 :
9777 149620 : weight2 = 0; /* values to use if var2 is zero */
9778 149620 : firstdigit2 = 0;
9779 149620 : for (i = 0; i < var2->ndigits; i++)
9780 : {
9781 149570 : firstdigit2 = var2->digits[i];
9782 149570 : if (firstdigit2 != 0)
9783 : {
9784 149570 : weight2 = var2->weight - i;
9785 149570 : break;
9786 : }
9787 : }
9788 :
9789 : /*
9790 : * Estimate weight of quotient. If the two first digits are equal, we
9791 : * can't be sure, but assume that var1 is less than var2.
9792 : */
9793 149620 : qweight = weight1 - weight2;
9794 149620 : if (firstdigit1 <= firstdigit2)
9795 132784 : qweight--;
9796 :
9797 : /* Select result scale */
9798 149620 : rscale = NUMERIC_MIN_SIG_DIGITS - qweight * DEC_DIGITS;
9799 149620 : rscale = Max(rscale, var1->dscale);
9800 149620 : rscale = Max(rscale, var2->dscale);
9801 149620 : rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
9802 149620 : rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
9803 :
9804 149620 : return rscale;
9805 : }
9806 :
9807 :
9808 : /*
9809 : * mod_var() -
9810 : *
9811 : * Calculate the modulo of two numerics at variable level
9812 : */
9813 : static void
9814 413768 : mod_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
9815 : {
9816 : NumericVar tmp;
9817 :
9818 413768 : init_var(&tmp);
9819 :
9820 : /* ---------
9821 : * We do this using the equation
9822 : * mod(x,y) = x - trunc(x/y)*y
9823 : * div_var can be persuaded to give us trunc(x/y) directly.
9824 : * ----------
9825 : */
9826 413768 : div_var(var1, var2, &tmp, 0, false, true);
9827 :
9828 413756 : mul_var(var2, &tmp, &tmp, var2->dscale);
9829 :
9830 413756 : sub_var(var1, &tmp, result);
9831 :
9832 413756 : free_var(&tmp);
9833 413756 : }
9834 :
9835 :
9836 : /*
9837 : * div_mod_var() -
9838 : *
9839 : * Calculate the truncated integer quotient and numeric remainder of two
9840 : * numeric variables. The remainder is precise to var2's dscale.
9841 : */
9842 : static void
9843 4518 : div_mod_var(const NumericVar *var1, const NumericVar *var2,
9844 : NumericVar *quot, NumericVar *rem)
9845 : {
9846 : NumericVar q;
9847 : NumericVar r;
9848 :
9849 4518 : init_var(&q);
9850 4518 : init_var(&r);
9851 :
9852 : /*
9853 : * Use div_var() with exact = false to get an initial estimate for the
9854 : * integer quotient (truncated towards zero). This might be slightly
9855 : * inaccurate, but we correct it below.
9856 : */
9857 4518 : div_var(var1, var2, &q, 0, false, false);
9858 :
9859 : /* Compute initial estimate of remainder using the quotient estimate. */
9860 4518 : mul_var(var2, &q, &r, var2->dscale);
9861 4518 : sub_var(var1, &r, &r);
9862 :
9863 : /*
9864 : * Adjust the results if necessary --- the remainder should have the same
9865 : * sign as var1, and its absolute value should be less than the absolute
9866 : * value of var2.
9867 : */
9868 4518 : while (r.ndigits != 0 && r.sign != var1->sign)
9869 : {
9870 : /* The absolute value of the quotient is too large */
9871 0 : if (var1->sign == var2->sign)
9872 : {
9873 0 : sub_var(&q, &const_one, &q);
9874 0 : add_var(&r, var2, &r);
9875 : }
9876 : else
9877 : {
9878 0 : add_var(&q, &const_one, &q);
9879 0 : sub_var(&r, var2, &r);
9880 : }
9881 : }
9882 :
9883 4518 : while (cmp_abs(&r, var2) >= 0)
9884 : {
9885 : /* The absolute value of the quotient is too small */
9886 0 : if (var1->sign == var2->sign)
9887 : {
9888 0 : add_var(&q, &const_one, &q);
9889 0 : sub_var(&r, var2, &r);
9890 : }
9891 : else
9892 : {
9893 0 : sub_var(&q, &const_one, &q);
9894 0 : add_var(&r, var2, &r);
9895 : }
9896 : }
9897 :
9898 4518 : set_var_from_var(&q, quot);
9899 4518 : set_var_from_var(&r, rem);
9900 :
9901 4518 : free_var(&q);
9902 4518 : free_var(&r);
9903 4518 : }
9904 :
9905 :
9906 : /*
9907 : * ceil_var() -
9908 : *
9909 : * Return the smallest integer greater than or equal to the argument
9910 : * on variable level
9911 : */
9912 : static void
9913 204 : ceil_var(const NumericVar *var, NumericVar *result)
9914 : {
9915 : NumericVar tmp;
9916 :
9917 204 : init_var(&tmp);
9918 204 : set_var_from_var(var, &tmp);
9919 :
9920 204 : trunc_var(&tmp, 0);
9921 :
9922 204 : if (var->sign == NUMERIC_POS && cmp_var(var, &tmp) != 0)
9923 60 : add_var(&tmp, &const_one, &tmp);
9924 :
9925 204 : set_var_from_var(&tmp, result);
9926 204 : free_var(&tmp);
9927 204 : }
9928 :
9929 :
9930 : /*
9931 : * floor_var() -
9932 : *
9933 : * Return the largest integer equal to or less than the argument
9934 : * on variable level
9935 : */
9936 : static void
9937 108 : floor_var(const NumericVar *var, NumericVar *result)
9938 : {
9939 : NumericVar tmp;
9940 :
9941 108 : init_var(&tmp);
9942 108 : set_var_from_var(var, &tmp);
9943 :
9944 108 : trunc_var(&tmp, 0);
9945 :
9946 108 : if (var->sign == NUMERIC_NEG && cmp_var(var, &tmp) != 0)
9947 30 : sub_var(&tmp, &const_one, &tmp);
9948 :
9949 108 : set_var_from_var(&tmp, result);
9950 108 : free_var(&tmp);
9951 108 : }
9952 :
9953 :
9954 : /*
9955 : * gcd_var() -
9956 : *
9957 : * Calculate the greatest common divisor of two numerics at variable level
9958 : */
9959 : static void
9960 222 : gcd_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
9961 : {
9962 : int res_dscale;
9963 : int cmp;
9964 : NumericVar tmp_arg;
9965 : NumericVar mod;
9966 :
9967 222 : res_dscale = Max(var1->dscale, var2->dscale);
9968 :
9969 : /*
9970 : * Arrange for var1 to be the number with the greater absolute value.
9971 : *
9972 : * This would happen automatically in the loop below, but avoids an
9973 : * expensive modulo operation.
9974 : */
9975 222 : cmp = cmp_abs(var1, var2);
9976 222 : if (cmp < 0)
9977 : {
9978 84 : const NumericVar *tmp = var1;
9979 :
9980 84 : var1 = var2;
9981 84 : var2 = tmp;
9982 : }
9983 :
9984 : /*
9985 : * Also avoid the taking the modulo if the inputs have the same absolute
9986 : * value, or if the smaller input is zero.
9987 : */
9988 222 : if (cmp == 0 || var2->ndigits == 0)
9989 : {
9990 72 : set_var_from_var(var1, result);
9991 72 : result->sign = NUMERIC_POS;
9992 72 : result->dscale = res_dscale;
9993 72 : return;
9994 : }
9995 :
9996 150 : init_var(&tmp_arg);
9997 150 : init_var(&mod);
9998 :
9999 : /* Use the Euclidean algorithm to find the GCD */
10000 150 : set_var_from_var(var1, &tmp_arg);
10001 150 : set_var_from_var(var2, result);
10002 :
10003 : for (;;)
10004 : {
10005 : /* this loop can take a while, so allow it to be interrupted */
10006 588 : CHECK_FOR_INTERRUPTS();
10007 :
10008 588 : mod_var(&tmp_arg, result, &mod);
10009 588 : if (mod.ndigits == 0)
10010 150 : break;
10011 438 : set_var_from_var(result, &tmp_arg);
10012 438 : set_var_from_var(&mod, result);
10013 : }
10014 150 : result->sign = NUMERIC_POS;
10015 150 : result->dscale = res_dscale;
10016 :
10017 150 : free_var(&tmp_arg);
10018 150 : free_var(&mod);
10019 : }
10020 :
10021 :
10022 : /*
10023 : * sqrt_var() -
10024 : *
10025 : * Compute the square root of x using the Karatsuba Square Root algorithm.
10026 : * NOTE: we allow rscale < 0 here, implying rounding before the decimal
10027 : * point.
10028 : */
10029 : static void
10030 4194 : sqrt_var(const NumericVar *arg, NumericVar *result, int rscale)
10031 : {
10032 : int stat;
10033 : int res_weight;
10034 : int res_ndigits;
10035 : int src_ndigits;
10036 : int step;
10037 : int ndigits[32];
10038 : int blen;
10039 : int64 arg_int64;
10040 : int src_idx;
10041 : int64 s_int64;
10042 : int64 r_int64;
10043 : NumericVar s_var;
10044 : NumericVar r_var;
10045 : NumericVar a0_var;
10046 : NumericVar a1_var;
10047 : NumericVar q_var;
10048 : NumericVar u_var;
10049 :
10050 4194 : stat = cmp_var(arg, &const_zero);
10051 4194 : if (stat == 0)
10052 : {
10053 18 : zero_var(result);
10054 18 : result->dscale = rscale;
10055 18 : return;
10056 : }
10057 :
10058 : /*
10059 : * SQL2003 defines sqrt() in terms of power, so we need to emit the right
10060 : * SQLSTATE error code if the operand is negative.
10061 : */
10062 4176 : if (stat < 0)
10063 6 : ereport(ERROR,
10064 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
10065 : errmsg("cannot take square root of a negative number")));
10066 :
10067 4170 : init_var(&s_var);
10068 4170 : init_var(&r_var);
10069 4170 : init_var(&a0_var);
10070 4170 : init_var(&a1_var);
10071 4170 : init_var(&q_var);
10072 4170 : init_var(&u_var);
10073 :
10074 : /*
10075 : * The result weight is half the input weight, rounded towards minus
10076 : * infinity --- res_weight = floor(arg->weight / 2).
10077 : */
10078 4170 : if (arg->weight >= 0)
10079 3858 : res_weight = arg->weight / 2;
10080 : else
10081 312 : res_weight = -((-arg->weight - 1) / 2 + 1);
10082 :
10083 : /*
10084 : * Number of NBASE digits to compute. To ensure correct rounding, compute
10085 : * at least 1 extra decimal digit. We explicitly allow rscale to be
10086 : * negative here, but must always compute at least 1 NBASE digit. Thus
10087 : * res_ndigits = res_weight + 1 + ceil((rscale + 1) / DEC_DIGITS) or 1.
10088 : */
10089 4170 : if (rscale + 1 >= 0)
10090 4170 : res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS) / DEC_DIGITS;
10091 : else
10092 0 : res_ndigits = res_weight + 1 - (-rscale - 1) / DEC_DIGITS;
10093 4170 : res_ndigits = Max(res_ndigits, 1);
10094 :
10095 : /*
10096 : * Number of source NBASE digits logically required to produce a result
10097 : * with this precision --- every digit before the decimal point, plus 2
10098 : * for each result digit after the decimal point (or minus 2 for each
10099 : * result digit we round before the decimal point).
10100 : */
10101 4170 : src_ndigits = arg->weight + 1 + (res_ndigits - res_weight - 1) * 2;
10102 4170 : src_ndigits = Max(src_ndigits, 1);
10103 :
10104 : /* ----------
10105 : * From this point on, we treat the input and the result as integers and
10106 : * compute the integer square root and remainder using the Karatsuba
10107 : * Square Root algorithm, which may be written recursively as follows:
10108 : *
10109 : * SqrtRem(n = a3*b^3 + a2*b^2 + a1*b + a0):
10110 : * [ for some base b, and coefficients a0,a1,a2,a3 chosen so that
10111 : * 0 <= a0,a1,a2 < b and a3 >= b/4 ]
10112 : * Let (s,r) = SqrtRem(a3*b + a2)
10113 : * Let (q,u) = DivRem(r*b + a1, 2*s)
10114 : * Let s = s*b + q
10115 : * Let r = u*b + a0 - q^2
10116 : * If r < 0 Then
10117 : * Let r = r + s
10118 : * Let s = s - 1
10119 : * Let r = r + s
10120 : * Return (s,r)
10121 : *
10122 : * See "Karatsuba Square Root", Paul Zimmermann, INRIA Research Report
10123 : * RR-3805, November 1999. At the time of writing this was available
10124 : * on the net at <https://hal.inria.fr/inria-00072854>.
10125 : *
10126 : * The way to read the assumption "n = a3*b^3 + a2*b^2 + a1*b + a0" is
10127 : * "choose a base b such that n requires at least four base-b digits to
10128 : * express; then those digits are a3,a2,a1,a0, with a3 possibly larger
10129 : * than b". For optimal performance, b should have approximately a
10130 : * quarter the number of digits in the input, so that the outer square
10131 : * root computes roughly twice as many digits as the inner one. For
10132 : * simplicity, we choose b = NBASE^blen, an integer power of NBASE.
10133 : *
10134 : * We implement the algorithm iteratively rather than recursively, to
10135 : * allow the working variables to be reused. With this approach, each
10136 : * digit of the input is read precisely once --- src_idx tracks the number
10137 : * of input digits used so far.
10138 : *
10139 : * The array ndigits[] holds the number of NBASE digits of the input that
10140 : * will have been used at the end of each iteration, which roughly doubles
10141 : * each time. Note that the array elements are stored in reverse order,
10142 : * so if the final iteration requires src_ndigits = 37 input digits, the
10143 : * array will contain [37,19,11,7,5,3], and we would start by computing
10144 : * the square root of the 3 most significant NBASE digits.
10145 : *
10146 : * In each iteration, we choose blen to be the largest integer for which
10147 : * the input number has a3 >= b/4, when written in the form above. In
10148 : * general, this means blen = src_ndigits / 4 (truncated), but if
10149 : * src_ndigits is a multiple of 4, that might lead to the coefficient a3
10150 : * being less than b/4 (if the first input digit is less than NBASE/4), in
10151 : * which case we choose blen = src_ndigits / 4 - 1. The number of digits
10152 : * in the inner square root is then src_ndigits - 2*blen. So, for
10153 : * example, if we have src_ndigits = 26 initially, the array ndigits[]
10154 : * will be either [26,14,8,4] or [26,14,8,6,4], depending on the size of
10155 : * the first input digit.
10156 : *
10157 : * Additionally, we can put an upper bound on the number of steps required
10158 : * as follows --- suppose that the number of source digits is an n-bit
10159 : * number in the range [2^(n-1), 2^n-1], then blen will be in the range
10160 : * [2^(n-3)-1, 2^(n-2)-1] and the number of digits in the inner square
10161 : * root will be in the range [2^(n-2), 2^(n-1)+1]. In the next step, blen
10162 : * will be in the range [2^(n-4)-1, 2^(n-3)] and the number of digits in
10163 : * the next inner square root will be in the range [2^(n-3), 2^(n-2)+1].
10164 : * This pattern repeats, and in the worst case the array ndigits[] will
10165 : * contain [2^n-1, 2^(n-1)+1, 2^(n-2)+1, ... 9, 5, 3], and the computation
10166 : * will require n steps. Therefore, since all digit array sizes are
10167 : * signed 32-bit integers, the number of steps required is guaranteed to
10168 : * be less than 32.
10169 : * ----------
10170 : */
10171 4170 : step = 0;
10172 19962 : while ((ndigits[step] = src_ndigits) > 4)
10173 : {
10174 : /* Choose b so that a3 >= b/4, as described above */
10175 15792 : blen = src_ndigits / 4;
10176 15792 : if (blen * 4 == src_ndigits && arg->digits[0] < NBASE / 4)
10177 324 : blen--;
10178 :
10179 : /* Number of digits in the next step (inner square root) */
10180 15792 : src_ndigits -= 2 * blen;
10181 15792 : step++;
10182 : }
10183 :
10184 : /*
10185 : * First iteration (innermost square root and remainder):
10186 : *
10187 : * Here src_ndigits <= 4, and the input fits in an int64. Its square root
10188 : * has at most 9 decimal digits, so estimate it using double precision
10189 : * arithmetic, which will in fact almost certainly return the correct
10190 : * result with no further correction required.
10191 : */
10192 4170 : arg_int64 = arg->digits[0];
10193 13314 : for (src_idx = 1; src_idx < src_ndigits; src_idx++)
10194 : {
10195 9144 : arg_int64 *= NBASE;
10196 9144 : if (src_idx < arg->ndigits)
10197 7686 : arg_int64 += arg->digits[src_idx];
10198 : }
10199 :
10200 4170 : s_int64 = (int64) sqrt((double) arg_int64);
10201 4170 : r_int64 = arg_int64 - s_int64 * s_int64;
10202 :
10203 : /*
10204 : * Use Newton's method to correct the result, if necessary.
10205 : *
10206 : * This uses integer division with truncation to compute the truncated
10207 : * integer square root by iterating using the formula x -> (x + n/x) / 2.
10208 : * This is known to converge to isqrt(n), unless n+1 is a perfect square.
10209 : * If n+1 is a perfect square, the sequence will oscillate between the two
10210 : * values isqrt(n) and isqrt(n)+1, so we can be assured of convergence by
10211 : * checking the remainder.
10212 : */
10213 4170 : while (r_int64 < 0 || r_int64 > 2 * s_int64)
10214 : {
10215 0 : s_int64 = (s_int64 + arg_int64 / s_int64) / 2;
10216 0 : r_int64 = arg_int64 - s_int64 * s_int64;
10217 : }
10218 :
10219 : /*
10220 : * Iterations with src_ndigits <= 8:
10221 : *
10222 : * The next 1 or 2 iterations compute larger (outer) square roots with
10223 : * src_ndigits <= 8, so the result still fits in an int64 (even though the
10224 : * input no longer does) and we can continue to compute using int64
10225 : * variables to avoid more expensive numeric computations.
10226 : *
10227 : * It is fairly easy to see that there is no risk of the intermediate
10228 : * values below overflowing 64-bit integers. In the worst case, the
10229 : * previous iteration will have computed a 3-digit square root (of a
10230 : * 6-digit input less than NBASE^6 / 4), so at the start of this
10231 : * iteration, s will be less than NBASE^3 / 2 = 10^12 / 2, and r will be
10232 : * less than 10^12. In this case, blen will be 1, so numer will be less
10233 : * than 10^17, and denom will be less than 10^12 (and hence u will also be
10234 : * less than 10^12). Finally, since q^2 = u*b + a0 - r, we can also be
10235 : * sure that q^2 < 10^17. Therefore all these quantities fit comfortably
10236 : * in 64-bit integers.
10237 : */
10238 4170 : step--;
10239 10566 : while (step >= 0 && (src_ndigits = ndigits[step]) <= 8)
10240 : {
10241 : int b;
10242 : int a0;
10243 : int a1;
10244 : int i;
10245 : int64 numer;
10246 : int64 denom;
10247 : int64 q;
10248 : int64 u;
10249 :
10250 6396 : blen = (src_ndigits - src_idx) / 2;
10251 :
10252 : /* Extract a1 and a0, and compute b */
10253 6396 : a0 = 0;
10254 6396 : a1 = 0;
10255 6396 : b = 1;
10256 :
10257 12936 : for (i = 0; i < blen; i++, src_idx++)
10258 : {
10259 6540 : b *= NBASE;
10260 6540 : a1 *= NBASE;
10261 6540 : if (src_idx < arg->ndigits)
10262 4800 : a1 += arg->digits[src_idx];
10263 : }
10264 :
10265 12936 : for (i = 0; i < blen; i++, src_idx++)
10266 : {
10267 6540 : a0 *= NBASE;
10268 6540 : if (src_idx < arg->ndigits)
10269 4644 : a0 += arg->digits[src_idx];
10270 : }
10271 :
10272 : /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
10273 6396 : numer = r_int64 * b + a1;
10274 6396 : denom = 2 * s_int64;
10275 6396 : q = numer / denom;
10276 6396 : u = numer - q * denom;
10277 :
10278 : /* Compute s = s*b + q and r = u*b + a0 - q^2 */
10279 6396 : s_int64 = s_int64 * b + q;
10280 6396 : r_int64 = u * b + a0 - q * q;
10281 :
10282 6396 : if (r_int64 < 0)
10283 : {
10284 : /* s is too large by 1; set r += s, s--, r += s */
10285 210 : r_int64 += s_int64;
10286 210 : s_int64--;
10287 210 : r_int64 += s_int64;
10288 : }
10289 :
10290 : Assert(src_idx == src_ndigits); /* All input digits consumed */
10291 6396 : step--;
10292 : }
10293 :
10294 : /*
10295 : * On platforms with 128-bit integer support, we can further delay the
10296 : * need to use numeric variables.
10297 : */
10298 : #ifdef HAVE_INT128
10299 4170 : if (step >= 0)
10300 : {
10301 : int128 s_int128;
10302 : int128 r_int128;
10303 :
10304 4170 : s_int128 = s_int64;
10305 4170 : r_int128 = r_int64;
10306 :
10307 : /*
10308 : * Iterations with src_ndigits <= 16:
10309 : *
10310 : * The result fits in an int128 (even though the input doesn't) so we
10311 : * use int128 variables to avoid more expensive numeric computations.
10312 : */
10313 9048 : while (step >= 0 && (src_ndigits = ndigits[step]) <= 16)
10314 : {
10315 : int64 b;
10316 : int64 a0;
10317 : int64 a1;
10318 : int64 i;
10319 : int128 numer;
10320 : int128 denom;
10321 : int128 q;
10322 : int128 u;
10323 :
10324 4878 : blen = (src_ndigits - src_idx) / 2;
10325 :
10326 : /* Extract a1 and a0, and compute b */
10327 4878 : a0 = 0;
10328 4878 : a1 = 0;
10329 4878 : b = 1;
10330 :
10331 16080 : for (i = 0; i < blen; i++, src_idx++)
10332 : {
10333 11202 : b *= NBASE;
10334 11202 : a1 *= NBASE;
10335 11202 : if (src_idx < arg->ndigits)
10336 6606 : a1 += arg->digits[src_idx];
10337 : }
10338 :
10339 16080 : for (i = 0; i < blen; i++, src_idx++)
10340 : {
10341 11202 : a0 *= NBASE;
10342 11202 : if (src_idx < arg->ndigits)
10343 4470 : a0 += arg->digits[src_idx];
10344 : }
10345 :
10346 : /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
10347 4878 : numer = r_int128 * b + a1;
10348 4878 : denom = 2 * s_int128;
10349 4878 : q = numer / denom;
10350 4878 : u = numer - q * denom;
10351 :
10352 : /* Compute s = s*b + q and r = u*b + a0 - q^2 */
10353 4878 : s_int128 = s_int128 * b + q;
10354 4878 : r_int128 = u * b + a0 - q * q;
10355 :
10356 4878 : if (r_int128 < 0)
10357 : {
10358 : /* s is too large by 1; set r += s, s--, r += s */
10359 192 : r_int128 += s_int128;
10360 192 : s_int128--;
10361 192 : r_int128 += s_int128;
10362 : }
10363 :
10364 : Assert(src_idx == src_ndigits); /* All input digits consumed */
10365 4878 : step--;
10366 : }
10367 :
10368 : /*
10369 : * All remaining iterations require numeric variables. Convert the
10370 : * integer values to NumericVar and continue. Note that in the final
10371 : * iteration we don't need the remainder, so we can save a few cycles
10372 : * there by not fully computing it.
10373 : */
10374 4170 : int128_to_numericvar(s_int128, &s_var);
10375 4170 : if (step >= 0)
10376 2724 : int128_to_numericvar(r_int128, &r_var);
10377 : }
10378 : else
10379 : {
10380 0 : int64_to_numericvar(s_int64, &s_var);
10381 : /* step < 0, so we certainly don't need r */
10382 : }
10383 : #else /* !HAVE_INT128 */
10384 : int64_to_numericvar(s_int64, &s_var);
10385 : if (step >= 0)
10386 : int64_to_numericvar(r_int64, &r_var);
10387 : #endif /* HAVE_INT128 */
10388 :
10389 : /*
10390 : * The remaining iterations with src_ndigits > 8 (or 16, if have int128)
10391 : * use numeric variables.
10392 : */
10393 8688 : while (step >= 0)
10394 : {
10395 : int tmp_len;
10396 :
10397 4518 : src_ndigits = ndigits[step];
10398 4518 : blen = (src_ndigits - src_idx) / 2;
10399 :
10400 : /* Extract a1 and a0 */
10401 4518 : if (src_idx < arg->ndigits)
10402 : {
10403 1512 : tmp_len = Min(blen, arg->ndigits - src_idx);
10404 1512 : alloc_var(&a1_var, tmp_len);
10405 1512 : memcpy(a1_var.digits, arg->digits + src_idx,
10406 : tmp_len * sizeof(NumericDigit));
10407 1512 : a1_var.weight = blen - 1;
10408 1512 : a1_var.sign = NUMERIC_POS;
10409 1512 : a1_var.dscale = 0;
10410 1512 : strip_var(&a1_var);
10411 : }
10412 : else
10413 : {
10414 3006 : zero_var(&a1_var);
10415 3006 : a1_var.dscale = 0;
10416 : }
10417 4518 : src_idx += blen;
10418 :
10419 4518 : if (src_idx < arg->ndigits)
10420 : {
10421 1512 : tmp_len = Min(blen, arg->ndigits - src_idx);
10422 1512 : alloc_var(&a0_var, tmp_len);
10423 1512 : memcpy(a0_var.digits, arg->digits + src_idx,
10424 : tmp_len * sizeof(NumericDigit));
10425 1512 : a0_var.weight = blen - 1;
10426 1512 : a0_var.sign = NUMERIC_POS;
10427 1512 : a0_var.dscale = 0;
10428 1512 : strip_var(&a0_var);
10429 : }
10430 : else
10431 : {
10432 3006 : zero_var(&a0_var);
10433 3006 : a0_var.dscale = 0;
10434 : }
10435 4518 : src_idx += blen;
10436 :
10437 : /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
10438 4518 : set_var_from_var(&r_var, &q_var);
10439 4518 : q_var.weight += blen;
10440 4518 : add_var(&q_var, &a1_var, &q_var);
10441 4518 : add_var(&s_var, &s_var, &u_var);
10442 4518 : div_mod_var(&q_var, &u_var, &q_var, &u_var);
10443 :
10444 : /* Compute s = s*b + q */
10445 4518 : s_var.weight += blen;
10446 4518 : add_var(&s_var, &q_var, &s_var);
10447 :
10448 : /*
10449 : * Compute r = u*b + a0 - q^2.
10450 : *
10451 : * In the final iteration, we don't actually need r; we just need to
10452 : * know whether it is negative, so that we know whether to adjust s.
10453 : * So instead of the final subtraction we can just compare.
10454 : */
10455 4518 : u_var.weight += blen;
10456 4518 : add_var(&u_var, &a0_var, &u_var);
10457 4518 : mul_var(&q_var, &q_var, &q_var, 0);
10458 :
10459 4518 : if (step > 0)
10460 : {
10461 : /* Need r for later iterations */
10462 1794 : sub_var(&u_var, &q_var, &r_var);
10463 1794 : if (r_var.sign == NUMERIC_NEG)
10464 : {
10465 : /* s is too large by 1; set r += s, s--, r += s */
10466 120 : add_var(&r_var, &s_var, &r_var);
10467 120 : sub_var(&s_var, &const_one, &s_var);
10468 120 : add_var(&r_var, &s_var, &r_var);
10469 : }
10470 : }
10471 : else
10472 : {
10473 : /* Don't need r anymore, except to test if s is too large by 1 */
10474 2724 : if (cmp_var(&u_var, &q_var) < 0)
10475 36 : sub_var(&s_var, &const_one, &s_var);
10476 : }
10477 :
10478 : Assert(src_idx == src_ndigits); /* All input digits consumed */
10479 4518 : step--;
10480 : }
10481 :
10482 : /*
10483 : * Construct the final result, rounding it to the requested precision.
10484 : */
10485 4170 : set_var_from_var(&s_var, result);
10486 4170 : result->weight = res_weight;
10487 4170 : result->sign = NUMERIC_POS;
10488 :
10489 : /* Round to target rscale (and set result->dscale) */
10490 4170 : round_var(result, rscale);
10491 :
10492 : /* Strip leading and trailing zeroes */
10493 4170 : strip_var(result);
10494 :
10495 4170 : free_var(&s_var);
10496 4170 : free_var(&r_var);
10497 4170 : free_var(&a0_var);
10498 4170 : free_var(&a1_var);
10499 4170 : free_var(&q_var);
10500 4170 : free_var(&u_var);
10501 : }
10502 :
10503 :
10504 : /*
10505 : * exp_var() -
10506 : *
10507 : * Raise e to the power of x, computed to rscale fractional digits
10508 : */
10509 : static void
10510 180 : exp_var(const NumericVar *arg, NumericVar *result, int rscale)
10511 : {
10512 : NumericVar x;
10513 : NumericVar elem;
10514 : int ni;
10515 : double val;
10516 : int dweight;
10517 : int ndiv2;
10518 : int sig_digits;
10519 : int local_rscale;
10520 :
10521 180 : init_var(&x);
10522 180 : init_var(&elem);
10523 :
10524 180 : set_var_from_var(arg, &x);
10525 :
10526 : /*
10527 : * Estimate the dweight of the result using floating point arithmetic, so
10528 : * that we can choose an appropriate local rscale for the calculation.
10529 : */
10530 180 : val = numericvar_to_double_no_overflow(&x);
10531 :
10532 : /* Guard against overflow/underflow */
10533 : /* If you change this limit, see also power_var()'s limit */
10534 180 : if (fabs(val) >= NUMERIC_MAX_RESULT_SCALE * 3)
10535 : {
10536 6 : if (val > 0)
10537 0 : ereport(ERROR,
10538 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
10539 : errmsg("value overflows numeric format")));
10540 6 : zero_var(result);
10541 6 : result->dscale = rscale;
10542 6 : return;
10543 : }
10544 :
10545 : /* decimal weight = log10(e^x) = x * log10(e) */
10546 174 : dweight = (int) (val * 0.434294481903252);
10547 :
10548 : /*
10549 : * Reduce x to the range -0.01 <= x <= 0.01 (approximately) by dividing by
10550 : * 2^ndiv2, to improve the convergence rate of the Taylor series.
10551 : *
10552 : * Note that the overflow check above ensures that fabs(x) < 6000, which
10553 : * means that ndiv2 <= 20 here.
10554 : */
10555 174 : if (fabs(val) > 0.01)
10556 : {
10557 144 : ndiv2 = 1;
10558 144 : val /= 2;
10559 :
10560 1818 : while (fabs(val) > 0.01)
10561 : {
10562 1674 : ndiv2++;
10563 1674 : val /= 2;
10564 : }
10565 :
10566 144 : local_rscale = x.dscale + ndiv2;
10567 144 : div_var_int(&x, 1 << ndiv2, 0, &x, local_rscale, true);
10568 : }
10569 : else
10570 30 : ndiv2 = 0;
10571 :
10572 : /*
10573 : * Set the scale for the Taylor series expansion. The final result has
10574 : * (dweight + rscale + 1) significant digits. In addition, we have to
10575 : * raise the Taylor series result to the power 2^ndiv2, which introduces
10576 : * an error of up to around log10(2^ndiv2) digits, so work with this many
10577 : * extra digits of precision (plus a few more for good measure).
10578 : */
10579 174 : sig_digits = 1 + dweight + rscale + (int) (ndiv2 * 0.301029995663981);
10580 174 : sig_digits = Max(sig_digits, 0) + 8;
10581 :
10582 174 : local_rscale = sig_digits - 1;
10583 :
10584 : /*
10585 : * Use the Taylor series
10586 : *
10587 : * exp(x) = 1 + x + x^2/2! + x^3/3! + ...
10588 : *
10589 : * Given the limited range of x, this should converge reasonably quickly.
10590 : * We run the series until the terms fall below the local_rscale limit.
10591 : */
10592 174 : add_var(&const_one, &x, result);
10593 :
10594 174 : mul_var(&x, &x, &elem, local_rscale);
10595 174 : ni = 2;
10596 174 : div_var_int(&elem, ni, 0, &elem, local_rscale, true);
10597 :
10598 4992 : while (elem.ndigits != 0)
10599 : {
10600 4818 : add_var(result, &elem, result);
10601 :
10602 4818 : mul_var(&elem, &x, &elem, local_rscale);
10603 4818 : ni++;
10604 4818 : div_var_int(&elem, ni, 0, &elem, local_rscale, true);
10605 : }
10606 :
10607 : /*
10608 : * Compensate for the argument range reduction. Since the weight of the
10609 : * result doubles with each multiplication, we can reduce the local rscale
10610 : * as we proceed.
10611 : */
10612 1992 : while (ndiv2-- > 0)
10613 : {
10614 1818 : local_rscale = sig_digits - result->weight * 2 * DEC_DIGITS;
10615 1818 : local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
10616 1818 : mul_var(result, result, result, local_rscale);
10617 : }
10618 :
10619 : /* Round to requested rscale */
10620 174 : round_var(result, rscale);
10621 :
10622 174 : free_var(&x);
10623 174 : free_var(&elem);
10624 : }
10625 :
10626 :
10627 : /*
10628 : * Estimate the dweight of the most significant decimal digit of the natural
10629 : * logarithm of a number.
10630 : *
10631 : * Essentially, we're approximating log10(abs(ln(var))). This is used to
10632 : * determine the appropriate rscale when computing natural logarithms.
10633 : *
10634 : * Note: many callers call this before range-checking the input. Therefore,
10635 : * we must be robust against values that are invalid to apply ln() to.
10636 : * We don't wish to throw an error here, so just return zero in such cases.
10637 : */
10638 : static int
10639 738 : estimate_ln_dweight(const NumericVar *var)
10640 : {
10641 : int ln_dweight;
10642 :
10643 : /* Caller should fail on ln(negative), but for the moment return zero */
10644 738 : if (var->sign != NUMERIC_POS)
10645 42 : return 0;
10646 :
10647 1314 : if (cmp_var(var, &const_zero_point_nine) >= 0 &&
10648 618 : cmp_var(var, &const_one_point_one) <= 0)
10649 90 : {
10650 : /*
10651 : * 0.9 <= var <= 1.1
10652 : *
10653 : * ln(var) has a negative weight (possibly very large). To get a
10654 : * reasonably accurate result, estimate it using ln(1+x) ~= x.
10655 : */
10656 : NumericVar x;
10657 :
10658 90 : init_var(&x);
10659 90 : sub_var(var, &const_one, &x);
10660 :
10661 90 : if (x.ndigits > 0)
10662 : {
10663 : /* Use weight of most significant decimal digit of x */
10664 42 : ln_dweight = x.weight * DEC_DIGITS + (int) log10(x.digits[0]);
10665 : }
10666 : else
10667 : {
10668 : /* x = 0. Since ln(1) = 0 exactly, we don't need extra digits */
10669 48 : ln_dweight = 0;
10670 : }
10671 :
10672 90 : free_var(&x);
10673 : }
10674 : else
10675 : {
10676 : /*
10677 : * Estimate the logarithm using the first couple of digits from the
10678 : * input number. This will give an accurate result whenever the input
10679 : * is not too close to 1.
10680 : */
10681 606 : if (var->ndigits > 0)
10682 : {
10683 : int digits;
10684 : int dweight;
10685 : double ln_var;
10686 :
10687 564 : digits = var->digits[0];
10688 564 : dweight = var->weight * DEC_DIGITS;
10689 :
10690 564 : if (var->ndigits > 1)
10691 : {
10692 342 : digits = digits * NBASE + var->digits[1];
10693 342 : dweight -= DEC_DIGITS;
10694 : }
10695 :
10696 : /*----------
10697 : * We have var ~= digits * 10^dweight
10698 : * so ln(var) ~= ln(digits) + dweight * ln(10)
10699 : *----------
10700 : */
10701 564 : ln_var = log((double) digits) + dweight * 2.302585092994046;
10702 564 : ln_dweight = (int) log10(fabs(ln_var));
10703 : }
10704 : else
10705 : {
10706 : /* Caller should fail on ln(0), but for the moment return zero */
10707 42 : ln_dweight = 0;
10708 : }
10709 : }
10710 :
10711 696 : return ln_dweight;
10712 : }
10713 :
10714 :
10715 : /*
10716 : * ln_var() -
10717 : *
10718 : * Compute the natural log of x
10719 : */
10720 : static void
10721 834 : ln_var(const NumericVar *arg, NumericVar *result, int rscale)
10722 : {
10723 : NumericVar x;
10724 : NumericVar xx;
10725 : int ni;
10726 : NumericVar elem;
10727 : NumericVar fact;
10728 : int nsqrt;
10729 : int local_rscale;
10730 : int cmp;
10731 :
10732 834 : cmp = cmp_var(arg, &const_zero);
10733 834 : if (cmp == 0)
10734 42 : ereport(ERROR,
10735 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
10736 : errmsg("cannot take logarithm of zero")));
10737 792 : else if (cmp < 0)
10738 36 : ereport(ERROR,
10739 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
10740 : errmsg("cannot take logarithm of a negative number")));
10741 :
10742 756 : init_var(&x);
10743 756 : init_var(&xx);
10744 756 : init_var(&elem);
10745 756 : init_var(&fact);
10746 :
10747 756 : set_var_from_var(arg, &x);
10748 756 : set_var_from_var(&const_two, &fact);
10749 :
10750 : /*
10751 : * Reduce input into range 0.9 < x < 1.1 with repeated sqrt() operations.
10752 : *
10753 : * The final logarithm will have up to around rscale+6 significant digits.
10754 : * Each sqrt() will roughly halve the weight of x, so adjust the local
10755 : * rscale as we work so that we keep this many significant digits at each
10756 : * step (plus a few more for good measure).
10757 : *
10758 : * Note that we allow local_rscale < 0 during this input reduction
10759 : * process, which implies rounding before the decimal point. sqrt_var()
10760 : * explicitly supports this, and it significantly reduces the work
10761 : * required to reduce very large inputs to the required range. Once the
10762 : * input reduction is complete, x.weight will be 0 and its display scale
10763 : * will be non-negative again.
10764 : */
10765 756 : nsqrt = 0;
10766 1068 : while (cmp_var(&x, &const_zero_point_nine) <= 0)
10767 : {
10768 312 : local_rscale = rscale - x.weight * DEC_DIGITS / 2 + 8;
10769 312 : sqrt_var(&x, &x, local_rscale);
10770 312 : mul_var(&fact, &const_two, &fact, 0);
10771 312 : nsqrt++;
10772 : }
10773 4128 : while (cmp_var(&x, &const_one_point_one) >= 0)
10774 : {
10775 3372 : local_rscale = rscale - x.weight * DEC_DIGITS / 2 + 8;
10776 3372 : sqrt_var(&x, &x, local_rscale);
10777 3372 : mul_var(&fact, &const_two, &fact, 0);
10778 3372 : nsqrt++;
10779 : }
10780 :
10781 : /*
10782 : * We use the Taylor series for 0.5 * ln((1+z)/(1-z)),
10783 : *
10784 : * z + z^3/3 + z^5/5 + ...
10785 : *
10786 : * where z = (x-1)/(x+1) is in the range (approximately) -0.053 .. 0.048
10787 : * due to the above range-reduction of x.
10788 : *
10789 : * The convergence of this is not as fast as one would like, but is
10790 : * tolerable given that z is small.
10791 : *
10792 : * The Taylor series result will be multiplied by 2^(nsqrt+1), which has a
10793 : * decimal weight of (nsqrt+1) * log10(2), so work with this many extra
10794 : * digits of precision (plus a few more for good measure).
10795 : */
10796 756 : local_rscale = rscale + (int) ((nsqrt + 1) * 0.301029995663981) + 8;
10797 :
10798 756 : sub_var(&x, &const_one, result);
10799 756 : add_var(&x, &const_one, &elem);
10800 756 : div_var(result, &elem, result, local_rscale, true, false);
10801 756 : set_var_from_var(result, &xx);
10802 756 : mul_var(result, result, &x, local_rscale);
10803 :
10804 756 : ni = 1;
10805 :
10806 : for (;;)
10807 : {
10808 14022 : ni += 2;
10809 14022 : mul_var(&xx, &x, &xx, local_rscale);
10810 14022 : div_var_int(&xx, ni, 0, &elem, local_rscale, true);
10811 :
10812 14022 : if (elem.ndigits == 0)
10813 756 : break;
10814 :
10815 13266 : add_var(result, &elem, result);
10816 :
10817 13266 : if (elem.weight < (result->weight - local_rscale * 2 / DEC_DIGITS))
10818 0 : break;
10819 : }
10820 :
10821 : /* Compensate for argument range reduction, round to requested rscale */
10822 756 : mul_var(result, &fact, result, rscale);
10823 :
10824 756 : free_var(&x);
10825 756 : free_var(&xx);
10826 756 : free_var(&elem);
10827 756 : free_var(&fact);
10828 756 : }
10829 :
10830 :
10831 : /*
10832 : * log_var() -
10833 : *
10834 : * Compute the logarithm of num in a given base.
10835 : *
10836 : * Note: this routine chooses dscale of the result.
10837 : */
10838 : static void
10839 216 : log_var(const NumericVar *base, const NumericVar *num, NumericVar *result)
10840 : {
10841 : NumericVar ln_base;
10842 : NumericVar ln_num;
10843 : int ln_base_dweight;
10844 : int ln_num_dweight;
10845 : int result_dweight;
10846 : int rscale;
10847 : int ln_base_rscale;
10848 : int ln_num_rscale;
10849 :
10850 216 : init_var(&ln_base);
10851 216 : init_var(&ln_num);
10852 :
10853 : /* Estimated dweights of ln(base), ln(num) and the final result */
10854 216 : ln_base_dweight = estimate_ln_dweight(base);
10855 216 : ln_num_dweight = estimate_ln_dweight(num);
10856 216 : result_dweight = ln_num_dweight - ln_base_dweight;
10857 :
10858 : /*
10859 : * Select the scale of the result so that it will have at least
10860 : * NUMERIC_MIN_SIG_DIGITS significant digits and is not less than either
10861 : * input's display scale.
10862 : */
10863 216 : rscale = NUMERIC_MIN_SIG_DIGITS - result_dweight;
10864 216 : rscale = Max(rscale, base->dscale);
10865 216 : rscale = Max(rscale, num->dscale);
10866 216 : rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
10867 216 : rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
10868 :
10869 : /*
10870 : * Set the scales for ln(base) and ln(num) so that they each have more
10871 : * significant digits than the final result.
10872 : */
10873 216 : ln_base_rscale = rscale + result_dweight - ln_base_dweight + 8;
10874 216 : ln_base_rscale = Max(ln_base_rscale, NUMERIC_MIN_DISPLAY_SCALE);
10875 :
10876 216 : ln_num_rscale = rscale + result_dweight - ln_num_dweight + 8;
10877 216 : ln_num_rscale = Max(ln_num_rscale, NUMERIC_MIN_DISPLAY_SCALE);
10878 :
10879 : /* Form natural logarithms */
10880 216 : ln_var(base, &ln_base, ln_base_rscale);
10881 192 : ln_var(num, &ln_num, ln_num_rscale);
10882 :
10883 : /* Divide and round to the required scale */
10884 162 : div_var(&ln_num, &ln_base, result, rscale, true, false);
10885 :
10886 156 : free_var(&ln_num);
10887 156 : free_var(&ln_base);
10888 156 : }
10889 :
10890 :
10891 : /*
10892 : * power_var() -
10893 : *
10894 : * Raise base to the power of exp
10895 : *
10896 : * Note: this routine chooses dscale of the result.
10897 : */
10898 : static void
10899 1398 : power_var(const NumericVar *base, const NumericVar *exp, NumericVar *result)
10900 : {
10901 : int res_sign;
10902 : NumericVar abs_base;
10903 : NumericVar ln_base;
10904 : NumericVar ln_num;
10905 : int ln_dweight;
10906 : int rscale;
10907 : int sig_digits;
10908 : int local_rscale;
10909 : double val;
10910 :
10911 : /* If exp can be represented as an integer, use power_var_int */
10912 1398 : if (exp->ndigits == 0 || exp->ndigits <= exp->weight + 1)
10913 : {
10914 : /* exact integer, but does it fit in int? */
10915 : int64 expval64;
10916 :
10917 1272 : if (numericvar_to_int64(exp, &expval64))
10918 : {
10919 1266 : if (expval64 >= PG_INT32_MIN && expval64 <= PG_INT32_MAX)
10920 : {
10921 : /* Okay, use power_var_int */
10922 1236 : power_var_int(base, (int) expval64, exp->dscale, result);
10923 1224 : return;
10924 : }
10925 : }
10926 : }
10927 :
10928 : /*
10929 : * This avoids log(0) for cases of 0 raised to a non-integer. 0 ^ 0 is
10930 : * handled by power_var_int().
10931 : */
10932 162 : if (cmp_var(base, &const_zero) == 0)
10933 : {
10934 18 : set_var_from_var(&const_zero, result);
10935 18 : result->dscale = NUMERIC_MIN_SIG_DIGITS; /* no need to round */
10936 18 : return;
10937 : }
10938 :
10939 144 : init_var(&abs_base);
10940 144 : init_var(&ln_base);
10941 144 : init_var(&ln_num);
10942 :
10943 : /*
10944 : * If base is negative, insist that exp be an integer. The result is then
10945 : * positive if exp is even and negative if exp is odd.
10946 : */
10947 144 : if (base->sign == NUMERIC_NEG)
10948 : {
10949 : /*
10950 : * Check that exp is an integer. This error code is defined by the
10951 : * SQL standard, and matches other errors in numeric_power().
10952 : */
10953 36 : if (exp->ndigits > 0 && exp->ndigits > exp->weight + 1)
10954 18 : ereport(ERROR,
10955 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
10956 : errmsg("a negative number raised to a non-integer power yields a complex result")));
10957 :
10958 : /* Test if exp is odd or even */
10959 18 : if (exp->ndigits > 0 && exp->ndigits == exp->weight + 1 &&
10960 12 : (exp->digits[exp->ndigits - 1] & 1))
10961 6 : res_sign = NUMERIC_NEG;
10962 : else
10963 12 : res_sign = NUMERIC_POS;
10964 :
10965 : /* Then work with abs(base) below */
10966 18 : set_var_from_var(base, &abs_base);
10967 18 : abs_base.sign = NUMERIC_POS;
10968 18 : base = &abs_base;
10969 : }
10970 : else
10971 108 : res_sign = NUMERIC_POS;
10972 :
10973 : /*----------
10974 : * Decide on the scale for the ln() calculation. For this we need an
10975 : * estimate of the weight of the result, which we obtain by doing an
10976 : * initial low-precision calculation of exp * ln(base).
10977 : *
10978 : * We want result = e ^ (exp * ln(base))
10979 : * so result dweight = log10(result) = exp * ln(base) * log10(e)
10980 : *
10981 : * We also perform a crude overflow test here so that we can exit early if
10982 : * the full-precision result is sure to overflow, and to guard against
10983 : * integer overflow when determining the scale for the real calculation.
10984 : * exp_var() supports inputs up to NUMERIC_MAX_RESULT_SCALE * 3, so the
10985 : * result will overflow if exp * ln(base) >= NUMERIC_MAX_RESULT_SCALE * 3.
10986 : * Since the values here are only approximations, we apply a small fuzz
10987 : * factor to this overflow test and let exp_var() determine the exact
10988 : * overflow threshold so that it is consistent for all inputs.
10989 : *----------
10990 : */
10991 126 : ln_dweight = estimate_ln_dweight(base);
10992 :
10993 : /*
10994 : * Set the scale for the low-precision calculation, computing ln(base) to
10995 : * around 8 significant digits. Note that ln_dweight may be as small as
10996 : * -NUMERIC_DSCALE_MAX, so the scale may exceed NUMERIC_MAX_DISPLAY_SCALE
10997 : * here.
10998 : */
10999 126 : local_rscale = 8 - ln_dweight;
11000 126 : local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
11001 :
11002 126 : ln_var(base, &ln_base, local_rscale);
11003 :
11004 126 : mul_var(&ln_base, exp, &ln_num, local_rscale);
11005 :
11006 126 : val = numericvar_to_double_no_overflow(&ln_num);
11007 :
11008 : /* initial overflow/underflow test with fuzz factor */
11009 126 : if (fabs(val) > NUMERIC_MAX_RESULT_SCALE * 3.01)
11010 : {
11011 6 : if (val > 0)
11012 0 : ereport(ERROR,
11013 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
11014 : errmsg("value overflows numeric format")));
11015 6 : zero_var(result);
11016 6 : result->dscale = NUMERIC_MAX_DISPLAY_SCALE;
11017 6 : return;
11018 : }
11019 :
11020 120 : val *= 0.434294481903252; /* approximate decimal result weight */
11021 :
11022 : /* choose the result scale */
11023 120 : rscale = NUMERIC_MIN_SIG_DIGITS - (int) val;
11024 120 : rscale = Max(rscale, base->dscale);
11025 120 : rscale = Max(rscale, exp->dscale);
11026 120 : rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
11027 120 : rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
11028 :
11029 : /* significant digits required in the result */
11030 120 : sig_digits = rscale + (int) val;
11031 120 : sig_digits = Max(sig_digits, 0);
11032 :
11033 : /* set the scale for the real exp * ln(base) calculation */
11034 120 : local_rscale = sig_digits - ln_dweight + 8;
11035 120 : local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
11036 :
11037 : /* and do the real calculation */
11038 :
11039 120 : ln_var(base, &ln_base, local_rscale);
11040 :
11041 120 : mul_var(&ln_base, exp, &ln_num, local_rscale);
11042 :
11043 120 : exp_var(&ln_num, result, rscale);
11044 :
11045 120 : if (res_sign == NUMERIC_NEG && result->ndigits > 0)
11046 6 : result->sign = NUMERIC_NEG;
11047 :
11048 120 : free_var(&ln_num);
11049 120 : free_var(&ln_base);
11050 120 : free_var(&abs_base);
11051 : }
11052 :
11053 : /*
11054 : * power_var_int() -
11055 : *
11056 : * Raise base to the power of exp, where exp is an integer.
11057 : *
11058 : * Note: this routine chooses dscale of the result.
11059 : */
11060 : static void
11061 1236 : power_var_int(const NumericVar *base, int exp, int exp_dscale,
11062 : NumericVar *result)
11063 : {
11064 : double f;
11065 : int p;
11066 : int i;
11067 : int rscale;
11068 : int sig_digits;
11069 : unsigned int mask;
11070 : bool neg;
11071 : NumericVar base_prod;
11072 : int local_rscale;
11073 :
11074 : /*
11075 : * Choose the result scale. For this we need an estimate of the decimal
11076 : * weight of the result, which we obtain by approximating using double
11077 : * precision arithmetic.
11078 : *
11079 : * We also perform crude overflow/underflow tests here so that we can exit
11080 : * early if the result is sure to overflow/underflow, and to guard against
11081 : * integer overflow when choosing the result scale.
11082 : */
11083 1236 : if (base->ndigits != 0)
11084 : {
11085 : /*----------
11086 : * Choose f (double) and p (int) such that base ~= f * 10^p.
11087 : * Then log10(result) = log10(base^exp) ~= exp * (log10(f) + p).
11088 : *----------
11089 : */
11090 1206 : f = base->digits[0];
11091 1206 : p = base->weight * DEC_DIGITS;
11092 :
11093 1290 : for (i = 1; i < base->ndigits && i * DEC_DIGITS < 16; i++)
11094 : {
11095 84 : f = f * NBASE + base->digits[i];
11096 84 : p -= DEC_DIGITS;
11097 : }
11098 :
11099 1206 : f = exp * (log10(f) + p); /* approximate decimal result weight */
11100 : }
11101 : else
11102 30 : f = 0; /* result is 0 or 1 (weight 0), or error */
11103 :
11104 : /* overflow/underflow tests with fuzz factors */
11105 1236 : if (f > (NUMERIC_WEIGHT_MAX + 1) * DEC_DIGITS)
11106 12 : ereport(ERROR,
11107 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
11108 : errmsg("value overflows numeric format")));
11109 1224 : if (f + 1 < -NUMERIC_MAX_DISPLAY_SCALE)
11110 : {
11111 12 : zero_var(result);
11112 12 : result->dscale = NUMERIC_MAX_DISPLAY_SCALE;
11113 216 : return;
11114 : }
11115 :
11116 : /*
11117 : * Choose the result scale in the same way as power_var(), so it has at
11118 : * least NUMERIC_MIN_SIG_DIGITS significant digits and is not less than
11119 : * either input's display scale.
11120 : */
11121 1212 : rscale = NUMERIC_MIN_SIG_DIGITS - (int) f;
11122 1212 : rscale = Max(rscale, base->dscale);
11123 1212 : rscale = Max(rscale, exp_dscale);
11124 1212 : rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
11125 1212 : rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
11126 :
11127 : /* Handle some common special cases, as well as corner cases */
11128 1212 : switch (exp)
11129 : {
11130 72 : case 0:
11131 :
11132 : /*
11133 : * While 0 ^ 0 can be either 1 or indeterminate (error), we treat
11134 : * it as 1 because most programming languages do this. SQL:2003
11135 : * also requires a return value of 1.
11136 : * https://en.wikipedia.org/wiki/Exponentiation#Zero_to_the_zero_power
11137 : */
11138 72 : set_var_from_var(&const_one, result);
11139 72 : result->dscale = rscale; /* no need to round */
11140 72 : return;
11141 48 : case 1:
11142 48 : set_var_from_var(base, result);
11143 48 : round_var(result, rscale);
11144 48 : return;
11145 30 : case -1:
11146 30 : div_var(&const_one, base, result, rscale, true, true);
11147 30 : return;
11148 54 : case 2:
11149 54 : mul_var(base, base, result, rscale);
11150 54 : return;
11151 1008 : default:
11152 1008 : break;
11153 : }
11154 :
11155 : /* Handle the special case where the base is zero */
11156 1008 : if (base->ndigits == 0)
11157 : {
11158 0 : if (exp < 0)
11159 0 : ereport(ERROR,
11160 : (errcode(ERRCODE_DIVISION_BY_ZERO),
11161 : errmsg("division by zero")));
11162 0 : zero_var(result);
11163 0 : result->dscale = rscale;
11164 0 : return;
11165 : }
11166 :
11167 : /*
11168 : * The general case repeatedly multiplies base according to the bit
11169 : * pattern of exp.
11170 : *
11171 : * The local rscale used for each multiplication is varied to keep a fixed
11172 : * number of significant digits, sufficient to give the required result
11173 : * scale.
11174 : */
11175 :
11176 : /*
11177 : * Approximate number of significant digits in the result. Note that the
11178 : * underflow test above, together with the choice of rscale, ensures that
11179 : * this approximation is necessarily > 0.
11180 : */
11181 1008 : sig_digits = 1 + rscale + (int) f;
11182 :
11183 : /*
11184 : * The multiplications to produce the result may introduce an error of up
11185 : * to around log10(abs(exp)) digits, so work with this many extra digits
11186 : * of precision (plus a few more for good measure).
11187 : */
11188 1008 : sig_digits += (int) log(fabs((double) exp)) + 8;
11189 :
11190 : /*
11191 : * Now we can proceed with the multiplications.
11192 : */
11193 1008 : neg = (exp < 0);
11194 1008 : mask = pg_abs_s32(exp);
11195 :
11196 1008 : init_var(&base_prod);
11197 1008 : set_var_from_var(base, &base_prod);
11198 :
11199 1008 : if (mask & 1)
11200 498 : set_var_from_var(base, result);
11201 : else
11202 510 : set_var_from_var(&const_one, result);
11203 :
11204 5076 : while ((mask >>= 1) > 0)
11205 : {
11206 : /*
11207 : * Do the multiplications using rscales large enough to hold the
11208 : * results to the required number of significant digits, but don't
11209 : * waste time by exceeding the scales of the numbers themselves.
11210 : */
11211 4068 : local_rscale = sig_digits - 2 * base_prod.weight * DEC_DIGITS;
11212 4068 : local_rscale = Min(local_rscale, 2 * base_prod.dscale);
11213 4068 : local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
11214 :
11215 4068 : mul_var(&base_prod, &base_prod, &base_prod, local_rscale);
11216 :
11217 4068 : if (mask & 1)
11218 : {
11219 2658 : local_rscale = sig_digits -
11220 2658 : (base_prod.weight + result->weight) * DEC_DIGITS;
11221 2658 : local_rscale = Min(local_rscale,
11222 : base_prod.dscale + result->dscale);
11223 2658 : local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
11224 :
11225 2658 : mul_var(&base_prod, result, result, local_rscale);
11226 : }
11227 :
11228 : /*
11229 : * When abs(base) > 1, the number of digits to the left of the decimal
11230 : * point in base_prod doubles at each iteration, so if exp is large we
11231 : * could easily spend large amounts of time and memory space doing the
11232 : * multiplications. But once the weight exceeds what will fit in
11233 : * int16, the final result is guaranteed to overflow (or underflow, if
11234 : * exp < 0), so we can give up before wasting too many cycles.
11235 : */
11236 4068 : if (base_prod.weight > NUMERIC_WEIGHT_MAX ||
11237 4068 : result->weight > NUMERIC_WEIGHT_MAX)
11238 : {
11239 : /* overflow, unless neg, in which case result should be 0 */
11240 0 : if (!neg)
11241 0 : ereport(ERROR,
11242 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
11243 : errmsg("value overflows numeric format")));
11244 0 : zero_var(result);
11245 0 : neg = false;
11246 0 : break;
11247 : }
11248 : }
11249 :
11250 1008 : free_var(&base_prod);
11251 :
11252 : /* Compensate for input sign, and round to requested rscale */
11253 1008 : if (neg)
11254 486 : div_var(&const_one, result, result, rscale, true, false);
11255 : else
11256 522 : round_var(result, rscale);
11257 : }
11258 :
11259 : /*
11260 : * power_ten_int() -
11261 : *
11262 : * Raise ten to the power of exp, where exp is an integer. Note that unlike
11263 : * power_var_int(), this does no overflow/underflow checking or rounding.
11264 : */
11265 : static void
11266 228 : power_ten_int(int exp, NumericVar *result)
11267 : {
11268 : /* Construct the result directly, starting from 10^0 = 1 */
11269 228 : set_var_from_var(&const_one, result);
11270 :
11271 : /* Scale needed to represent the result exactly */
11272 228 : result->dscale = exp < 0 ? -exp : 0;
11273 :
11274 : /* Base-NBASE weight of result and remaining exponent */
11275 228 : if (exp >= 0)
11276 162 : result->weight = exp / DEC_DIGITS;
11277 : else
11278 66 : result->weight = (exp + 1) / DEC_DIGITS - 1;
11279 :
11280 228 : exp -= result->weight * DEC_DIGITS;
11281 :
11282 : /* Final adjustment of the result's single NBASE digit */
11283 594 : while (exp-- > 0)
11284 366 : result->digits[0] *= 10;
11285 228 : }
11286 :
11287 : /*
11288 : * random_var() - return a random value in the range [rmin, rmax].
11289 : */
11290 : static void
11291 33438 : random_var(pg_prng_state *state, const NumericVar *rmin,
11292 : const NumericVar *rmax, NumericVar *result)
11293 : {
11294 : int rscale;
11295 : NumericVar rlen;
11296 : int res_ndigits;
11297 : int n;
11298 : int pow10;
11299 : int i;
11300 : uint64 rlen64;
11301 : int rlen64_ndigits;
11302 :
11303 33438 : rscale = Max(rmin->dscale, rmax->dscale);
11304 :
11305 : /* Compute rlen = rmax - rmin and check the range bounds */
11306 33438 : init_var(&rlen);
11307 33438 : sub_var(rmax, rmin, &rlen);
11308 :
11309 33438 : if (rlen.sign == NUMERIC_NEG)
11310 6 : ereport(ERROR,
11311 : errcode(ERRCODE_INVALID_PARAMETER_VALUE),
11312 : errmsg("lower bound must be less than or equal to upper bound"));
11313 :
11314 : /* Special case for an empty range */
11315 33432 : if (rlen.ndigits == 0)
11316 : {
11317 12 : set_var_from_var(rmin, result);
11318 12 : result->dscale = rscale;
11319 12 : free_var(&rlen);
11320 12 : return;
11321 : }
11322 :
11323 : /*
11324 : * Otherwise, select a random value in the range [0, rlen = rmax - rmin],
11325 : * and shift it to the required range by adding rmin.
11326 : */
11327 :
11328 : /* Required result digits */
11329 33420 : res_ndigits = rlen.weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
11330 :
11331 : /*
11332 : * To get the required rscale, the final result digit must be a multiple
11333 : * of pow10 = 10^n, where n = (-rscale) mod DEC_DIGITS.
11334 : */
11335 33420 : n = ((rscale + DEC_DIGITS - 1) / DEC_DIGITS) * DEC_DIGITS - rscale;
11336 33420 : pow10 = 1;
11337 87900 : for (i = 0; i < n; i++)
11338 54480 : pow10 *= 10;
11339 :
11340 : /*
11341 : * To choose a random value uniformly from the range [0, rlen], we choose
11342 : * from the slightly larger range [0, rlen2], where rlen2 is formed from
11343 : * rlen by copying the first 4 NBASE digits, and setting all remaining
11344 : * decimal digits to "9".
11345 : *
11346 : * Without loss of generality, we can ignore the weight of rlen2 and treat
11347 : * it as a pure integer for the purposes of this discussion. The process
11348 : * above gives rlen2 + 1 = rlen64 * 10^N, for some integer N, where rlen64
11349 : * is a 64-bit integer formed from the first 4 NBASE digits copied from
11350 : * rlen. Since this trivially factors into smaller pieces that fit in
11351 : * 64-bit integers, the task of choosing a random value uniformly from the
11352 : * rlen2 + 1 possible values in [0, rlen2] is much simpler.
11353 : *
11354 : * If the random value selected is too large, it is rejected, and we try
11355 : * again until we get a result <= rlen, ensuring that the overall result
11356 : * is uniform (no particular value is any more likely than any other).
11357 : *
11358 : * Since rlen64 holds 4 NBASE digits from rlen, it contains at least
11359 : * DEC_DIGITS * 3 + 1 decimal digits (i.e., at least 13 decimal digits,
11360 : * when DEC_DIGITS is 4). Therefore the probability of needing to reject
11361 : * the value chosen and retry is less than 1e-13.
11362 : */
11363 33420 : rlen64 = (uint64) rlen.digits[0];
11364 33420 : rlen64_ndigits = 1;
11365 76212 : while (rlen64_ndigits < res_ndigits && rlen64_ndigits < 4)
11366 : {
11367 42792 : rlen64 *= NBASE;
11368 42792 : if (rlen64_ndigits < rlen.ndigits)
11369 6612 : rlen64 += rlen.digits[rlen64_ndigits];
11370 42792 : rlen64_ndigits++;
11371 : }
11372 :
11373 : /* Loop until we get a result <= rlen */
11374 : do
11375 : {
11376 : NumericDigit *res_digits;
11377 : uint64 rand;
11378 : int whole_ndigits;
11379 :
11380 33420 : alloc_var(result, res_ndigits);
11381 33420 : result->sign = NUMERIC_POS;
11382 33420 : result->weight = rlen.weight;
11383 33420 : result->dscale = rscale;
11384 33420 : res_digits = result->digits;
11385 :
11386 : /*
11387 : * Set the first rlen64_ndigits using a random value in [0, rlen64].
11388 : *
11389 : * If this is the whole result, and rscale is not a multiple of
11390 : * DEC_DIGITS (pow10 from above is not 1), then we need this to be a
11391 : * multiple of pow10.
11392 : */
11393 33420 : if (rlen64_ndigits == res_ndigits && pow10 != 1)
11394 21132 : rand = pg_prng_uint64_range(state, 0, rlen64 / pow10) * pow10;
11395 : else
11396 12288 : rand = pg_prng_uint64_range(state, 0, rlen64);
11397 :
11398 109632 : for (i = rlen64_ndigits - 1; i >= 0; i--)
11399 : {
11400 76212 : res_digits[i] = (NumericDigit) (rand % NBASE);
11401 76212 : rand = rand / NBASE;
11402 : }
11403 :
11404 : /*
11405 : * Set the remaining digits to random values in range [0, NBASE),
11406 : * noting that the last digit needs to be a multiple of pow10.
11407 : */
11408 33420 : whole_ndigits = res_ndigits;
11409 33420 : if (pow10 != 1)
11410 33210 : whole_ndigits--;
11411 :
11412 : /* Set whole digits in groups of 4 for best performance */
11413 33420 : i = rlen64_ndigits;
11414 33480 : while (i < whole_ndigits - 3)
11415 : {
11416 60 : rand = pg_prng_uint64_range(state, 0,
11417 : (uint64) NBASE * NBASE * NBASE * NBASE - 1);
11418 60 : res_digits[i++] = (NumericDigit) (rand % NBASE);
11419 60 : rand = rand / NBASE;
11420 60 : res_digits[i++] = (NumericDigit) (rand % NBASE);
11421 60 : rand = rand / NBASE;
11422 60 : res_digits[i++] = (NumericDigit) (rand % NBASE);
11423 60 : rand = rand / NBASE;
11424 60 : res_digits[i++] = (NumericDigit) rand;
11425 : }
11426 :
11427 : /* Remaining whole digits */
11428 33630 : while (i < whole_ndigits)
11429 : {
11430 210 : rand = pg_prng_uint64_range(state, 0, NBASE - 1);
11431 210 : res_digits[i++] = (NumericDigit) rand;
11432 : }
11433 :
11434 : /* Final partial digit (multiple of pow10) */
11435 33420 : if (i < res_ndigits)
11436 : {
11437 12078 : rand = pg_prng_uint64_range(state, 0, NBASE / pow10 - 1) * pow10;
11438 12078 : res_digits[i] = (NumericDigit) rand;
11439 : }
11440 :
11441 : /* Remove leading/trailing zeroes */
11442 33420 : strip_var(result);
11443 :
11444 : /* If result > rlen, try again */
11445 :
11446 33420 : } while (cmp_var(result, &rlen) > 0);
11447 :
11448 : /* Offset the result to the required range */
11449 33420 : add_var(result, rmin, result);
11450 :
11451 33420 : free_var(&rlen);
11452 : }
11453 :
11454 :
11455 : /* ----------------------------------------------------------------------
11456 : *
11457 : * Following are the lowest level functions that operate unsigned
11458 : * on the variable level
11459 : *
11460 : * ----------------------------------------------------------------------
11461 : */
11462 :
11463 :
11464 : /* ----------
11465 : * cmp_abs() -
11466 : *
11467 : * Compare the absolute values of var1 and var2
11468 : * Returns: -1 for ABS(var1) < ABS(var2)
11469 : * 0 for ABS(var1) == ABS(var2)
11470 : * 1 for ABS(var1) > ABS(var2)
11471 : * ----------
11472 : */
11473 : static int
11474 709538 : cmp_abs(const NumericVar *var1, const NumericVar *var2)
11475 : {
11476 1419076 : return cmp_abs_common(var1->digits, var1->ndigits, var1->weight,
11477 709538 : var2->digits, var2->ndigits, var2->weight);
11478 : }
11479 :
11480 : /* ----------
11481 : * cmp_abs_common() -
11482 : *
11483 : * Main routine of cmp_abs(). This function can be used by both
11484 : * NumericVar and Numeric.
11485 : * ----------
11486 : */
11487 : static int
11488 19566002 : cmp_abs_common(const NumericDigit *var1digits, int var1ndigits, int var1weight,
11489 : const NumericDigit *var2digits, int var2ndigits, int var2weight)
11490 : {
11491 19566002 : int i1 = 0;
11492 19566002 : int i2 = 0;
11493 :
11494 : /* Check any digits before the first common digit */
11495 :
11496 19566002 : while (var1weight > var2weight && i1 < var1ndigits)
11497 : {
11498 25784 : if (var1digits[i1++] != 0)
11499 25784 : return 1;
11500 0 : var1weight--;
11501 : }
11502 19540218 : while (var2weight > var1weight && i2 < var2ndigits)
11503 : {
11504 150314 : if (var2digits[i2++] != 0)
11505 150314 : return -1;
11506 0 : var2weight--;
11507 : }
11508 :
11509 : /* At this point, either w1 == w2 or we've run out of digits */
11510 :
11511 19389904 : if (var1weight == var2weight)
11512 : {
11513 31526714 : while (i1 < var1ndigits && i2 < var2ndigits)
11514 : {
11515 20954802 : int stat = var1digits[i1++] - var2digits[i2++];
11516 :
11517 20954802 : if (stat)
11518 : {
11519 8811634 : if (stat > 0)
11520 5292214 : return 1;
11521 3519420 : return -1;
11522 : }
11523 : }
11524 : }
11525 :
11526 : /*
11527 : * At this point, we've run out of digits on one side or the other; so any
11528 : * remaining nonzero digits imply that side is larger
11529 : */
11530 10578606 : while (i1 < var1ndigits)
11531 : {
11532 9500 : if (var1digits[i1++] != 0)
11533 9164 : return 1;
11534 : }
11535 10569430 : while (i2 < var2ndigits)
11536 : {
11537 1210 : if (var2digits[i2++] != 0)
11538 886 : return -1;
11539 : }
11540 :
11541 10568220 : return 0;
11542 : }
11543 :
11544 :
11545 : /*
11546 : * add_abs() -
11547 : *
11548 : * Add the absolute values of two variables into result.
11549 : * result might point to one of the operands without danger.
11550 : */
11551 : static void
11552 446314 : add_abs(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
11553 : {
11554 : NumericDigit *res_buf;
11555 : NumericDigit *res_digits;
11556 : int res_ndigits;
11557 : int res_weight;
11558 : int res_rscale,
11559 : rscale1,
11560 : rscale2;
11561 : int res_dscale;
11562 : int i,
11563 : i1,
11564 : i2;
11565 446314 : int carry = 0;
11566 :
11567 : /* copy these values into local vars for speed in inner loop */
11568 446314 : int var1ndigits = var1->ndigits;
11569 446314 : int var2ndigits = var2->ndigits;
11570 446314 : NumericDigit *var1digits = var1->digits;
11571 446314 : NumericDigit *var2digits = var2->digits;
11572 :
11573 446314 : res_weight = Max(var1->weight, var2->weight) + 1;
11574 :
11575 446314 : res_dscale = Max(var1->dscale, var2->dscale);
11576 :
11577 : /* Note: here we are figuring rscale in base-NBASE digits */
11578 446314 : rscale1 = var1->ndigits - var1->weight - 1;
11579 446314 : rscale2 = var2->ndigits - var2->weight - 1;
11580 446314 : res_rscale = Max(rscale1, rscale2);
11581 :
11582 446314 : res_ndigits = res_rscale + res_weight + 1;
11583 446314 : if (res_ndigits <= 0)
11584 0 : res_ndigits = 1;
11585 :
11586 446314 : res_buf = digitbuf_alloc(res_ndigits + 1);
11587 446314 : res_buf[0] = 0; /* spare digit for later rounding */
11588 446314 : res_digits = res_buf + 1;
11589 :
11590 446314 : i1 = res_rscale + var1->weight + 1;
11591 446314 : i2 = res_rscale + var2->weight + 1;
11592 3638884 : for (i = res_ndigits - 1; i >= 0; i--)
11593 : {
11594 3192570 : i1--;
11595 3192570 : i2--;
11596 3192570 : if (i1 >= 0 && i1 < var1ndigits)
11597 1416684 : carry += var1digits[i1];
11598 3192570 : if (i2 >= 0 && i2 < var2ndigits)
11599 1136434 : carry += var2digits[i2];
11600 :
11601 3192570 : if (carry >= NBASE)
11602 : {
11603 226076 : res_digits[i] = carry - NBASE;
11604 226076 : carry = 1;
11605 : }
11606 : else
11607 : {
11608 2966494 : res_digits[i] = carry;
11609 2966494 : carry = 0;
11610 : }
11611 : }
11612 :
11613 : Assert(carry == 0); /* else we failed to allow for carry out */
11614 :
11615 446314 : digitbuf_free(result->buf);
11616 446314 : result->ndigits = res_ndigits;
11617 446314 : result->buf = res_buf;
11618 446314 : result->digits = res_digits;
11619 446314 : result->weight = res_weight;
11620 446314 : result->dscale = res_dscale;
11621 :
11622 : /* Remove leading/trailing zeroes */
11623 446314 : strip_var(result);
11624 446314 : }
11625 :
11626 :
11627 : /*
11628 : * sub_abs()
11629 : *
11630 : * Subtract the absolute value of var2 from the absolute value of var1
11631 : * and store in result. result might point to one of the operands
11632 : * without danger.
11633 : *
11634 : * ABS(var1) MUST BE GREATER OR EQUAL ABS(var2) !!!
11635 : */
11636 : static void
11637 655278 : sub_abs(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
11638 : {
11639 : NumericDigit *res_buf;
11640 : NumericDigit *res_digits;
11641 : int res_ndigits;
11642 : int res_weight;
11643 : int res_rscale,
11644 : rscale1,
11645 : rscale2;
11646 : int res_dscale;
11647 : int i,
11648 : i1,
11649 : i2;
11650 655278 : int borrow = 0;
11651 :
11652 : /* copy these values into local vars for speed in inner loop */
11653 655278 : int var1ndigits = var1->ndigits;
11654 655278 : int var2ndigits = var2->ndigits;
11655 655278 : NumericDigit *var1digits = var1->digits;
11656 655278 : NumericDigit *var2digits = var2->digits;
11657 :
11658 655278 : res_weight = var1->weight;
11659 :
11660 655278 : res_dscale = Max(var1->dscale, var2->dscale);
11661 :
11662 : /* Note: here we are figuring rscale in base-NBASE digits */
11663 655278 : rscale1 = var1->ndigits - var1->weight - 1;
11664 655278 : rscale2 = var2->ndigits - var2->weight - 1;
11665 655278 : res_rscale = Max(rscale1, rscale2);
11666 :
11667 655278 : res_ndigits = res_rscale + res_weight + 1;
11668 655278 : if (res_ndigits <= 0)
11669 0 : res_ndigits = 1;
11670 :
11671 655278 : res_buf = digitbuf_alloc(res_ndigits + 1);
11672 655278 : res_buf[0] = 0; /* spare digit for later rounding */
11673 655278 : res_digits = res_buf + 1;
11674 :
11675 655278 : i1 = res_rscale + var1->weight + 1;
11676 655278 : i2 = res_rscale + var2->weight + 1;
11677 5188520 : for (i = res_ndigits - 1; i >= 0; i--)
11678 : {
11679 4533242 : i1--;
11680 4533242 : i2--;
11681 4533242 : if (i1 >= 0 && i1 < var1ndigits)
11682 4112122 : borrow += var1digits[i1];
11683 4533242 : if (i2 >= 0 && i2 < var2ndigits)
11684 4032070 : borrow -= var2digits[i2];
11685 :
11686 4533242 : if (borrow < 0)
11687 : {
11688 454100 : res_digits[i] = borrow + NBASE;
11689 454100 : borrow = -1;
11690 : }
11691 : else
11692 : {
11693 4079142 : res_digits[i] = borrow;
11694 4079142 : borrow = 0;
11695 : }
11696 : }
11697 :
11698 : Assert(borrow == 0); /* else caller gave us var1 < var2 */
11699 :
11700 655278 : digitbuf_free(result->buf);
11701 655278 : result->ndigits = res_ndigits;
11702 655278 : result->buf = res_buf;
11703 655278 : result->digits = res_digits;
11704 655278 : result->weight = res_weight;
11705 655278 : result->dscale = res_dscale;
11706 :
11707 : /* Remove leading/trailing zeroes */
11708 655278 : strip_var(result);
11709 655278 : }
11710 :
11711 : /*
11712 : * round_var
11713 : *
11714 : * Round the value of a variable to no more than rscale decimal digits
11715 : * after the decimal point. NOTE: we allow rscale < 0 here, implying
11716 : * rounding before the decimal point.
11717 : */
11718 : static void
11719 248768 : round_var(NumericVar *var, int rscale)
11720 : {
11721 248768 : NumericDigit *digits = var->digits;
11722 : int di;
11723 : int ndigits;
11724 : int carry;
11725 :
11726 248768 : var->dscale = rscale;
11727 :
11728 : /* decimal digits wanted */
11729 248768 : di = (var->weight + 1) * DEC_DIGITS + rscale;
11730 :
11731 : /*
11732 : * If di = 0, the value loses all digits, but could round up to 1 if its
11733 : * first extra digit is >= 5. If di < 0 the result must be 0.
11734 : */
11735 248768 : if (di < 0)
11736 : {
11737 104 : var->ndigits = 0;
11738 104 : var->weight = 0;
11739 104 : var->sign = NUMERIC_POS;
11740 : }
11741 : else
11742 : {
11743 : /* NBASE digits wanted */
11744 248664 : ndigits = (di + DEC_DIGITS - 1) / DEC_DIGITS;
11745 :
11746 : /* 0, or number of decimal digits to keep in last NBASE digit */
11747 248664 : di %= DEC_DIGITS;
11748 :
11749 248664 : if (ndigits < var->ndigits ||
11750 45872 : (ndigits == var->ndigits && di > 0))
11751 : {
11752 206244 : var->ndigits = ndigits;
11753 :
11754 : #if DEC_DIGITS == 1
11755 : /* di must be zero */
11756 : carry = (digits[ndigits] >= HALF_NBASE) ? 1 : 0;
11757 : #else
11758 206244 : if (di == 0)
11759 164370 : carry = (digits[ndigits] >= HALF_NBASE) ? 1 : 0;
11760 : else
11761 : {
11762 : /* Must round within last NBASE digit */
11763 : int extra,
11764 : pow10;
11765 :
11766 : #if DEC_DIGITS == 4
11767 41874 : pow10 = round_powers[di];
11768 : #elif DEC_DIGITS == 2
11769 : pow10 = 10;
11770 : #else
11771 : #error unsupported NBASE
11772 : #endif
11773 41874 : extra = digits[--ndigits] % pow10;
11774 41874 : digits[ndigits] -= extra;
11775 41874 : carry = 0;
11776 41874 : if (extra >= pow10 / 2)
11777 : {
11778 19448 : pow10 += digits[ndigits];
11779 19448 : if (pow10 >= NBASE)
11780 : {
11781 812 : pow10 -= NBASE;
11782 812 : carry = 1;
11783 : }
11784 19448 : digits[ndigits] = pow10;
11785 : }
11786 : }
11787 : #endif
11788 :
11789 : /* Propagate carry if needed */
11790 239866 : while (carry)
11791 : {
11792 33622 : carry += digits[--ndigits];
11793 33622 : if (carry >= NBASE)
11794 : {
11795 24626 : digits[ndigits] = carry - NBASE;
11796 24626 : carry = 1;
11797 : }
11798 : else
11799 : {
11800 8996 : digits[ndigits] = carry;
11801 8996 : carry = 0;
11802 : }
11803 : }
11804 :
11805 206244 : if (ndigits < 0)
11806 : {
11807 : Assert(ndigits == -1); /* better not have added > 1 digit */
11808 : Assert(var->digits > var->buf);
11809 96 : var->digits--;
11810 96 : var->ndigits++;
11811 96 : var->weight++;
11812 : }
11813 : }
11814 : }
11815 248768 : }
11816 :
11817 : /*
11818 : * trunc_var
11819 : *
11820 : * Truncate (towards zero) the value of a variable at rscale decimal digits
11821 : * after the decimal point. NOTE: we allow rscale < 0 here, implying
11822 : * truncation before the decimal point.
11823 : */
11824 : static void
11825 420880 : trunc_var(NumericVar *var, int rscale)
11826 : {
11827 : int di;
11828 : int ndigits;
11829 :
11830 420880 : var->dscale = rscale;
11831 :
11832 : /* decimal digits wanted */
11833 420880 : di = (var->weight + 1) * DEC_DIGITS + rscale;
11834 :
11835 : /*
11836 : * If di <= 0, the value loses all digits.
11837 : */
11838 420880 : if (di <= 0)
11839 : {
11840 90 : var->ndigits = 0;
11841 90 : var->weight = 0;
11842 90 : var->sign = NUMERIC_POS;
11843 : }
11844 : else
11845 : {
11846 : /* NBASE digits wanted */
11847 420790 : ndigits = (di + DEC_DIGITS - 1) / DEC_DIGITS;
11848 :
11849 420790 : if (ndigits <= var->ndigits)
11850 : {
11851 420520 : var->ndigits = ndigits;
11852 :
11853 : #if DEC_DIGITS == 1
11854 : /* no within-digit stuff to worry about */
11855 : #else
11856 : /* 0, or number of decimal digits to keep in last NBASE digit */
11857 420520 : di %= DEC_DIGITS;
11858 :
11859 420520 : if (di > 0)
11860 : {
11861 : /* Must truncate within last NBASE digit */
11862 106 : NumericDigit *digits = var->digits;
11863 : int extra,
11864 : pow10;
11865 :
11866 : #if DEC_DIGITS == 4
11867 106 : pow10 = round_powers[di];
11868 : #elif DEC_DIGITS == 2
11869 : pow10 = 10;
11870 : #else
11871 : #error unsupported NBASE
11872 : #endif
11873 106 : extra = digits[--ndigits] % pow10;
11874 106 : digits[ndigits] -= extra;
11875 : }
11876 : #endif
11877 : }
11878 : }
11879 420880 : }
11880 :
11881 : /*
11882 : * strip_var
11883 : *
11884 : * Strip any leading and trailing zeroes from a numeric variable
11885 : */
11886 : static void
11887 3285004 : strip_var(NumericVar *var)
11888 : {
11889 3285004 : NumericDigit *digits = var->digits;
11890 3285004 : int ndigits = var->ndigits;
11891 :
11892 : /* Strip leading zeroes */
11893 5631116 : while (ndigits > 0 && *digits == 0)
11894 : {
11895 2346112 : digits++;
11896 2346112 : var->weight--;
11897 2346112 : ndigits--;
11898 : }
11899 :
11900 : /* Strip trailing zeroes */
11901 3959360 : while (ndigits > 0 && digits[ndigits - 1] == 0)
11902 674356 : ndigits--;
11903 :
11904 : /* If it's zero, normalize the sign and weight */
11905 3285004 : if (ndigits == 0)
11906 : {
11907 50580 : var->sign = NUMERIC_POS;
11908 50580 : var->weight = 0;
11909 : }
11910 :
11911 3285004 : var->digits = digits;
11912 3285004 : var->ndigits = ndigits;
11913 3285004 : }
11914 :
11915 :
11916 : /* ----------------------------------------------------------------------
11917 : *
11918 : * Fast sum accumulator functions
11919 : *
11920 : * ----------------------------------------------------------------------
11921 : */
11922 :
11923 : /*
11924 : * Reset the accumulator's value to zero. The buffers to hold the digits
11925 : * are not free'd.
11926 : */
11927 : static void
11928 18 : accum_sum_reset(NumericSumAccum *accum)
11929 : {
11930 : int i;
11931 :
11932 18 : accum->dscale = 0;
11933 66 : for (i = 0; i < accum->ndigits; i++)
11934 : {
11935 48 : accum->pos_digits[i] = 0;
11936 48 : accum->neg_digits[i] = 0;
11937 : }
11938 18 : }
11939 :
11940 : /*
11941 : * Accumulate a new value.
11942 : */
11943 : static void
11944 2355704 : accum_sum_add(NumericSumAccum *accum, const NumericVar *val)
11945 : {
11946 : int32 *accum_digits;
11947 : int i,
11948 : val_i;
11949 : int val_ndigits;
11950 : NumericDigit *val_digits;
11951 :
11952 : /*
11953 : * If we have accumulated too many values since the last carry
11954 : * propagation, do it now, to avoid overflowing. (We could allow more
11955 : * than NBASE - 1, if we reserved two extra digits, rather than one, for
11956 : * carry propagation. But even with NBASE - 1, this needs to be done so
11957 : * seldom, that the performance difference is negligible.)
11958 : */
11959 2355704 : if (accum->num_uncarried == NBASE - 1)
11960 168 : accum_sum_carry(accum);
11961 :
11962 : /*
11963 : * Adjust the weight or scale of the old value, so that it can accommodate
11964 : * the new value.
11965 : */
11966 2355704 : accum_sum_rescale(accum, val);
11967 :
11968 : /* */
11969 2355704 : if (val->sign == NUMERIC_POS)
11970 1755026 : accum_digits = accum->pos_digits;
11971 : else
11972 600678 : accum_digits = accum->neg_digits;
11973 :
11974 : /* copy these values into local vars for speed in loop */
11975 2355704 : val_ndigits = val->ndigits;
11976 2355704 : val_digits = val->digits;
11977 :
11978 2355704 : i = accum->weight - val->weight;
11979 11889938 : for (val_i = 0; val_i < val_ndigits; val_i++)
11980 : {
11981 9534234 : accum_digits[i] += (int32) val_digits[val_i];
11982 9534234 : i++;
11983 : }
11984 :
11985 2355704 : accum->num_uncarried++;
11986 2355704 : }
11987 :
11988 : /*
11989 : * Propagate carries.
11990 : */
11991 : static void
11992 172770 : accum_sum_carry(NumericSumAccum *accum)
11993 : {
11994 : int i;
11995 : int ndigits;
11996 : int32 *dig;
11997 : int32 carry;
11998 172770 : int32 newdig = 0;
11999 :
12000 : /*
12001 : * If no new values have been added since last carry propagation, nothing
12002 : * to do.
12003 : */
12004 172770 : if (accum->num_uncarried == 0)
12005 72 : return;
12006 :
12007 : /*
12008 : * We maintain that the weight of the accumulator is always one larger
12009 : * than needed to hold the current value, before carrying, to make sure
12010 : * there is enough space for the possible extra digit when carry is
12011 : * propagated. We cannot expand the buffer here, unless we require
12012 : * callers of accum_sum_final() to switch to the right memory context.
12013 : */
12014 : Assert(accum->pos_digits[0] == 0 && accum->neg_digits[0] == 0);
12015 :
12016 172698 : ndigits = accum->ndigits;
12017 :
12018 : /* Propagate carry in the positive sum */
12019 172698 : dig = accum->pos_digits;
12020 172698 : carry = 0;
12021 2605580 : for (i = ndigits - 1; i >= 0; i--)
12022 : {
12023 2432882 : newdig = dig[i] + carry;
12024 2432882 : if (newdig >= NBASE)
12025 : {
12026 110822 : carry = newdig / NBASE;
12027 110822 : newdig -= carry * NBASE;
12028 : }
12029 : else
12030 2322060 : carry = 0;
12031 2432882 : dig[i] = newdig;
12032 : }
12033 : /* Did we use up the digit reserved for carry propagation? */
12034 172698 : if (newdig > 0)
12035 2638 : accum->have_carry_space = false;
12036 :
12037 : /* And the same for the negative sum */
12038 172698 : dig = accum->neg_digits;
12039 172698 : carry = 0;
12040 2605580 : for (i = ndigits - 1; i >= 0; i--)
12041 : {
12042 2432882 : newdig = dig[i] + carry;
12043 2432882 : if (newdig >= NBASE)
12044 : {
12045 198 : carry = newdig / NBASE;
12046 198 : newdig -= carry * NBASE;
12047 : }
12048 : else
12049 2432684 : carry = 0;
12050 2432882 : dig[i] = newdig;
12051 : }
12052 172698 : if (newdig > 0)
12053 30 : accum->have_carry_space = false;
12054 :
12055 172698 : accum->num_uncarried = 0;
12056 : }
12057 :
12058 : /*
12059 : * Re-scale accumulator to accommodate new value.
12060 : *
12061 : * If the new value has more digits than the current digit buffers in the
12062 : * accumulator, enlarge the buffers.
12063 : */
12064 : static void
12065 2355704 : accum_sum_rescale(NumericSumAccum *accum, const NumericVar *val)
12066 : {
12067 2355704 : int old_weight = accum->weight;
12068 2355704 : int old_ndigits = accum->ndigits;
12069 : int accum_ndigits;
12070 : int accum_weight;
12071 : int accum_rscale;
12072 : int val_rscale;
12073 :
12074 2355704 : accum_weight = old_weight;
12075 2355704 : accum_ndigits = old_ndigits;
12076 :
12077 : /*
12078 : * Does the new value have a larger weight? If so, enlarge the buffers,
12079 : * and shift the existing value to the new weight, by adding leading
12080 : * zeros.
12081 : *
12082 : * We enforce that the accumulator always has a weight one larger than
12083 : * needed for the inputs, so that we have space for an extra digit at the
12084 : * final carry-propagation phase, if necessary.
12085 : */
12086 2355704 : if (val->weight >= accum_weight)
12087 : {
12088 262224 : accum_weight = val->weight + 1;
12089 262224 : accum_ndigits = accum_ndigits + (accum_weight - old_weight);
12090 : }
12091 :
12092 : /*
12093 : * Even though the new value is small, we might've used up the space
12094 : * reserved for the carry digit in the last call to accum_sum_carry(). If
12095 : * so, enlarge to make room for another one.
12096 : */
12097 2093480 : else if (!accum->have_carry_space)
12098 : {
12099 90 : accum_weight++;
12100 90 : accum_ndigits++;
12101 : }
12102 :
12103 : /* Is the new value wider on the right side? */
12104 2355704 : accum_rscale = accum_ndigits - accum_weight - 1;
12105 2355704 : val_rscale = val->ndigits - val->weight - 1;
12106 2355704 : if (val_rscale > accum_rscale)
12107 172246 : accum_ndigits = accum_ndigits + (val_rscale - accum_rscale);
12108 :
12109 2355704 : if (accum_ndigits != old_ndigits ||
12110 : accum_weight != old_weight)
12111 : {
12112 : int32 *new_pos_digits;
12113 : int32 *new_neg_digits;
12114 : int weightdiff;
12115 :
12116 262586 : weightdiff = accum_weight - old_weight;
12117 :
12118 262586 : new_pos_digits = palloc0(accum_ndigits * sizeof(int32));
12119 262586 : new_neg_digits = palloc0(accum_ndigits * sizeof(int32));
12120 :
12121 262586 : if (accum->pos_digits)
12122 : {
12123 90410 : memcpy(&new_pos_digits[weightdiff], accum->pos_digits,
12124 : old_ndigits * sizeof(int32));
12125 90410 : pfree(accum->pos_digits);
12126 :
12127 90410 : memcpy(&new_neg_digits[weightdiff], accum->neg_digits,
12128 : old_ndigits * sizeof(int32));
12129 90410 : pfree(accum->neg_digits);
12130 : }
12131 :
12132 262586 : accum->pos_digits = new_pos_digits;
12133 262586 : accum->neg_digits = new_neg_digits;
12134 :
12135 262586 : accum->weight = accum_weight;
12136 262586 : accum->ndigits = accum_ndigits;
12137 :
12138 : Assert(accum->pos_digits[0] == 0 && accum->neg_digits[0] == 0);
12139 262586 : accum->have_carry_space = true;
12140 : }
12141 :
12142 2355704 : if (val->dscale > accum->dscale)
12143 300 : accum->dscale = val->dscale;
12144 2355704 : }
12145 :
12146 : /*
12147 : * Return the current value of the accumulator. This perform final carry
12148 : * propagation, and adds together the positive and negative sums.
12149 : *
12150 : * Unlike all the other routines, the caller is not required to switch to
12151 : * the memory context that holds the accumulator.
12152 : */
12153 : static void
12154 172602 : accum_sum_final(NumericSumAccum *accum, NumericVar *result)
12155 : {
12156 : int i;
12157 : NumericVar pos_var;
12158 : NumericVar neg_var;
12159 :
12160 172602 : if (accum->ndigits == 0)
12161 : {
12162 0 : set_var_from_var(&const_zero, result);
12163 0 : return;
12164 : }
12165 :
12166 : /* Perform final carry */
12167 172602 : accum_sum_carry(accum);
12168 :
12169 : /* Create NumericVars representing the positive and negative sums */
12170 172602 : init_var(&pos_var);
12171 172602 : init_var(&neg_var);
12172 :
12173 172602 : pos_var.ndigits = neg_var.ndigits = accum->ndigits;
12174 172602 : pos_var.weight = neg_var.weight = accum->weight;
12175 172602 : pos_var.dscale = neg_var.dscale = accum->dscale;
12176 172602 : pos_var.sign = NUMERIC_POS;
12177 172602 : neg_var.sign = NUMERIC_NEG;
12178 :
12179 172602 : pos_var.buf = pos_var.digits = digitbuf_alloc(accum->ndigits);
12180 172602 : neg_var.buf = neg_var.digits = digitbuf_alloc(accum->ndigits);
12181 :
12182 2605102 : for (i = 0; i < accum->ndigits; i++)
12183 : {
12184 : Assert(accum->pos_digits[i] < NBASE);
12185 2432500 : pos_var.digits[i] = (int16) accum->pos_digits[i];
12186 :
12187 : Assert(accum->neg_digits[i] < NBASE);
12188 2432500 : neg_var.digits[i] = (int16) accum->neg_digits[i];
12189 : }
12190 :
12191 : /* And add them together */
12192 172602 : add_var(&pos_var, &neg_var, result);
12193 :
12194 : /* Remove leading/trailing zeroes */
12195 172602 : strip_var(result);
12196 : }
12197 :
12198 : /*
12199 : * Copy an accumulator's state.
12200 : *
12201 : * 'dst' is assumed to be uninitialized beforehand. No attempt is made at
12202 : * freeing old values.
12203 : */
12204 : static void
12205 42 : accum_sum_copy(NumericSumAccum *dst, NumericSumAccum *src)
12206 : {
12207 42 : dst->pos_digits = palloc(src->ndigits * sizeof(int32));
12208 42 : dst->neg_digits = palloc(src->ndigits * sizeof(int32));
12209 :
12210 42 : memcpy(dst->pos_digits, src->pos_digits, src->ndigits * sizeof(int32));
12211 42 : memcpy(dst->neg_digits, src->neg_digits, src->ndigits * sizeof(int32));
12212 42 : dst->num_uncarried = src->num_uncarried;
12213 42 : dst->ndigits = src->ndigits;
12214 42 : dst->weight = src->weight;
12215 42 : dst->dscale = src->dscale;
12216 42 : }
12217 :
12218 : /*
12219 : * Add the current value of 'accum2' into 'accum'.
12220 : */
12221 : static void
12222 48 : accum_sum_combine(NumericSumAccum *accum, NumericSumAccum *accum2)
12223 : {
12224 : NumericVar tmp_var;
12225 :
12226 48 : init_var(&tmp_var);
12227 :
12228 48 : accum_sum_final(accum2, &tmp_var);
12229 48 : accum_sum_add(accum, &tmp_var);
12230 :
12231 48 : free_var(&tmp_var);
12232 48 : }
|