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