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