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