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 99676 : numeric_in(PG_FUNCTION_ARGS)
628 : {
629 99676 : char *str = PG_GETARG_CSTRING(0);
630 : #ifdef NOT_USED
631 : Oid typelem = PG_GETARG_OID(1);
632 : #endif
633 99676 : int32 typmod = PG_GETARG_INT32(2);
634 99676 : Node *escontext = fcinfo->context;
635 : Numeric res;
636 : const char *cp;
637 : const char *numstart;
638 : int sign;
639 :
640 : /* Skip leading spaces */
641 99676 : cp = str;
642 100060 : while (*cp)
643 : {
644 100048 : if (!isspace((unsigned char) *cp))
645 99664 : 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 99676 : numstart = cp;
655 99676 : sign = NUMERIC_POS;
656 :
657 99676 : if (*cp == '+')
658 36 : cp++;
659 99640 : else if (*cp == '-')
660 : {
661 3546 : sign = NUMERIC_NEG;
662 3546 : 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 99676 : 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 1536 : if (pg_strncasecmp(numstart, "NaN", 3) == 0)
679 : {
680 550 : res = make_result(&const_nan);
681 550 : cp = numstart + 3;
682 : }
683 986 : else if (pg_strncasecmp(cp, "Infinity", 8) == 0)
684 : {
685 396 : res = make_result(sign == NUMERIC_POS ? &const_pinf : &const_ninf);
686 396 : 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 1516 : while (*cp)
704 : {
705 42 : if (!isspace((unsigned char) *cp))
706 0 : goto invalid_syntax;
707 42 : cp++;
708 : }
709 :
710 1474 : 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 98140 : 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 98140 : if (cp[0] == '0')
730 : {
731 25366 : 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 25210 : default:
746 25210 : base = 10;
747 : }
748 : }
749 : else
750 72774 : base = 10;
751 :
752 : /* Parse the rest of the number and apply the sign */
753 98140 : if (base == 10)
754 : {
755 97984 : if (!set_var_from_str(str, cp, &value, &cp, escontext))
756 30 : PG_RETURN_NULL();
757 97936 : 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 98152 : while (*cp)
771 : {
772 138 : if (!isspace((unsigned char) *cp))
773 60 : goto invalid_syntax;
774 78 : cp++;
775 : }
776 :
777 98014 : if (!apply_typmod(&value, typmod, escontext))
778 12 : PG_RETURN_NULL();
779 :
780 98002 : res = make_result_opt_error(&value, &have_error);
781 :
782 98002 : 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 97984 : free_var(&value);
788 : }
789 :
790 99458 : 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 779258 : numeric_out(PG_FUNCTION_ARGS)
807 : {
808 779258 : Numeric num = PG_GETARG_NUMERIC(0);
809 : NumericVar x;
810 : char *str;
811 :
812 : /*
813 : * Handle NaN and infinities
814 : */
815 779258 : if (NUMERIC_IS_SPECIAL(num))
816 : {
817 3504 : if (NUMERIC_IS_PINF(num))
818 998 : PG_RETURN_CSTRING(pstrdup("Infinity"));
819 2506 : else if (NUMERIC_IS_NINF(num))
820 616 : 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 775754 : init_var_from_num(num, &x);
829 :
830 775754 : str = get_str_from_var(&x);
831 :
832 775754 : PG_RETURN_CSTRING(str);
833 : }
834 :
835 : /*
836 : * numeric_is_nan() -
837 : *
838 : * Is Numeric value a NaN?
839 : */
840 : bool
841 13208 : numeric_is_nan(Numeric num)
842 : {
843 13208 : 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 123500 : is_valid_numeric_typmod(int32 typmod)
907 : {
908 123500 : 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 24646 : numeric_typmod_precision(int32 typmod)
918 : {
919 24646 : 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 17064 : numeric_typmod_scale(int32 typmod)
933 : {
934 17064 : 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 7582 : numeric_maximum_size(int32 typmod)
944 : {
945 : int precision;
946 : int numeric_digits;
947 :
948 7582 : if (!is_valid_numeric_typmod(typmod))
949 0 : return -1;
950 :
951 : /* precision (ie, max # of digits) is in upper bits of typmod */
952 7582 : 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 7582 : 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 7582 : 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 12966 : numeric_normalize(Numeric num)
1017 : {
1018 : NumericVar x;
1019 : char *str;
1020 : int last;
1021 :
1022 : /*
1023 : * Handle NaN and infinities
1024 : */
1025 12966 : 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 12966 : init_var_from_num(num, &x);
1036 :
1037 12966 : str = get_str_from_var(&x);
1038 :
1039 : /* If there's no decimal point, there's certainly nothing to remove. */
1040 12966 : 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 12966 : 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 7132 : && (NUMERIC_CAN_BE_SHORT(dscale, NUMERIC_WEIGHT(num))
1285 0 : || !NUMERIC_IS_SHORT(num)))
1286 : {
1287 7132 : new = duplicate_numeric(num);
1288 7132 : if (NUMERIC_IS_SHORT(num))
1289 7132 : new->choice.n_short.n_header =
1290 7132 : (num->choice.n_short.n_header & ~NUMERIC_SHORT_DSCALE_MASK)
1291 7132 : | (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 7132 : 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 4448 : init_var(&var);
1303 :
1304 4448 : set_var_from_num(num, &var);
1305 4448 : (void) apply_typmod(&var, typmod, NULL);
1306 4388 : new = make_result(&var);
1307 :
1308 4388 : free_var(&var);
1309 :
1310 4388 : 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 498 : numeric_uplus(PG_FUNCTION_ARGS)
1453 : {
1454 498 : Numeric num = PG_GETARG_NUMERIC(0);
1455 :
1456 498 : 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 946 : numeric_sortsupport(PG_FUNCTION_ARGS)
2005 : {
2006 946 : SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
2007 :
2008 946 : ssup->comparator = numeric_fast_cmp;
2009 :
2010 946 : 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 946 : 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 4562398 : numeric_fast_cmp(Datum x, Datum y, SortSupport ssup)
2181 : {
2182 4562398 : Numeric nx = DatumGetNumeric(x);
2183 4562398 : Numeric ny = DatumGetNumeric(y);
2184 : int result;
2185 :
2186 4562398 : result = cmp_numerics(nx, ny);
2187 :
2188 4562398 : if ((Pointer) nx != DatumGetPointer(x))
2189 172662 : pfree(nx);
2190 4562398 : if ((Pointer) ny != DatumGetPointer(y))
2191 172656 : pfree(ny);
2192 :
2193 4562398 : 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 120 : return 1;
2210 806 : if (DatumGetNumericAbbrev(x) > DatumGetNumericAbbrev(y))
2211 740 : 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 757436 : numeric_cmp(PG_FUNCTION_ARGS)
2399 : {
2400 757436 : Numeric num1 = PG_GETARG_NUMERIC(0);
2401 757436 : Numeric num2 = PG_GETARG_NUMERIC(1);
2402 : int result;
2403 :
2404 757436 : result = cmp_numerics(num1, num2);
2405 :
2406 757436 : PG_FREE_IF_COPY(num1, 0);
2407 757436 : PG_FREE_IF_COPY(num2, 1);
2408 :
2409 757436 : PG_RETURN_INT32(result);
2410 : }
2411 :
2412 :
2413 : Datum
2414 603454 : numeric_eq(PG_FUNCTION_ARGS)
2415 : {
2416 603454 : Numeric num1 = PG_GETARG_NUMERIC(0);
2417 603454 : Numeric num2 = PG_GETARG_NUMERIC(1);
2418 : bool result;
2419 :
2420 603454 : result = cmp_numerics(num1, num2) == 0;
2421 :
2422 603454 : PG_FREE_IF_COPY(num1, 0);
2423 603454 : PG_FREE_IF_COPY(num2, 1);
2424 :
2425 603454 : 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 37268 : numeric_gt(PG_FUNCTION_ARGS)
2445 : {
2446 37268 : Numeric num1 = PG_GETARG_NUMERIC(0);
2447 37268 : Numeric num2 = PG_GETARG_NUMERIC(1);
2448 : bool result;
2449 :
2450 37268 : result = cmp_numerics(num1, num2) > 0;
2451 :
2452 37268 : PG_FREE_IF_COPY(num1, 0);
2453 37268 : PG_FREE_IF_COPY(num2, 1);
2454 :
2455 37268 : PG_RETURN_BOOL(result);
2456 : }
2457 :
2458 : Datum
2459 16744 : numeric_ge(PG_FUNCTION_ARGS)
2460 : {
2461 16744 : Numeric num1 = PG_GETARG_NUMERIC(0);
2462 16744 : Numeric num2 = PG_GETARG_NUMERIC(1);
2463 : bool result;
2464 :
2465 16744 : result = cmp_numerics(num1, num2) >= 0;
2466 :
2467 16744 : PG_FREE_IF_COPY(num1, 0);
2468 16744 : PG_FREE_IF_COPY(num2, 1);
2469 :
2470 16744 : PG_RETURN_BOOL(result);
2471 : }
2472 :
2473 : Datum
2474 28558 : numeric_lt(PG_FUNCTION_ARGS)
2475 : {
2476 28558 : Numeric num1 = PG_GETARG_NUMERIC(0);
2477 28558 : Numeric num2 = PG_GETARG_NUMERIC(1);
2478 : bool result;
2479 :
2480 28558 : result = cmp_numerics(num1, num2) < 0;
2481 :
2482 28558 : PG_FREE_IF_COPY(num1, 0);
2483 28558 : PG_FREE_IF_COPY(num2, 1);
2484 :
2485 28558 : PG_RETURN_BOOL(result);
2486 : }
2487 :
2488 : Datum
2489 15488 : numeric_le(PG_FUNCTION_ARGS)
2490 : {
2491 15488 : Numeric num1 = PG_GETARG_NUMERIC(0);
2492 15488 : Numeric num2 = PG_GETARG_NUMERIC(1);
2493 : bool result;
2494 :
2495 15488 : result = cmp_numerics(num1, num2) <= 0;
2496 :
2497 15488 : PG_FREE_IF_COPY(num1, 0);
2498 15488 : PG_FREE_IF_COPY(num2, 1);
2499 :
2500 15488 : PG_RETURN_BOOL(result);
2501 : }
2502 :
2503 : static int
2504 6029020 : 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 6029020 : if (NUMERIC_IS_SPECIAL(num1))
2514 : {
2515 9372 : if (NUMERIC_IS_NAN(num1))
2516 : {
2517 9282 : if (NUMERIC_IS_NAN(num2))
2518 1342 : result = 0; /* NAN = NAN */
2519 : else
2520 7940 : 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 6019648 : else if (NUMERIC_IS_SPECIAL(num2))
2540 : {
2541 11282 : if (NUMERIC_IS_NINF(num2))
2542 12 : result = 1; /* normal > NINF */
2543 : else
2544 11270 : result = -1; /* normal < NAN or PINF */
2545 : }
2546 : else
2547 : {
2548 12017820 : result = cmp_var_common(NUMERIC_DIGITS(num1), NUMERIC_NDIGITS(num1),
2549 6008686 : NUMERIC_WEIGHT(num1), NUMERIC_SIGN(num1),
2550 6008366 : NUMERIC_DIGITS(num2), NUMERIC_NDIGITS(num2),
2551 6009134 : NUMERIC_WEIGHT(num2), NUMERIC_SIGN(num2));
2552 : }
2553 :
2554 6029020 : 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 592034 : hash_numeric(PG_FUNCTION_ARGS)
2697 : {
2698 592034 : 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 592034 : if (NUMERIC_IS_SPECIAL(key))
2710 0 : PG_RETURN_UINT32(0);
2711 :
2712 592034 : weight = NUMERIC_WEIGHT(key);
2713 592034 : start_offset = 0;
2714 592034 : 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 592034 : digits = NUMERIC_DIGITS(key);
2723 592034 : for (i = 0; i < NUMERIC_NDIGITS(key); i++)
2724 : {
2725 590540 : if (digits[i] != (NumericDigit) 0)
2726 590540 : 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 592034 : if (NUMERIC_NDIGITS(key) == start_offset)
2742 1494 : PG_RETURN_UINT32(-1);
2743 :
2744 590540 : for (i = NUMERIC_NDIGITS(key) - 1; i >= 0; i--)
2745 : {
2746 590540 : if (digits[i] != (NumericDigit) 0)
2747 590540 : 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 590540 : hash_len = NUMERIC_NDIGITS(key) - start_offset - end_offset;
2762 590540 : 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 590540 : result = digit_hash ^ weight;
2767 :
2768 590540 : 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 252032 : numeric_add(PG_FUNCTION_ARGS)
2848 : {
2849 252032 : Numeric num1 = PG_GETARG_NUMERIC(0);
2850 252032 : Numeric num2 = PG_GETARG_NUMERIC(1);
2851 : Numeric res;
2852 :
2853 252032 : res = numeric_add_opt_error(num1, num2, NULL);
2854 :
2855 252032 : 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 252878 : 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 252878 : 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 252680 : init_var_from_num(num1, &arg1);
2905 252680 : init_var_from_num(num2, &arg2);
2906 :
2907 252680 : init_var(&result);
2908 252680 : add_var(&arg1, &arg2, &result);
2909 :
2910 252680 : res = make_result_opt_error(&result, have_error);
2911 :
2912 252680 : free_var(&result);
2913 :
2914 252680 : return res;
2915 : }
2916 :
2917 :
2918 : /*
2919 : * numeric_sub() -
2920 : *
2921 : * Subtract one numeric from another
2922 : */
2923 : Datum
2924 55846 : numeric_sub(PG_FUNCTION_ARGS)
2925 : {
2926 55846 : Numeric num1 = PG_GETARG_NUMERIC(0);
2927 55846 : Numeric num2 = PG_GETARG_NUMERIC(1);
2928 : Numeric res;
2929 :
2930 55846 : res = numeric_sub_opt_error(num1, num2, NULL);
2931 :
2932 55846 : 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 55900 : 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 55900 : if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
2955 : {
2956 2470 : if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2957 2350 : 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 53430 : init_var_from_num(num1, &arg1);
2983 53430 : init_var_from_num(num2, &arg2);
2984 :
2985 53430 : init_var(&result);
2986 53430 : sub_var(&arg1, &arg2, &result);
2987 :
2988 53430 : res = make_result_opt_error(&result, have_error);
2989 :
2990 53430 : free_var(&result);
2991 :
2992 53430 : 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 121050 : numeric_div(PG_FUNCTION_ARGS)
3124 : {
3125 121050 : Numeric num1 = PG_GETARG_NUMERIC(0);
3126 121050 : Numeric num2 = PG_GETARG_NUMERIC(1);
3127 : Numeric res;
3128 :
3129 121050 : res = numeric_div_opt_error(num1, num2, NULL);
3130 :
3131 121018 : 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 121890 : 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 121890 : if (have_error)
3152 48 : *have_error = false;
3153 :
3154 : /*
3155 : * Handle NaN and infinities
3156 : */
3157 121890 : 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 121692 : init_var_from_num(num1, &arg1);
3221 121692 : init_var_from_num(num2, &arg2);
3222 :
3223 121692 : init_var(&result);
3224 :
3225 : /*
3226 : * Select scale for division result
3227 : */
3228 121692 : rscale = select_div_scale(&arg1, &arg2);
3229 :
3230 : /*
3231 : * If "have_error" is provided, check for division by zero here
3232 : */
3233 121692 : 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 121680 : div_var(&arg1, &arg2, &result, rscale, true);
3243 :
3244 121642 : res = make_result_opt_error(&result, have_error);
3245 :
3246 121642 : free_var(&result);
3247 :
3248 121642 : 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 54180 : numeric_mod(PG_FUNCTION_ARGS)
3348 : {
3349 54180 : Numeric num1 = PG_GETARG_NUMERIC(0);
3350 54180 : Numeric num2 = PG_GETARG_NUMERIC(1);
3351 : Numeric res;
3352 :
3353 54180 : res = numeric_mod_opt_error(num1, num2, NULL);
3354 :
3355 54162 : 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 54192 : 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 54192 : 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 54192 : 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 53994 : init_var_from_num(num1, &arg1);
3407 53994 : init_var_from_num(num2, &arg2);
3408 :
3409 53994 : init_var(&result);
3410 :
3411 : /*
3412 : * If "have_error" is provided, check for division by zero here
3413 : */
3414 53994 : if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
3415 : {
3416 0 : *have_error = true;
3417 0 : return NULL;
3418 : }
3419 :
3420 53994 : mod_var(&arg1, &arg2, &result);
3421 :
3422 53982 : res = make_result_opt_error(&result, NULL);
3423 :
3424 53982 : free_var(&result);
3425 :
3426 53982 : 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 1816410 : int64_to_numeric(int64 val)
4233 : {
4234 : Numeric res;
4235 : NumericVar result;
4236 :
4237 1816410 : init_var(&result);
4238 :
4239 1816410 : int64_to_numericvar(val, &result);
4240 :
4241 1816410 : res = make_result(&result);
4242 :
4243 1816410 : free_var(&result);
4244 :
4245 1816410 : 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 1523424 : int4_numeric(PG_FUNCTION_ARGS)
4339 : {
4340 1523424 : int32 val = PG_GETARG_INT32(0);
4341 :
4342 1523424 : PG_RETURN_NUMERIC(int64_to_numeric(val));
4343 : }
4344 :
4345 : int32
4346 7228 : numeric_int4_opt_error(Numeric num, bool *have_error)
4347 : {
4348 : NumericVar x;
4349 : int32 result;
4350 :
4351 7228 : if (have_error)
4352 288 : *have_error = false;
4353 :
4354 7228 : 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 7210 : init_var_from_num(num, &x);
4376 :
4377 7210 : 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 7174 : return result;
4393 : }
4394 :
4395 : Datum
4396 6940 : numeric_int4(PG_FUNCTION_ARGS)
4397 : {
4398 6940 : Numeric num = PG_GETARG_NUMERIC(0);
4399 :
4400 6940 : 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 7948 : numericvar_to_int32(const NumericVar *var, int32 *result)
4410 : {
4411 : int64 val;
4412 :
4413 7948 : if (!numericvar_to_int64(var, &val))
4414 0 : return false;
4415 :
4416 7948 : if (unlikely(val < PG_INT32_MIN) || unlikely(val > PG_INT32_MAX))
4417 36 : return false;
4418 :
4419 : /* Down-convert to int4 */
4420 7912 : *result = (int32) val;
4421 :
4422 7912 : return true;
4423 : }
4424 :
4425 : Datum
4426 12764 : int8_numeric(PG_FUNCTION_ARGS)
4427 : {
4428 12764 : int64 val = PG_GETARG_INT64(0);
4429 :
4430 12764 : 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 519080 : numeric_float8(PG_FUNCTION_ARGS)
4551 : {
4552 519080 : Numeric num = PG_GETARG_NUMERIC(0);
4553 : char *tmp;
4554 : Datum result;
4555 :
4556 519080 : 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 519002 : tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
4567 : NumericGetDatum(num)));
4568 :
4569 519002 : result = DirectFunctionCall1(float8in, CStringGetDatum(tmp));
4570 :
4571 519002 : pfree(tmp);
4572 :
4573 519002 : 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 2868 : numeric_float8_no_overflow(PG_FUNCTION_ARGS)
4584 : {
4585 2868 : Numeric num = PG_GETARG_NUMERIC(0);
4586 : double val;
4587 :
4588 2868 : 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 2868 : init_var_from_num(num, &x);
4602 2868 : val = numericvar_to_double_no_overflow(&x);
4603 : }
4604 :
4605 2868 : PG_RETURN_FLOAT8(val);
4606 : }
4607 :
4608 : Datum
4609 21644 : float4_numeric(PG_FUNCTION_ARGS)
4610 : {
4611 21644 : float4 val = PG_GETARG_FLOAT4(0);
4612 : Numeric res;
4613 : NumericVar result;
4614 : char buf[FLT_DIG + 100];
4615 : const char *endptr;
4616 :
4617 21644 : if (isnan(val))
4618 6 : PG_RETURN_NUMERIC(make_result(&const_nan));
4619 :
4620 21638 : 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 21626 : snprintf(buf, sizeof(buf), "%.*g", FLT_DIG, val);
4629 :
4630 21626 : init_var(&result);
4631 :
4632 : /* Assume we need not worry about leading/trailing spaces */
4633 21626 : (void) set_var_from_str(buf, buf, &result, &endptr, NULL);
4634 :
4635 21626 : res = make_result(&result);
4636 :
4637 21626 : free_var(&result);
4638 :
4639 21626 : 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 120 : numeric_pg_lsn(PG_FUNCTION_ARGS)
4673 : {
4674 120 : Numeric num = PG_GETARG_NUMERIC(0);
4675 : NumericVar x;
4676 : XLogRecPtr result;
4677 :
4678 120 : 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 114 : init_var_from_num(num, &x);
4692 :
4693 114 : 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 90 : 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 : * Initialize a StringInfo so that we can "receive" it using the standard
5194 : * recv-function infrastructure.
5195 : */
5196 14 : initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
5197 14 : VARSIZE_ANY_EXHDR(sstate));
5198 :
5199 14 : result = makeNumericAggStateCurrentContext(false);
5200 :
5201 : /* N */
5202 14 : result->N = pq_getmsgint64(&buf);
5203 :
5204 : /* sumX */
5205 14 : numericvar_deserialize(&buf, &tmp_var);
5206 14 : accum_sum_add(&(result->sumX), &tmp_var);
5207 :
5208 : /* maxScale */
5209 14 : result->maxScale = pq_getmsgint(&buf, 4);
5210 :
5211 : /* maxScaleCount */
5212 14 : result->maxScaleCount = pq_getmsgint64(&buf);
5213 :
5214 : /* NaNcount */
5215 14 : result->NaNcount = pq_getmsgint64(&buf);
5216 :
5217 : /* pInfcount */
5218 14 : result->pInfcount = pq_getmsgint64(&buf);
5219 :
5220 : /* nInfcount */
5221 14 : result->nInfcount = pq_getmsgint64(&buf);
5222 :
5223 14 : pq_getmsgend(&buf);
5224 :
5225 14 : free_var(&tmp_var);
5226 :
5227 14 : PG_RETURN_POINTER(result);
5228 : }
5229 :
5230 : /*
5231 : * numeric_serialize
5232 : * Serialization function for NumericAggState for numeric aggregates that
5233 : * require sumX2.
5234 : */
5235 : Datum
5236 26 : numeric_serialize(PG_FUNCTION_ARGS)
5237 : {
5238 : NumericAggState *state;
5239 : StringInfoData buf;
5240 : bytea *result;
5241 : NumericVar tmp_var;
5242 :
5243 : /* Ensure we disallow calling when not in aggregate context */
5244 26 : if (!AggCheckCallContext(fcinfo, NULL))
5245 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5246 :
5247 26 : state = (NumericAggState *) PG_GETARG_POINTER(0);
5248 :
5249 26 : init_var(&tmp_var);
5250 :
5251 26 : pq_begintypsend(&buf);
5252 :
5253 : /* N */
5254 26 : pq_sendint64(&buf, state->N);
5255 :
5256 : /* sumX */
5257 26 : accum_sum_final(&state->sumX, &tmp_var);
5258 26 : numericvar_serialize(&buf, &tmp_var);
5259 :
5260 : /* sumX2 */
5261 26 : accum_sum_final(&state->sumX2, &tmp_var);
5262 26 : numericvar_serialize(&buf, &tmp_var);
5263 :
5264 : /* maxScale */
5265 26 : pq_sendint32(&buf, state->maxScale);
5266 :
5267 : /* maxScaleCount */
5268 26 : pq_sendint64(&buf, state->maxScaleCount);
5269 :
5270 : /* NaNcount */
5271 26 : pq_sendint64(&buf, state->NaNcount);
5272 :
5273 : /* pInfcount */
5274 26 : pq_sendint64(&buf, state->pInfcount);
5275 :
5276 : /* nInfcount */
5277 26 : pq_sendint64(&buf, state->nInfcount);
5278 :
5279 26 : result = pq_endtypsend(&buf);
5280 :
5281 26 : free_var(&tmp_var);
5282 :
5283 26 : PG_RETURN_BYTEA_P(result);
5284 : }
5285 :
5286 : /*
5287 : * numeric_deserialize
5288 : * Deserialization function for NumericAggState for numeric aggregates that
5289 : * require sumX2.
5290 : */
5291 : Datum
5292 26 : numeric_deserialize(PG_FUNCTION_ARGS)
5293 : {
5294 : bytea *sstate;
5295 : NumericAggState *result;
5296 : StringInfoData buf;
5297 : NumericVar tmp_var;
5298 :
5299 26 : if (!AggCheckCallContext(fcinfo, NULL))
5300 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5301 :
5302 26 : sstate = PG_GETARG_BYTEA_PP(0);
5303 :
5304 26 : init_var(&tmp_var);
5305 :
5306 : /*
5307 : * Initialize a StringInfo so that we can "receive" it using the standard
5308 : * recv-function infrastructure.
5309 : */
5310 26 : initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
5311 26 : VARSIZE_ANY_EXHDR(sstate));
5312 :
5313 26 : result = makeNumericAggStateCurrentContext(false);
5314 :
5315 : /* N */
5316 26 : result->N = pq_getmsgint64(&buf);
5317 :
5318 : /* sumX */
5319 26 : numericvar_deserialize(&buf, &tmp_var);
5320 26 : accum_sum_add(&(result->sumX), &tmp_var);
5321 :
5322 : /* sumX2 */
5323 26 : numericvar_deserialize(&buf, &tmp_var);
5324 26 : accum_sum_add(&(result->sumX2), &tmp_var);
5325 :
5326 : /* maxScale */
5327 26 : result->maxScale = pq_getmsgint(&buf, 4);
5328 :
5329 : /* maxScaleCount */
5330 26 : result->maxScaleCount = pq_getmsgint64(&buf);
5331 :
5332 : /* NaNcount */
5333 26 : result->NaNcount = pq_getmsgint64(&buf);
5334 :
5335 : /* pInfcount */
5336 26 : result->pInfcount = pq_getmsgint64(&buf);
5337 :
5338 : /* nInfcount */
5339 26 : result->nInfcount = pq_getmsgint64(&buf);
5340 :
5341 26 : pq_getmsgend(&buf);
5342 :
5343 26 : free_var(&tmp_var);
5344 :
5345 26 : PG_RETURN_POINTER(result);
5346 : }
5347 :
5348 : /*
5349 : * Generic inverse transition function for numeric aggregates
5350 : * (with or without requirement for X^2).
5351 : */
5352 : Datum
5353 228 : numeric_accum_inv(PG_FUNCTION_ARGS)
5354 : {
5355 : NumericAggState *state;
5356 :
5357 228 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
5358 :
5359 : /* Should not get here with no state */
5360 228 : if (state == NULL)
5361 0 : elog(ERROR, "numeric_accum_inv called with NULL state");
5362 :
5363 228 : if (!PG_ARGISNULL(1))
5364 : {
5365 : /* If we fail to perform the inverse transition, return NULL */
5366 198 : if (!do_numeric_discard(state, PG_GETARG_NUMERIC(1)))
5367 6 : PG_RETURN_NULL();
5368 : }
5369 :
5370 222 : PG_RETURN_POINTER(state);
5371 : }
5372 :
5373 :
5374 : /*
5375 : * Integer data types in general use Numeric accumulators to share code
5376 : * and avoid risk of overflow.
5377 : *
5378 : * However for performance reasons optimized special-purpose accumulator
5379 : * routines are used when possible.
5380 : *
5381 : * On platforms with 128-bit integer support, the 128-bit routines will be
5382 : * used when sum(X) or sum(X*X) fit into 128-bit.
5383 : *
5384 : * For 16 and 32 bit inputs, the N and sum(X) fit into 64-bit so the 64-bit
5385 : * accumulators will be used for SUM and AVG of these data types.
5386 : */
5387 :
5388 : #ifdef HAVE_INT128
5389 : typedef struct Int128AggState
5390 : {
5391 : bool calcSumX2; /* if true, calculate sumX2 */
5392 : int64 N; /* count of processed numbers */
5393 : int128 sumX; /* sum of processed numbers */
5394 : int128 sumX2; /* sum of squares of processed numbers */
5395 : } Int128AggState;
5396 :
5397 : /*
5398 : * Prepare state data for a 128-bit aggregate function that needs to compute
5399 : * sum, count and optionally sum of squares of the input.
5400 : */
5401 : static Int128AggState *
5402 662 : makeInt128AggState(FunctionCallInfo fcinfo, bool calcSumX2)
5403 : {
5404 : Int128AggState *state;
5405 : MemoryContext agg_context;
5406 : MemoryContext old_context;
5407 :
5408 662 : if (!AggCheckCallContext(fcinfo, &agg_context))
5409 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5410 :
5411 662 : old_context = MemoryContextSwitchTo(agg_context);
5412 :
5413 662 : state = (Int128AggState *) palloc0(sizeof(Int128AggState));
5414 662 : state->calcSumX2 = calcSumX2;
5415 :
5416 662 : MemoryContextSwitchTo(old_context);
5417 :
5418 662 : return state;
5419 : }
5420 :
5421 : /*
5422 : * Like makeInt128AggState(), but allocate the state in the current memory
5423 : * context.
5424 : */
5425 : static Int128AggState *
5426 26 : makeInt128AggStateCurrentContext(bool calcSumX2)
5427 : {
5428 : Int128AggState *state;
5429 :
5430 26 : state = (Int128AggState *) palloc0(sizeof(Int128AggState));
5431 26 : state->calcSumX2 = calcSumX2;
5432 :
5433 26 : return state;
5434 : }
5435 :
5436 : /*
5437 : * Accumulate a new input value for 128-bit aggregate functions.
5438 : */
5439 : static void
5440 552946 : do_int128_accum(Int128AggState *state, int128 newval)
5441 : {
5442 552946 : if (state->calcSumX2)
5443 242360 : state->sumX2 += newval * newval;
5444 :
5445 552946 : state->sumX += newval;
5446 552946 : state->N++;
5447 552946 : }
5448 :
5449 : /*
5450 : * Remove an input value from the aggregated state.
5451 : */
5452 : static void
5453 312 : do_int128_discard(Int128AggState *state, int128 newval)
5454 : {
5455 312 : if (state->calcSumX2)
5456 288 : state->sumX2 -= newval * newval;
5457 :
5458 312 : state->sumX -= newval;
5459 312 : state->N--;
5460 312 : }
5461 :
5462 : typedef Int128AggState PolyNumAggState;
5463 : #define makePolyNumAggState makeInt128AggState
5464 : #define makePolyNumAggStateCurrentContext makeInt128AggStateCurrentContext
5465 : #else
5466 : typedef NumericAggState PolyNumAggState;
5467 : #define makePolyNumAggState makeNumericAggState
5468 : #define makePolyNumAggStateCurrentContext makeNumericAggStateCurrentContext
5469 : #endif
5470 :
5471 : Datum
5472 198 : int2_accum(PG_FUNCTION_ARGS)
5473 : {
5474 : PolyNumAggState *state;
5475 :
5476 198 : state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
5477 :
5478 : /* Create the state data on the first call */
5479 198 : if (state == NULL)
5480 36 : state = makePolyNumAggState(fcinfo, true);
5481 :
5482 198 : if (!PG_ARGISNULL(1))
5483 : {
5484 : #ifdef HAVE_INT128
5485 180 : do_int128_accum(state, (int128) PG_GETARG_INT16(1));
5486 : #else
5487 : do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT16(1)));
5488 : #endif
5489 : }
5490 :
5491 198 : PG_RETURN_POINTER(state);
5492 : }
5493 :
5494 : Datum
5495 242198 : int4_accum(PG_FUNCTION_ARGS)
5496 : {
5497 : PolyNumAggState *state;
5498 :
5499 242198 : state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
5500 :
5501 : /* Create the state data on the first call */
5502 242198 : if (state == NULL)
5503 66 : state = makePolyNumAggState(fcinfo, true);
5504 :
5505 242198 : if (!PG_ARGISNULL(1))
5506 : {
5507 : #ifdef HAVE_INT128
5508 242180 : do_int128_accum(state, (int128) PG_GETARG_INT32(1));
5509 : #else
5510 : do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT32(1)));
5511 : #endif
5512 : }
5513 :
5514 242198 : PG_RETURN_POINTER(state);
5515 : }
5516 :
5517 : Datum
5518 240198 : int8_accum(PG_FUNCTION_ARGS)
5519 : {
5520 : NumericAggState *state;
5521 :
5522 240198 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
5523 :
5524 : /* Create the state data on the first call */
5525 240198 : if (state == NULL)
5526 50 : state = makeNumericAggState(fcinfo, true);
5527 :
5528 240198 : if (!PG_ARGISNULL(1))
5529 240180 : do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT64(1)));
5530 :
5531 240198 : PG_RETURN_POINTER(state);
5532 : }
5533 :
5534 : /*
5535 : * Combine function for numeric aggregates which require sumX2
5536 : */
5537 : Datum
5538 10 : numeric_poly_combine(PG_FUNCTION_ARGS)
5539 : {
5540 : PolyNumAggState *state1;
5541 : PolyNumAggState *state2;
5542 : MemoryContext agg_context;
5543 : MemoryContext old_context;
5544 :
5545 10 : if (!AggCheckCallContext(fcinfo, &agg_context))
5546 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5547 :
5548 10 : state1 = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
5549 10 : state2 = PG_ARGISNULL(1) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(1);
5550 :
5551 10 : if (state2 == NULL)
5552 0 : PG_RETURN_POINTER(state1);
5553 :
5554 : /* manually copy all fields from state2 to state1 */
5555 10 : if (state1 == NULL)
5556 : {
5557 6 : old_context = MemoryContextSwitchTo(agg_context);
5558 :
5559 6 : state1 = makePolyNumAggState(fcinfo, true);
5560 6 : state1->N = state2->N;
5561 :
5562 : #ifdef HAVE_INT128
5563 6 : state1->sumX = state2->sumX;
5564 6 : state1->sumX2 = state2->sumX2;
5565 : #else
5566 : accum_sum_copy(&state1->sumX, &state2->sumX);
5567 : accum_sum_copy(&state1->sumX2, &state2->sumX2);
5568 : #endif
5569 :
5570 6 : MemoryContextSwitchTo(old_context);
5571 :
5572 6 : PG_RETURN_POINTER(state1);
5573 : }
5574 :
5575 4 : if (state2->N > 0)
5576 : {
5577 4 : state1->N += state2->N;
5578 :
5579 : #ifdef HAVE_INT128
5580 4 : state1->sumX += state2->sumX;
5581 4 : state1->sumX2 += state2->sumX2;
5582 : #else
5583 : /* The rest of this needs to work in the aggregate context */
5584 : old_context = MemoryContextSwitchTo(agg_context);
5585 :
5586 : /* Accumulate sums */
5587 : accum_sum_combine(&state1->sumX, &state2->sumX);
5588 : accum_sum_combine(&state1->sumX2, &state2->sumX2);
5589 :
5590 : MemoryContextSwitchTo(old_context);
5591 : #endif
5592 :
5593 : }
5594 4 : PG_RETURN_POINTER(state1);
5595 : }
5596 :
5597 : /*
5598 : * numeric_poly_serialize
5599 : * Serialize PolyNumAggState into bytea for aggregate functions which
5600 : * require sumX2.
5601 : */
5602 : Datum
5603 10 : numeric_poly_serialize(PG_FUNCTION_ARGS)
5604 : {
5605 : PolyNumAggState *state;
5606 : StringInfoData buf;
5607 : bytea *result;
5608 : NumericVar tmp_var;
5609 :
5610 : /* Ensure we disallow calling when not in aggregate context */
5611 10 : if (!AggCheckCallContext(fcinfo, NULL))
5612 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5613 :
5614 10 : state = (PolyNumAggState *) PG_GETARG_POINTER(0);
5615 :
5616 : /*
5617 : * If the platform supports int128 then sumX and sumX2 will be a 128 bit
5618 : * integer type. Here we'll convert that into a numeric type so that the
5619 : * combine state is in the same format for both int128 enabled machines
5620 : * and machines which don't support that type. The logic here is that one
5621 : * day we might like to send these over to another server for further
5622 : * processing and we want a standard format to work with.
5623 : */
5624 :
5625 10 : init_var(&tmp_var);
5626 :
5627 10 : pq_begintypsend(&buf);
5628 :
5629 : /* N */
5630 10 : pq_sendint64(&buf, state->N);
5631 :
5632 : /* sumX */
5633 : #ifdef HAVE_INT128
5634 10 : int128_to_numericvar(state->sumX, &tmp_var);
5635 : #else
5636 : accum_sum_final(&state->sumX, &tmp_var);
5637 : #endif
5638 10 : numericvar_serialize(&buf, &tmp_var);
5639 :
5640 : /* sumX2 */
5641 : #ifdef HAVE_INT128
5642 10 : int128_to_numericvar(state->sumX2, &tmp_var);
5643 : #else
5644 : accum_sum_final(&state->sumX2, &tmp_var);
5645 : #endif
5646 10 : numericvar_serialize(&buf, &tmp_var);
5647 :
5648 10 : result = pq_endtypsend(&buf);
5649 :
5650 10 : free_var(&tmp_var);
5651 :
5652 10 : PG_RETURN_BYTEA_P(result);
5653 : }
5654 :
5655 : /*
5656 : * numeric_poly_deserialize
5657 : * Deserialize PolyNumAggState from bytea for aggregate functions which
5658 : * require sumX2.
5659 : */
5660 : Datum
5661 10 : numeric_poly_deserialize(PG_FUNCTION_ARGS)
5662 : {
5663 : bytea *sstate;
5664 : PolyNumAggState *result;
5665 : StringInfoData buf;
5666 : NumericVar tmp_var;
5667 :
5668 10 : if (!AggCheckCallContext(fcinfo, NULL))
5669 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5670 :
5671 10 : sstate = PG_GETARG_BYTEA_PP(0);
5672 :
5673 10 : init_var(&tmp_var);
5674 :
5675 : /*
5676 : * Initialize a StringInfo so that we can "receive" it using the standard
5677 : * recv-function infrastructure.
5678 : */
5679 10 : initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
5680 10 : VARSIZE_ANY_EXHDR(sstate));
5681 :
5682 10 : result = makePolyNumAggStateCurrentContext(false);
5683 :
5684 : /* N */
5685 10 : result->N = pq_getmsgint64(&buf);
5686 :
5687 : /* sumX */
5688 10 : numericvar_deserialize(&buf, &tmp_var);
5689 : #ifdef HAVE_INT128
5690 10 : numericvar_to_int128(&tmp_var, &result->sumX);
5691 : #else
5692 : accum_sum_add(&result->sumX, &tmp_var);
5693 : #endif
5694 :
5695 : /* sumX2 */
5696 10 : numericvar_deserialize(&buf, &tmp_var);
5697 : #ifdef HAVE_INT128
5698 10 : numericvar_to_int128(&tmp_var, &result->sumX2);
5699 : #else
5700 : accum_sum_add(&result->sumX2, &tmp_var);
5701 : #endif
5702 :
5703 10 : pq_getmsgend(&buf);
5704 :
5705 10 : free_var(&tmp_var);
5706 :
5707 10 : PG_RETURN_POINTER(result);
5708 : }
5709 :
5710 : /*
5711 : * Transition function for int8 input when we don't need sumX2.
5712 : */
5713 : Datum
5714 311570 : int8_avg_accum(PG_FUNCTION_ARGS)
5715 : {
5716 : PolyNumAggState *state;
5717 :
5718 311570 : state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
5719 :
5720 : /* Create the state data on the first call */
5721 311570 : if (state == NULL)
5722 542 : state = makePolyNumAggState(fcinfo, false);
5723 :
5724 311570 : if (!PG_ARGISNULL(1))
5725 : {
5726 : #ifdef HAVE_INT128
5727 310586 : do_int128_accum(state, (int128) PG_GETARG_INT64(1));
5728 : #else
5729 : do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT64(1)));
5730 : #endif
5731 : }
5732 :
5733 311570 : PG_RETURN_POINTER(state);
5734 : }
5735 :
5736 : /*
5737 : * Combine function for PolyNumAggState for aggregates which don't require
5738 : * sumX2
5739 : */
5740 : Datum
5741 16 : int8_avg_combine(PG_FUNCTION_ARGS)
5742 : {
5743 : PolyNumAggState *state1;
5744 : PolyNumAggState *state2;
5745 : MemoryContext agg_context;
5746 : MemoryContext old_context;
5747 :
5748 16 : if (!AggCheckCallContext(fcinfo, &agg_context))
5749 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5750 :
5751 16 : state1 = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
5752 16 : state2 = PG_ARGISNULL(1) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(1);
5753 :
5754 16 : if (state2 == NULL)
5755 0 : PG_RETURN_POINTER(state1);
5756 :
5757 : /* manually copy all fields from state2 to state1 */
5758 16 : if (state1 == NULL)
5759 : {
5760 12 : old_context = MemoryContextSwitchTo(agg_context);
5761 :
5762 12 : state1 = makePolyNumAggState(fcinfo, false);
5763 12 : state1->N = state2->N;
5764 :
5765 : #ifdef HAVE_INT128
5766 12 : state1->sumX = state2->sumX;
5767 : #else
5768 : accum_sum_copy(&state1->sumX, &state2->sumX);
5769 : #endif
5770 12 : MemoryContextSwitchTo(old_context);
5771 :
5772 12 : PG_RETURN_POINTER(state1);
5773 : }
5774 :
5775 4 : if (state2->N > 0)
5776 : {
5777 4 : state1->N += state2->N;
5778 :
5779 : #ifdef HAVE_INT128
5780 4 : state1->sumX += state2->sumX;
5781 : #else
5782 : /* The rest of this needs to work in the aggregate context */
5783 : old_context = MemoryContextSwitchTo(agg_context);
5784 :
5785 : /* Accumulate sums */
5786 : accum_sum_combine(&state1->sumX, &state2->sumX);
5787 :
5788 : MemoryContextSwitchTo(old_context);
5789 : #endif
5790 :
5791 : }
5792 4 : PG_RETURN_POINTER(state1);
5793 : }
5794 :
5795 : /*
5796 : * int8_avg_serialize
5797 : * Serialize PolyNumAggState into bytea using the standard
5798 : * recv-function infrastructure.
5799 : */
5800 : Datum
5801 16 : int8_avg_serialize(PG_FUNCTION_ARGS)
5802 : {
5803 : PolyNumAggState *state;
5804 : StringInfoData buf;
5805 : bytea *result;
5806 : NumericVar tmp_var;
5807 :
5808 : /* Ensure we disallow calling when not in aggregate context */
5809 16 : if (!AggCheckCallContext(fcinfo, NULL))
5810 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5811 :
5812 16 : state = (PolyNumAggState *) PG_GETARG_POINTER(0);
5813 :
5814 : /*
5815 : * If the platform supports int128 then sumX will be a 128 integer type.
5816 : * Here we'll convert that into a numeric type so that the combine state
5817 : * is in the same format for both int128 enabled machines and machines
5818 : * which don't support that type. The logic here is that one day we might
5819 : * like to send these over to another server for further processing and we
5820 : * want a standard format to work with.
5821 : */
5822 :
5823 16 : init_var(&tmp_var);
5824 :
5825 16 : pq_begintypsend(&buf);
5826 :
5827 : /* N */
5828 16 : pq_sendint64(&buf, state->N);
5829 :
5830 : /* sumX */
5831 : #ifdef HAVE_INT128
5832 16 : int128_to_numericvar(state->sumX, &tmp_var);
5833 : #else
5834 : accum_sum_final(&state->sumX, &tmp_var);
5835 : #endif
5836 16 : numericvar_serialize(&buf, &tmp_var);
5837 :
5838 16 : result = pq_endtypsend(&buf);
5839 :
5840 16 : free_var(&tmp_var);
5841 :
5842 16 : PG_RETURN_BYTEA_P(result);
5843 : }
5844 :
5845 : /*
5846 : * int8_avg_deserialize
5847 : * Deserialize bytea back into PolyNumAggState.
5848 : */
5849 : Datum
5850 16 : int8_avg_deserialize(PG_FUNCTION_ARGS)
5851 : {
5852 : bytea *sstate;
5853 : PolyNumAggState *result;
5854 : StringInfoData buf;
5855 : NumericVar tmp_var;
5856 :
5857 16 : if (!AggCheckCallContext(fcinfo, NULL))
5858 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5859 :
5860 16 : sstate = PG_GETARG_BYTEA_PP(0);
5861 :
5862 16 : init_var(&tmp_var);
5863 :
5864 : /*
5865 : * Initialize a StringInfo so that we can "receive" it using the standard
5866 : * recv-function infrastructure.
5867 : */
5868 16 : initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
5869 16 : VARSIZE_ANY_EXHDR(sstate));
5870 :
5871 16 : result = makePolyNumAggStateCurrentContext(false);
5872 :
5873 : /* N */
5874 16 : result->N = pq_getmsgint64(&buf);
5875 :
5876 : /* sumX */
5877 16 : numericvar_deserialize(&buf, &tmp_var);
5878 : #ifdef HAVE_INT128
5879 16 : numericvar_to_int128(&tmp_var, &result->sumX);
5880 : #else
5881 : accum_sum_add(&result->sumX, &tmp_var);
5882 : #endif
5883 :
5884 16 : pq_getmsgend(&buf);
5885 :
5886 16 : free_var(&tmp_var);
5887 :
5888 16 : PG_RETURN_POINTER(result);
5889 : }
5890 :
5891 : /*
5892 : * Inverse transition functions to go with the above.
5893 : */
5894 :
5895 : Datum
5896 162 : int2_accum_inv(PG_FUNCTION_ARGS)
5897 : {
5898 : PolyNumAggState *state;
5899 :
5900 162 : state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
5901 :
5902 : /* Should not get here with no state */
5903 162 : if (state == NULL)
5904 0 : elog(ERROR, "int2_accum_inv called with NULL state");
5905 :
5906 162 : if (!PG_ARGISNULL(1))
5907 : {
5908 : #ifdef HAVE_INT128
5909 144 : do_int128_discard(state, (int128) PG_GETARG_INT16(1));
5910 : #else
5911 : /* Should never fail, all inputs have dscale 0 */
5912 : if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT16(1))))
5913 : elog(ERROR, "do_numeric_discard failed unexpectedly");
5914 : #endif
5915 : }
5916 :
5917 162 : PG_RETURN_POINTER(state);
5918 : }
5919 :
5920 : Datum
5921 162 : int4_accum_inv(PG_FUNCTION_ARGS)
5922 : {
5923 : PolyNumAggState *state;
5924 :
5925 162 : state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
5926 :
5927 : /* Should not get here with no state */
5928 162 : if (state == NULL)
5929 0 : elog(ERROR, "int4_accum_inv called with NULL state");
5930 :
5931 162 : if (!PG_ARGISNULL(1))
5932 : {
5933 : #ifdef HAVE_INT128
5934 144 : do_int128_discard(state, (int128) PG_GETARG_INT32(1));
5935 : #else
5936 : /* Should never fail, all inputs have dscale 0 */
5937 : if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT32(1))))
5938 : elog(ERROR, "do_numeric_discard failed unexpectedly");
5939 : #endif
5940 : }
5941 :
5942 162 : PG_RETURN_POINTER(state);
5943 : }
5944 :
5945 : Datum
5946 162 : int8_accum_inv(PG_FUNCTION_ARGS)
5947 : {
5948 : NumericAggState *state;
5949 :
5950 162 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
5951 :
5952 : /* Should not get here with no state */
5953 162 : if (state == NULL)
5954 0 : elog(ERROR, "int8_accum_inv called with NULL state");
5955 :
5956 162 : if (!PG_ARGISNULL(1))
5957 : {
5958 : /* Should never fail, all inputs have dscale 0 */
5959 144 : if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT64(1))))
5960 0 : elog(ERROR, "do_numeric_discard failed unexpectedly");
5961 : }
5962 :
5963 162 : PG_RETURN_POINTER(state);
5964 : }
5965 :
5966 : Datum
5967 36 : int8_avg_accum_inv(PG_FUNCTION_ARGS)
5968 : {
5969 : PolyNumAggState *state;
5970 :
5971 36 : state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
5972 :
5973 : /* Should not get here with no state */
5974 36 : if (state == NULL)
5975 0 : elog(ERROR, "int8_avg_accum_inv called with NULL state");
5976 :
5977 36 : if (!PG_ARGISNULL(1))
5978 : {
5979 : #ifdef HAVE_INT128
5980 24 : do_int128_discard(state, (int128) PG_GETARG_INT64(1));
5981 : #else
5982 : /* Should never fail, all inputs have dscale 0 */
5983 : if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT64(1))))
5984 : elog(ERROR, "do_numeric_discard failed unexpectedly");
5985 : #endif
5986 : }
5987 :
5988 36 : PG_RETURN_POINTER(state);
5989 : }
5990 :
5991 : Datum
5992 772 : numeric_poly_sum(PG_FUNCTION_ARGS)
5993 : {
5994 : #ifdef HAVE_INT128
5995 : PolyNumAggState *state;
5996 : Numeric res;
5997 : NumericVar result;
5998 :
5999 772 : state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
6000 :
6001 : /* If there were no non-null inputs, return NULL */
6002 772 : if (state == NULL || state->N == 0)
6003 24 : PG_RETURN_NULL();
6004 :
6005 748 : init_var(&result);
6006 :
6007 748 : int128_to_numericvar(state->sumX, &result);
6008 :
6009 748 : res = make_result(&result);
6010 :
6011 748 : free_var(&result);
6012 :
6013 748 : PG_RETURN_NUMERIC(res);
6014 : #else
6015 : return numeric_sum(fcinfo);
6016 : #endif
6017 : }
6018 :
6019 : Datum
6020 36 : numeric_poly_avg(PG_FUNCTION_ARGS)
6021 : {
6022 : #ifdef HAVE_INT128
6023 : PolyNumAggState *state;
6024 : NumericVar result;
6025 : Datum countd,
6026 : sumd;
6027 :
6028 36 : state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
6029 :
6030 : /* If there were no non-null inputs, return NULL */
6031 36 : if (state == NULL || state->N == 0)
6032 18 : PG_RETURN_NULL();
6033 :
6034 18 : init_var(&result);
6035 :
6036 18 : int128_to_numericvar(state->sumX, &result);
6037 :
6038 18 : countd = NumericGetDatum(int64_to_numeric(state->N));
6039 18 : sumd = NumericGetDatum(make_result(&result));
6040 :
6041 18 : free_var(&result);
6042 :
6043 18 : PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumd, countd));
6044 : #else
6045 : return numeric_avg(fcinfo);
6046 : #endif
6047 : }
6048 :
6049 : Datum
6050 78 : numeric_avg(PG_FUNCTION_ARGS)
6051 : {
6052 : NumericAggState *state;
6053 : Datum N_datum;
6054 : Datum sumX_datum;
6055 : NumericVar sumX_var;
6056 :
6057 78 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
6058 :
6059 : /* If there were no non-null inputs, return NULL */
6060 78 : if (state == NULL || NA_TOTAL_COUNT(state) == 0)
6061 18 : PG_RETURN_NULL();
6062 :
6063 60 : if (state->NaNcount > 0) /* there was at least one NaN input */
6064 6 : PG_RETURN_NUMERIC(make_result(&const_nan));
6065 :
6066 : /* adding plus and minus infinities gives NaN */
6067 54 : if (state->pInfcount > 0 && state->nInfcount > 0)
6068 6 : PG_RETURN_NUMERIC(make_result(&const_nan));
6069 48 : if (state->pInfcount > 0)
6070 18 : PG_RETURN_NUMERIC(make_result(&const_pinf));
6071 30 : if (state->nInfcount > 0)
6072 6 : PG_RETURN_NUMERIC(make_result(&const_ninf));
6073 :
6074 24 : N_datum = NumericGetDatum(int64_to_numeric(state->N));
6075 :
6076 24 : init_var(&sumX_var);
6077 24 : accum_sum_final(&state->sumX, &sumX_var);
6078 24 : sumX_datum = NumericGetDatum(make_result(&sumX_var));
6079 24 : free_var(&sumX_var);
6080 :
6081 24 : PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumX_datum, N_datum));
6082 : }
6083 :
6084 : Datum
6085 170906 : numeric_sum(PG_FUNCTION_ARGS)
6086 : {
6087 : NumericAggState *state;
6088 : NumericVar sumX_var;
6089 : Numeric result;
6090 :
6091 170906 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
6092 :
6093 : /* If there were no non-null inputs, return NULL */
6094 170906 : if (state == NULL || NA_TOTAL_COUNT(state) == 0)
6095 18 : PG_RETURN_NULL();
6096 :
6097 170888 : if (state->NaNcount > 0) /* there was at least one NaN input */
6098 18 : PG_RETURN_NUMERIC(make_result(&const_nan));
6099 :
6100 : /* adding plus and minus infinities gives NaN */
6101 170870 : if (state->pInfcount > 0 && state->nInfcount > 0)
6102 6 : PG_RETURN_NUMERIC(make_result(&const_nan));
6103 170864 : if (state->pInfcount > 0)
6104 18 : PG_RETURN_NUMERIC(make_result(&const_pinf));
6105 170846 : if (state->nInfcount > 0)
6106 6 : PG_RETURN_NUMERIC(make_result(&const_ninf));
6107 :
6108 170840 : init_var(&sumX_var);
6109 170840 : accum_sum_final(&state->sumX, &sumX_var);
6110 170840 : result = make_result(&sumX_var);
6111 170840 : free_var(&sumX_var);
6112 :
6113 170840 : PG_RETURN_NUMERIC(result);
6114 : }
6115 :
6116 : /*
6117 : * Workhorse routine for the standard deviance and variance
6118 : * aggregates. 'state' is aggregate's transition state.
6119 : * 'variance' specifies whether we should calculate the
6120 : * variance or the standard deviation. 'sample' indicates whether the
6121 : * caller is interested in the sample or the population
6122 : * variance/stddev.
6123 : *
6124 : * If appropriate variance statistic is undefined for the input,
6125 : * *is_null is set to true and NULL is returned.
6126 : */
6127 : static Numeric
6128 986 : numeric_stddev_internal(NumericAggState *state,
6129 : bool variance, bool sample,
6130 : bool *is_null)
6131 : {
6132 : Numeric res;
6133 : NumericVar vN,
6134 : vsumX,
6135 : vsumX2,
6136 : vNminus1;
6137 : int64 totCount;
6138 : int rscale;
6139 :
6140 : /*
6141 : * Sample stddev and variance are undefined when N <= 1; population stddev
6142 : * is undefined when N == 0. Return NULL in either case (note that NaNs
6143 : * and infinities count as normal inputs for this purpose).
6144 : */
6145 986 : if (state == NULL || (totCount = NA_TOTAL_COUNT(state)) == 0)
6146 : {
6147 0 : *is_null = true;
6148 0 : return NULL;
6149 : }
6150 :
6151 986 : if (sample && totCount <= 1)
6152 : {
6153 132 : *is_null = true;
6154 132 : return NULL;
6155 : }
6156 :
6157 854 : *is_null = false;
6158 :
6159 : /*
6160 : * Deal with NaN and infinity cases. By analogy to the behavior of the
6161 : * float8 functions, any infinity input produces NaN output.
6162 : */
6163 854 : if (state->NaNcount > 0 || state->pInfcount > 0 || state->nInfcount > 0)
6164 54 : return make_result(&const_nan);
6165 :
6166 : /* OK, normal calculation applies */
6167 800 : init_var(&vN);
6168 800 : init_var(&vsumX);
6169 800 : init_var(&vsumX2);
6170 :
6171 800 : int64_to_numericvar(state->N, &vN);
6172 800 : accum_sum_final(&(state->sumX), &vsumX);
6173 800 : accum_sum_final(&(state->sumX2), &vsumX2);
6174 :
6175 800 : init_var(&vNminus1);
6176 800 : sub_var(&vN, &const_one, &vNminus1);
6177 :
6178 : /* compute rscale for mul_var calls */
6179 800 : rscale = vsumX.dscale * 2;
6180 :
6181 800 : mul_var(&vsumX, &vsumX, &vsumX, rscale); /* vsumX = sumX * sumX */
6182 800 : mul_var(&vN, &vsumX2, &vsumX2, rscale); /* vsumX2 = N * sumX2 */
6183 800 : sub_var(&vsumX2, &vsumX, &vsumX2); /* N * sumX2 - sumX * sumX */
6184 :
6185 800 : if (cmp_var(&vsumX2, &const_zero) <= 0)
6186 : {
6187 : /* Watch out for roundoff error producing a negative numerator */
6188 80 : res = make_result(&const_zero);
6189 : }
6190 : else
6191 : {
6192 720 : if (sample)
6193 492 : mul_var(&vN, &vNminus1, &vNminus1, 0); /* N * (N - 1) */
6194 : else
6195 228 : mul_var(&vN, &vN, &vNminus1, 0); /* N * N */
6196 720 : rscale = select_div_scale(&vsumX2, &vNminus1);
6197 720 : div_var(&vsumX2, &vNminus1, &vsumX, rscale, true); /* variance */
6198 720 : if (!variance)
6199 378 : sqrt_var(&vsumX, &vsumX, rscale); /* stddev */
6200 :
6201 720 : res = make_result(&vsumX);
6202 : }
6203 :
6204 800 : free_var(&vNminus1);
6205 800 : free_var(&vsumX);
6206 800 : free_var(&vsumX2);
6207 :
6208 800 : return res;
6209 : }
6210 :
6211 : Datum
6212 180 : numeric_var_samp(PG_FUNCTION_ARGS)
6213 : {
6214 : NumericAggState *state;
6215 : Numeric res;
6216 : bool is_null;
6217 :
6218 180 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
6219 :
6220 180 : res = numeric_stddev_internal(state, true, true, &is_null);
6221 :
6222 180 : if (is_null)
6223 42 : PG_RETURN_NULL();
6224 : else
6225 138 : PG_RETURN_NUMERIC(res);
6226 : }
6227 :
6228 : Datum
6229 174 : numeric_stddev_samp(PG_FUNCTION_ARGS)
6230 : {
6231 : NumericAggState *state;
6232 : Numeric res;
6233 : bool is_null;
6234 :
6235 174 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
6236 :
6237 174 : res = numeric_stddev_internal(state, false, true, &is_null);
6238 :
6239 174 : if (is_null)
6240 42 : PG_RETURN_NULL();
6241 : else
6242 132 : PG_RETURN_NUMERIC(res);
6243 : }
6244 :
6245 : Datum
6246 114 : numeric_var_pop(PG_FUNCTION_ARGS)
6247 : {
6248 : NumericAggState *state;
6249 : Numeric res;
6250 : bool is_null;
6251 :
6252 114 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
6253 :
6254 114 : res = numeric_stddev_internal(state, true, false, &is_null);
6255 :
6256 114 : if (is_null)
6257 0 : PG_RETURN_NULL();
6258 : else
6259 114 : PG_RETURN_NUMERIC(res);
6260 : }
6261 :
6262 : Datum
6263 96 : numeric_stddev_pop(PG_FUNCTION_ARGS)
6264 : {
6265 : NumericAggState *state;
6266 : Numeric res;
6267 : bool is_null;
6268 :
6269 96 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
6270 :
6271 96 : res = numeric_stddev_internal(state, false, false, &is_null);
6272 :
6273 96 : if (is_null)
6274 0 : PG_RETURN_NULL();
6275 : else
6276 96 : PG_RETURN_NUMERIC(res);
6277 : }
6278 :
6279 : #ifdef HAVE_INT128
6280 : static Numeric
6281 422 : numeric_poly_stddev_internal(Int128AggState *state,
6282 : bool variance, bool sample,
6283 : bool *is_null)
6284 : {
6285 : NumericAggState numstate;
6286 : Numeric res;
6287 :
6288 : /* Initialize an empty agg state */
6289 422 : memset(&numstate, 0, sizeof(NumericAggState));
6290 :
6291 422 : if (state)
6292 : {
6293 : NumericVar tmp_var;
6294 :
6295 422 : numstate.N = state->N;
6296 :
6297 422 : init_var(&tmp_var);
6298 :
6299 422 : int128_to_numericvar(state->sumX, &tmp_var);
6300 422 : accum_sum_add(&numstate.sumX, &tmp_var);
6301 :
6302 422 : int128_to_numericvar(state->sumX2, &tmp_var);
6303 422 : accum_sum_add(&numstate.sumX2, &tmp_var);
6304 :
6305 422 : free_var(&tmp_var);
6306 : }
6307 :
6308 422 : res = numeric_stddev_internal(&numstate, variance, sample, is_null);
6309 :
6310 422 : if (numstate.sumX.ndigits > 0)
6311 : {
6312 422 : pfree(numstate.sumX.pos_digits);
6313 422 : pfree(numstate.sumX.neg_digits);
6314 : }
6315 422 : if (numstate.sumX2.ndigits > 0)
6316 : {
6317 422 : pfree(numstate.sumX2.pos_digits);
6318 422 : pfree(numstate.sumX2.neg_digits);
6319 : }
6320 :
6321 422 : return res;
6322 : }
6323 : #endif
6324 :
6325 : Datum
6326 126 : numeric_poly_var_samp(PG_FUNCTION_ARGS)
6327 : {
6328 : #ifdef HAVE_INT128
6329 : PolyNumAggState *state;
6330 : Numeric res;
6331 : bool is_null;
6332 :
6333 126 : state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
6334 :
6335 126 : res = numeric_poly_stddev_internal(state, true, true, &is_null);
6336 :
6337 126 : if (is_null)
6338 24 : PG_RETURN_NULL();
6339 : else
6340 102 : PG_RETURN_NUMERIC(res);
6341 : #else
6342 : return numeric_var_samp(fcinfo);
6343 : #endif
6344 : }
6345 :
6346 : Datum
6347 164 : numeric_poly_stddev_samp(PG_FUNCTION_ARGS)
6348 : {
6349 : #ifdef HAVE_INT128
6350 : PolyNumAggState *state;
6351 : Numeric res;
6352 : bool is_null;
6353 :
6354 164 : state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
6355 :
6356 164 : res = numeric_poly_stddev_internal(state, false, true, &is_null);
6357 :
6358 164 : if (is_null)
6359 24 : PG_RETURN_NULL();
6360 : else
6361 140 : PG_RETURN_NUMERIC(res);
6362 : #else
6363 : return numeric_stddev_samp(fcinfo);
6364 : #endif
6365 : }
6366 :
6367 : Datum
6368 60 : numeric_poly_var_pop(PG_FUNCTION_ARGS)
6369 : {
6370 : #ifdef HAVE_INT128
6371 : PolyNumAggState *state;
6372 : Numeric res;
6373 : bool is_null;
6374 :
6375 60 : state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
6376 :
6377 60 : res = numeric_poly_stddev_internal(state, true, false, &is_null);
6378 :
6379 60 : if (is_null)
6380 0 : PG_RETURN_NULL();
6381 : else
6382 60 : PG_RETURN_NUMERIC(res);
6383 : #else
6384 : return numeric_var_pop(fcinfo);
6385 : #endif
6386 : }
6387 :
6388 : Datum
6389 72 : numeric_poly_stddev_pop(PG_FUNCTION_ARGS)
6390 : {
6391 : #ifdef HAVE_INT128
6392 : PolyNumAggState *state;
6393 : Numeric res;
6394 : bool is_null;
6395 :
6396 72 : state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
6397 :
6398 72 : res = numeric_poly_stddev_internal(state, false, false, &is_null);
6399 :
6400 72 : if (is_null)
6401 0 : PG_RETURN_NULL();
6402 : else
6403 72 : PG_RETURN_NUMERIC(res);
6404 : #else
6405 : return numeric_stddev_pop(fcinfo);
6406 : #endif
6407 : }
6408 :
6409 : /*
6410 : * SUM transition functions for integer datatypes.
6411 : *
6412 : * To avoid overflow, we use accumulators wider than the input datatype.
6413 : * A Numeric accumulator is needed for int8 input; for int4 and int2
6414 : * inputs, we use int8 accumulators which should be sufficient for practical
6415 : * purposes. (The latter two therefore don't really belong in this file,
6416 : * but we keep them here anyway.)
6417 : *
6418 : * Because SQL defines the SUM() of no values to be NULL, not zero,
6419 : * the initial condition of the transition data value needs to be NULL. This
6420 : * means we can't rely on ExecAgg to automatically insert the first non-null
6421 : * data value into the transition data: it doesn't know how to do the type
6422 : * conversion. The upshot is that these routines have to be marked non-strict
6423 : * and handle substitution of the first non-null input themselves.
6424 : *
6425 : * Note: these functions are used only in plain aggregation mode.
6426 : * In moving-aggregate mode, we use intX_avg_accum and intX_avg_accum_inv.
6427 : */
6428 :
6429 : Datum
6430 24 : int2_sum(PG_FUNCTION_ARGS)
6431 : {
6432 : int64 newval;
6433 :
6434 24 : if (PG_ARGISNULL(0))
6435 : {
6436 : /* No non-null input seen so far... */
6437 6 : if (PG_ARGISNULL(1))
6438 0 : PG_RETURN_NULL(); /* still no non-null */
6439 : /* This is the first non-null input. */
6440 6 : newval = (int64) PG_GETARG_INT16(1);
6441 6 : PG_RETURN_INT64(newval);
6442 : }
6443 :
6444 : /*
6445 : * If we're invoked as an aggregate, we can cheat and modify our first
6446 : * parameter in-place to avoid palloc overhead. If not, we need to return
6447 : * the new value of the transition variable. (If int8 is pass-by-value,
6448 : * then of course this is useless as well as incorrect, so just ifdef it
6449 : * out.)
6450 : */
6451 : #ifndef USE_FLOAT8_BYVAL /* controls int8 too */
6452 : if (AggCheckCallContext(fcinfo, NULL))
6453 : {
6454 : int64 *oldsum = (int64 *) PG_GETARG_POINTER(0);
6455 :
6456 : /* Leave the running sum unchanged in the new input is null */
6457 : if (!PG_ARGISNULL(1))
6458 : *oldsum = *oldsum + (int64) PG_GETARG_INT16(1);
6459 :
6460 : PG_RETURN_POINTER(oldsum);
6461 : }
6462 : else
6463 : #endif
6464 : {
6465 18 : int64 oldsum = PG_GETARG_INT64(0);
6466 :
6467 : /* Leave sum unchanged if new input is null. */
6468 18 : if (PG_ARGISNULL(1))
6469 0 : PG_RETURN_INT64(oldsum);
6470 :
6471 : /* OK to do the addition. */
6472 18 : newval = oldsum + (int64) PG_GETARG_INT16(1);
6473 :
6474 18 : PG_RETURN_INT64(newval);
6475 : }
6476 : }
6477 :
6478 : Datum
6479 3395312 : int4_sum(PG_FUNCTION_ARGS)
6480 : {
6481 : int64 newval;
6482 :
6483 3395312 : if (PG_ARGISNULL(0))
6484 : {
6485 : /* No non-null input seen so far... */
6486 85936 : if (PG_ARGISNULL(1))
6487 986 : PG_RETURN_NULL(); /* still no non-null */
6488 : /* This is the first non-null input. */
6489 84950 : newval = (int64) PG_GETARG_INT32(1);
6490 84950 : PG_RETURN_INT64(newval);
6491 : }
6492 :
6493 : /*
6494 : * If we're invoked as an aggregate, we can cheat and modify our first
6495 : * parameter in-place to avoid palloc overhead. If not, we need to return
6496 : * the new value of the transition variable. (If int8 is pass-by-value,
6497 : * then of course this is useless as well as incorrect, so just ifdef it
6498 : * out.)
6499 : */
6500 : #ifndef USE_FLOAT8_BYVAL /* controls int8 too */
6501 : if (AggCheckCallContext(fcinfo, NULL))
6502 : {
6503 : int64 *oldsum = (int64 *) PG_GETARG_POINTER(0);
6504 :
6505 : /* Leave the running sum unchanged in the new input is null */
6506 : if (!PG_ARGISNULL(1))
6507 : *oldsum = *oldsum + (int64) PG_GETARG_INT32(1);
6508 :
6509 : PG_RETURN_POINTER(oldsum);
6510 : }
6511 : else
6512 : #endif
6513 : {
6514 3309376 : int64 oldsum = PG_GETARG_INT64(0);
6515 :
6516 : /* Leave sum unchanged if new input is null. */
6517 3309376 : if (PG_ARGISNULL(1))
6518 874 : PG_RETURN_INT64(oldsum);
6519 :
6520 : /* OK to do the addition. */
6521 3308502 : newval = oldsum + (int64) PG_GETARG_INT32(1);
6522 :
6523 3308502 : PG_RETURN_INT64(newval);
6524 : }
6525 : }
6526 :
6527 : /*
6528 : * Note: this function is obsolete, it's no longer used for SUM(int8).
6529 : */
6530 : Datum
6531 0 : int8_sum(PG_FUNCTION_ARGS)
6532 : {
6533 : Numeric oldsum;
6534 :
6535 0 : if (PG_ARGISNULL(0))
6536 : {
6537 : /* No non-null input seen so far... */
6538 0 : if (PG_ARGISNULL(1))
6539 0 : PG_RETURN_NULL(); /* still no non-null */
6540 : /* This is the first non-null input. */
6541 0 : PG_RETURN_NUMERIC(int64_to_numeric(PG_GETARG_INT64(1)));
6542 : }
6543 :
6544 : /*
6545 : * Note that we cannot special-case the aggregate case here, as we do for
6546 : * int2_sum and int4_sum: numeric is of variable size, so we cannot modify
6547 : * our first parameter in-place.
6548 : */
6549 :
6550 0 : oldsum = PG_GETARG_NUMERIC(0);
6551 :
6552 : /* Leave sum unchanged if new input is null. */
6553 0 : if (PG_ARGISNULL(1))
6554 0 : PG_RETURN_NUMERIC(oldsum);
6555 :
6556 : /* OK to do the addition. */
6557 0 : PG_RETURN_DATUM(DirectFunctionCall2(numeric_add,
6558 : NumericGetDatum(oldsum),
6559 : NumericGetDatum(int64_to_numeric(PG_GETARG_INT64(1)))));
6560 : }
6561 :
6562 :
6563 : /*
6564 : * Routines for avg(int2) and avg(int4). The transition datatype
6565 : * is a two-element int8 array, holding count and sum.
6566 : *
6567 : * These functions are also used for sum(int2) and sum(int4) when
6568 : * operating in moving-aggregate mode, since for correct inverse transitions
6569 : * we need to count the inputs.
6570 : */
6571 :
6572 : typedef struct Int8TransTypeData
6573 : {
6574 : int64 count;
6575 : int64 sum;
6576 : } Int8TransTypeData;
6577 :
6578 : Datum
6579 42 : int2_avg_accum(PG_FUNCTION_ARGS)
6580 : {
6581 : ArrayType *transarray;
6582 42 : int16 newval = PG_GETARG_INT16(1);
6583 : Int8TransTypeData *transdata;
6584 :
6585 : /*
6586 : * If we're invoked as an aggregate, we can cheat and modify our first
6587 : * parameter in-place to reduce palloc overhead. Otherwise we need to make
6588 : * a copy of it before scribbling on it.
6589 : */
6590 42 : if (AggCheckCallContext(fcinfo, NULL))
6591 42 : transarray = PG_GETARG_ARRAYTYPE_P(0);
6592 : else
6593 0 : transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
6594 :
6595 42 : if (ARR_HASNULL(transarray) ||
6596 42 : ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
6597 0 : elog(ERROR, "expected 2-element int8 array");
6598 :
6599 42 : transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
6600 42 : transdata->count++;
6601 42 : transdata->sum += newval;
6602 :
6603 42 : PG_RETURN_ARRAYTYPE_P(transarray);
6604 : }
6605 :
6606 : Datum
6607 2652804 : int4_avg_accum(PG_FUNCTION_ARGS)
6608 : {
6609 : ArrayType *transarray;
6610 2652804 : int32 newval = PG_GETARG_INT32(1);
6611 : Int8TransTypeData *transdata;
6612 :
6613 : /*
6614 : * If we're invoked as an aggregate, we can cheat and modify our first
6615 : * parameter in-place to reduce palloc overhead. Otherwise we need to make
6616 : * a copy of it before scribbling on it.
6617 : */
6618 2652804 : if (AggCheckCallContext(fcinfo, NULL))
6619 2652804 : transarray = PG_GETARG_ARRAYTYPE_P(0);
6620 : else
6621 0 : transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
6622 :
6623 2652804 : if (ARR_HASNULL(transarray) ||
6624 2652804 : ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
6625 0 : elog(ERROR, "expected 2-element int8 array");
6626 :
6627 2652804 : transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
6628 2652804 : transdata->count++;
6629 2652804 : transdata->sum += newval;
6630 :
6631 2652804 : PG_RETURN_ARRAYTYPE_P(transarray);
6632 : }
6633 :
6634 : Datum
6635 3422 : int4_avg_combine(PG_FUNCTION_ARGS)
6636 : {
6637 : ArrayType *transarray1;
6638 : ArrayType *transarray2;
6639 : Int8TransTypeData *state1;
6640 : Int8TransTypeData *state2;
6641 :
6642 3422 : if (!AggCheckCallContext(fcinfo, NULL))
6643 0 : elog(ERROR, "aggregate function called in non-aggregate context");
6644 :
6645 3422 : transarray1 = PG_GETARG_ARRAYTYPE_P(0);
6646 3422 : transarray2 = PG_GETARG_ARRAYTYPE_P(1);
6647 :
6648 3422 : if (ARR_HASNULL(transarray1) ||
6649 3422 : ARR_SIZE(transarray1) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
6650 0 : elog(ERROR, "expected 2-element int8 array");
6651 :
6652 3422 : if (ARR_HASNULL(transarray2) ||
6653 3422 : ARR_SIZE(transarray2) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
6654 0 : elog(ERROR, "expected 2-element int8 array");
6655 :
6656 3422 : state1 = (Int8TransTypeData *) ARR_DATA_PTR(transarray1);
6657 3422 : state2 = (Int8TransTypeData *) ARR_DATA_PTR(transarray2);
6658 :
6659 3422 : state1->count += state2->count;
6660 3422 : state1->sum += state2->sum;
6661 :
6662 3422 : PG_RETURN_ARRAYTYPE_P(transarray1);
6663 : }
6664 :
6665 : Datum
6666 12 : int2_avg_accum_inv(PG_FUNCTION_ARGS)
6667 : {
6668 : ArrayType *transarray;
6669 12 : int16 newval = PG_GETARG_INT16(1);
6670 : Int8TransTypeData *transdata;
6671 :
6672 : /*
6673 : * If we're invoked as an aggregate, we can cheat and modify our first
6674 : * parameter in-place to reduce palloc overhead. Otherwise we need to make
6675 : * a copy of it before scribbling on it.
6676 : */
6677 12 : if (AggCheckCallContext(fcinfo, NULL))
6678 12 : transarray = PG_GETARG_ARRAYTYPE_P(0);
6679 : else
6680 0 : transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
6681 :
6682 12 : if (ARR_HASNULL(transarray) ||
6683 12 : ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
6684 0 : elog(ERROR, "expected 2-element int8 array");
6685 :
6686 12 : transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
6687 12 : transdata->count--;
6688 12 : transdata->sum -= newval;
6689 :
6690 12 : PG_RETURN_ARRAYTYPE_P(transarray);
6691 : }
6692 :
6693 : Datum
6694 1452 : int4_avg_accum_inv(PG_FUNCTION_ARGS)
6695 : {
6696 : ArrayType *transarray;
6697 1452 : int32 newval = PG_GETARG_INT32(1);
6698 : Int8TransTypeData *transdata;
6699 :
6700 : /*
6701 : * If we're invoked as an aggregate, we can cheat and modify our first
6702 : * parameter in-place to reduce palloc overhead. Otherwise we need to make
6703 : * a copy of it before scribbling on it.
6704 : */
6705 1452 : if (AggCheckCallContext(fcinfo, NULL))
6706 1452 : transarray = PG_GETARG_ARRAYTYPE_P(0);
6707 : else
6708 0 : transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
6709 :
6710 1452 : if (ARR_HASNULL(transarray) ||
6711 1452 : ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
6712 0 : elog(ERROR, "expected 2-element int8 array");
6713 :
6714 1452 : transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
6715 1452 : transdata->count--;
6716 1452 : transdata->sum -= newval;
6717 :
6718 1452 : PG_RETURN_ARRAYTYPE_P(transarray);
6719 : }
6720 :
6721 : Datum
6722 10726 : int8_avg(PG_FUNCTION_ARGS)
6723 : {
6724 10726 : ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
6725 : Int8TransTypeData *transdata;
6726 : Datum countd,
6727 : sumd;
6728 :
6729 10726 : if (ARR_HASNULL(transarray) ||
6730 10726 : ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
6731 0 : elog(ERROR, "expected 2-element int8 array");
6732 10726 : transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
6733 :
6734 : /* SQL defines AVG of no values to be NULL */
6735 10726 : if (transdata->count == 0)
6736 118 : PG_RETURN_NULL();
6737 :
6738 10608 : countd = NumericGetDatum(int64_to_numeric(transdata->count));
6739 10608 : sumd = NumericGetDatum(int64_to_numeric(transdata->sum));
6740 :
6741 10608 : PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumd, countd));
6742 : }
6743 :
6744 : /*
6745 : * SUM(int2) and SUM(int4) both return int8, so we can use this
6746 : * final function for both.
6747 : */
6748 : Datum
6749 5532 : int2int4_sum(PG_FUNCTION_ARGS)
6750 : {
6751 5532 : ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
6752 : Int8TransTypeData *transdata;
6753 :
6754 5532 : if (ARR_HASNULL(transarray) ||
6755 5532 : ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
6756 0 : elog(ERROR, "expected 2-element int8 array");
6757 5532 : transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
6758 :
6759 : /* SQL defines SUM of no values to be NULL */
6760 5532 : if (transdata->count == 0)
6761 498 : PG_RETURN_NULL();
6762 :
6763 5034 : PG_RETURN_DATUM(Int64GetDatumFast(transdata->sum));
6764 : }
6765 :
6766 :
6767 : /* ----------------------------------------------------------------------
6768 : *
6769 : * Debug support
6770 : *
6771 : * ----------------------------------------------------------------------
6772 : */
6773 :
6774 : #ifdef NUMERIC_DEBUG
6775 :
6776 : /*
6777 : * dump_numeric() - Dump a value in the db storage format for debugging
6778 : */
6779 : static void
6780 : dump_numeric(const char *str, Numeric num)
6781 : {
6782 : NumericDigit *digits = NUMERIC_DIGITS(num);
6783 : int ndigits;
6784 : int i;
6785 :
6786 : ndigits = NUMERIC_NDIGITS(num);
6787 :
6788 : printf("%s: NUMERIC w=%d d=%d ", str,
6789 : NUMERIC_WEIGHT(num), NUMERIC_DSCALE(num));
6790 : switch (NUMERIC_SIGN(num))
6791 : {
6792 : case NUMERIC_POS:
6793 : printf("POS");
6794 : break;
6795 : case NUMERIC_NEG:
6796 : printf("NEG");
6797 : break;
6798 : case NUMERIC_NAN:
6799 : printf("NaN");
6800 : break;
6801 : case NUMERIC_PINF:
6802 : printf("Infinity");
6803 : break;
6804 : case NUMERIC_NINF:
6805 : printf("-Infinity");
6806 : break;
6807 : default:
6808 : printf("SIGN=0x%x", NUMERIC_SIGN(num));
6809 : break;
6810 : }
6811 :
6812 : for (i = 0; i < ndigits; i++)
6813 : printf(" %0*d", DEC_DIGITS, digits[i]);
6814 : printf("\n");
6815 : }
6816 :
6817 :
6818 : /*
6819 : * dump_var() - Dump a value in the variable format for debugging
6820 : */
6821 : static void
6822 : dump_var(const char *str, NumericVar *var)
6823 : {
6824 : int i;
6825 :
6826 : printf("%s: VAR w=%d d=%d ", str, var->weight, var->dscale);
6827 : switch (var->sign)
6828 : {
6829 : case NUMERIC_POS:
6830 : printf("POS");
6831 : break;
6832 : case NUMERIC_NEG:
6833 : printf("NEG");
6834 : break;
6835 : case NUMERIC_NAN:
6836 : printf("NaN");
6837 : break;
6838 : case NUMERIC_PINF:
6839 : printf("Infinity");
6840 : break;
6841 : case NUMERIC_NINF:
6842 : printf("-Infinity");
6843 : break;
6844 : default:
6845 : printf("SIGN=0x%x", var->sign);
6846 : break;
6847 : }
6848 :
6849 : for (i = 0; i < var->ndigits; i++)
6850 : printf(" %0*d", DEC_DIGITS, var->digits[i]);
6851 :
6852 : printf("\n");
6853 : }
6854 : #endif /* NUMERIC_DEBUG */
6855 :
6856 :
6857 : /* ----------------------------------------------------------------------
6858 : *
6859 : * Local functions follow
6860 : *
6861 : * In general, these do not support "special" (NaN or infinity) inputs;
6862 : * callers should handle those possibilities first.
6863 : * (There are one or two exceptions, noted in their header comments.)
6864 : *
6865 : * ----------------------------------------------------------------------
6866 : */
6867 :
6868 :
6869 : /*
6870 : * alloc_var() -
6871 : *
6872 : * Allocate a digit buffer of ndigits digits (plus a spare digit for rounding)
6873 : */
6874 : static void
6875 2828430 : alloc_var(NumericVar *var, int ndigits)
6876 : {
6877 2828430 : digitbuf_free(var->buf);
6878 2828430 : var->buf = digitbuf_alloc(ndigits + 1);
6879 2828430 : var->buf[0] = 0; /* spare digit for rounding */
6880 2828430 : var->digits = var->buf + 1;
6881 2828430 : var->ndigits = ndigits;
6882 2828430 : }
6883 :
6884 :
6885 : /*
6886 : * free_var() -
6887 : *
6888 : * Return the digit buffer of a variable to the free pool
6889 : */
6890 : static void
6891 3235386 : free_var(NumericVar *var)
6892 : {
6893 3235386 : digitbuf_free(var->buf);
6894 3235386 : var->buf = NULL;
6895 3235386 : var->digits = NULL;
6896 3235386 : var->sign = NUMERIC_NAN;
6897 3235386 : }
6898 :
6899 :
6900 : /*
6901 : * zero_var() -
6902 : *
6903 : * Set a variable to ZERO.
6904 : * Note: its dscale is not touched.
6905 : */
6906 : static void
6907 40092 : zero_var(NumericVar *var)
6908 : {
6909 40092 : digitbuf_free(var->buf);
6910 40092 : var->buf = NULL;
6911 40092 : var->digits = NULL;
6912 40092 : var->ndigits = 0;
6913 40092 : var->weight = 0; /* by convention; doesn't really matter */
6914 40092 : var->sign = NUMERIC_POS; /* anything but NAN... */
6915 40092 : }
6916 :
6917 :
6918 : /*
6919 : * set_var_from_str()
6920 : *
6921 : * Parse a string and put the number into a variable
6922 : *
6923 : * This function does not handle leading or trailing spaces. It returns
6924 : * the end+1 position parsed into *endptr, so that caller can check for
6925 : * trailing spaces/garbage if deemed necessary.
6926 : *
6927 : * cp is the place to actually start parsing; str is what to use in error
6928 : * reports. (Typically cp would be the same except advanced over spaces.)
6929 : *
6930 : * Returns true on success, false on failure (if escontext points to an
6931 : * ErrorSaveContext; otherwise errors are thrown).
6932 : */
6933 : static bool
6934 120428 : set_var_from_str(const char *str, const char *cp,
6935 : NumericVar *dest, const char **endptr,
6936 : Node *escontext)
6937 : {
6938 120428 : bool have_dp = false;
6939 : int i;
6940 : unsigned char *decdigits;
6941 120428 : int sign = NUMERIC_POS;
6942 120428 : int dweight = -1;
6943 : int ddigits;
6944 120428 : int dscale = 0;
6945 : int weight;
6946 : int ndigits;
6947 : int offset;
6948 : NumericDigit *digits;
6949 :
6950 : /*
6951 : * We first parse the string to extract decimal digits and determine the
6952 : * correct decimal weight. Then convert to NBASE representation.
6953 : */
6954 120428 : switch (*cp)
6955 : {
6956 0 : case '+':
6957 0 : sign = NUMERIC_POS;
6958 0 : cp++;
6959 0 : break;
6960 :
6961 300 : case '-':
6962 300 : sign = NUMERIC_NEG;
6963 300 : cp++;
6964 300 : break;
6965 : }
6966 :
6967 120428 : if (*cp == '.')
6968 : {
6969 382 : have_dp = true;
6970 382 : cp++;
6971 : }
6972 :
6973 120428 : if (!isdigit((unsigned char) *cp))
6974 0 : goto invalid_syntax;
6975 :
6976 120428 : decdigits = (unsigned char *) palloc(strlen(cp) + DEC_DIGITS * 2);
6977 :
6978 : /* leading padding for digit alignment later */
6979 120428 : memset(decdigits, 0, DEC_DIGITS);
6980 120428 : i = DEC_DIGITS;
6981 :
6982 491254 : while (*cp)
6983 : {
6984 371906 : if (isdigit((unsigned char) *cp))
6985 : {
6986 355914 : decdigits[i++] = *cp++ - '0';
6987 355914 : if (!have_dp)
6988 293596 : dweight++;
6989 : else
6990 62318 : dscale++;
6991 : }
6992 15992 : else if (*cp == '.')
6993 : {
6994 14750 : if (have_dp)
6995 0 : goto invalid_syntax;
6996 14750 : have_dp = true;
6997 14750 : cp++;
6998 : /* decimal point must not be followed by underscore */
6999 14750 : if (*cp == '_')
7000 6 : goto invalid_syntax;
7001 : }
7002 1242 : else if (*cp == '_')
7003 : {
7004 : /* underscore must be followed by more digits */
7005 186 : cp++;
7006 186 : if (!isdigit((unsigned char) *cp))
7007 18 : goto invalid_syntax;
7008 : }
7009 : else
7010 1056 : break;
7011 : }
7012 :
7013 120404 : ddigits = i - DEC_DIGITS;
7014 : /* trailing padding for digit alignment later */
7015 120404 : memset(decdigits + i, 0, DEC_DIGITS - 1);
7016 :
7017 : /* Handle exponent, if any */
7018 120404 : if (*cp == 'e' || *cp == 'E')
7019 : {
7020 1020 : int64 exponent = 0;
7021 1020 : bool neg = false;
7022 :
7023 : /*
7024 : * At this point, dweight and dscale can't be more than about
7025 : * INT_MAX/2 due to the MaxAllocSize limit on string length, so
7026 : * constraining the exponent similarly should be enough to prevent
7027 : * integer overflow in this function. If the value is too large to
7028 : * fit in storage format, make_result() will complain about it later;
7029 : * for consistency use the same ereport errcode/text as make_result().
7030 : */
7031 :
7032 : /* exponent sign */
7033 1020 : cp++;
7034 1020 : if (*cp == '+')
7035 154 : cp++;
7036 866 : else if (*cp == '-')
7037 : {
7038 380 : neg = true;
7039 380 : cp++;
7040 : }
7041 :
7042 : /* exponent digits */
7043 1020 : if (!isdigit((unsigned char) *cp))
7044 6 : goto invalid_syntax;
7045 :
7046 3102 : while (*cp)
7047 : {
7048 2106 : if (isdigit((unsigned char) *cp))
7049 : {
7050 2064 : exponent = exponent * 10 + (*cp++ - '0');
7051 2064 : if (exponent > PG_INT32_MAX / 2)
7052 6 : goto out_of_range;
7053 : }
7054 42 : else if (*cp == '_')
7055 : {
7056 : /* underscore must be followed by more digits */
7057 42 : cp++;
7058 42 : if (!isdigit((unsigned char) *cp))
7059 12 : goto invalid_syntax;
7060 : }
7061 : else
7062 0 : break;
7063 : }
7064 :
7065 996 : if (neg)
7066 380 : exponent = -exponent;
7067 :
7068 996 : dweight += (int) exponent;
7069 996 : dscale -= (int) exponent;
7070 996 : if (dscale < 0)
7071 412 : dscale = 0;
7072 : }
7073 :
7074 : /*
7075 : * Okay, convert pure-decimal representation to base NBASE. First we need
7076 : * to determine the converted weight and ndigits. offset is the number of
7077 : * decimal zeroes to insert before the first given digit to have a
7078 : * correctly aligned first NBASE digit.
7079 : */
7080 120380 : if (dweight >= 0)
7081 119720 : weight = (dweight + 1 + DEC_DIGITS - 1) / DEC_DIGITS - 1;
7082 : else
7083 660 : weight = -((-dweight - 1) / DEC_DIGITS + 1);
7084 120380 : offset = (weight + 1) * DEC_DIGITS - (dweight + 1);
7085 120380 : ndigits = (ddigits + offset + DEC_DIGITS - 1) / DEC_DIGITS;
7086 :
7087 120380 : alloc_var(dest, ndigits);
7088 120380 : dest->sign = sign;
7089 120380 : dest->weight = weight;
7090 120380 : dest->dscale = dscale;
7091 :
7092 120380 : i = DEC_DIGITS - offset;
7093 120380 : digits = dest->digits;
7094 :
7095 283150 : while (ndigits-- > 0)
7096 : {
7097 : #if DEC_DIGITS == 4
7098 162770 : *digits++ = ((decdigits[i] * 10 + decdigits[i + 1]) * 10 +
7099 162770 : decdigits[i + 2]) * 10 + decdigits[i + 3];
7100 : #elif DEC_DIGITS == 2
7101 : *digits++ = decdigits[i] * 10 + decdigits[i + 1];
7102 : #elif DEC_DIGITS == 1
7103 : *digits++ = decdigits[i];
7104 : #else
7105 : #error unsupported NBASE
7106 : #endif
7107 162770 : i += DEC_DIGITS;
7108 : }
7109 :
7110 120380 : pfree(decdigits);
7111 :
7112 : /* Strip any leading/trailing zeroes, and normalize weight if zero */
7113 120380 : strip_var(dest);
7114 :
7115 : /* Return end+1 position for caller */
7116 120380 : *endptr = cp;
7117 :
7118 120380 : return true;
7119 :
7120 6 : out_of_range:
7121 6 : ereturn(escontext, false,
7122 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
7123 : errmsg("value overflows numeric format")));
7124 :
7125 42 : invalid_syntax:
7126 42 : ereturn(escontext, false,
7127 : (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
7128 : errmsg("invalid input syntax for type %s: \"%s\"",
7129 : "numeric", str)));
7130 : }
7131 :
7132 :
7133 : /*
7134 : * Return the numeric value of a single hex digit.
7135 : */
7136 : static inline int
7137 708 : xdigit_value(char dig)
7138 : {
7139 894 : return dig >= '0' && dig <= '9' ? dig - '0' :
7140 294 : dig >= 'a' && dig <= 'f' ? dig - 'a' + 10 :
7141 108 : dig >= 'A' && dig <= 'F' ? dig - 'A' + 10 : -1;
7142 : }
7143 :
7144 : /*
7145 : * set_var_from_non_decimal_integer_str()
7146 : *
7147 : * Parse a string containing a non-decimal integer
7148 : *
7149 : * This function does not handle leading or trailing spaces. It returns
7150 : * the end+1 position parsed into *endptr, so that caller can check for
7151 : * trailing spaces/garbage if deemed necessary.
7152 : *
7153 : * cp is the place to actually start parsing; str is what to use in error
7154 : * reports. The number's sign and base prefix indicator (e.g., "0x") are
7155 : * assumed to have already been parsed, so cp should point to the number's
7156 : * first digit in the base specified.
7157 : *
7158 : * base is expected to be 2, 8 or 16.
7159 : *
7160 : * Returns true on success, false on failure (if escontext points to an
7161 : * ErrorSaveContext; otherwise errors are thrown).
7162 : */
7163 : static bool
7164 156 : set_var_from_non_decimal_integer_str(const char *str, const char *cp, int sign,
7165 : int base, NumericVar *dest,
7166 : const char **endptr, Node *escontext)
7167 : {
7168 156 : const char *firstdigit = cp;
7169 : int64 tmp;
7170 : int64 mul;
7171 : NumericVar tmp_var;
7172 :
7173 156 : init_var(&tmp_var);
7174 :
7175 156 : zero_var(dest);
7176 :
7177 : /*
7178 : * Process input digits in groups that fit in int64. Here "tmp" is the
7179 : * value of the digits in the group, and "mul" is base^n, where n is the
7180 : * number of digits in the group. Thus tmp < mul, and we must start a new
7181 : * group when mul * base threatens to overflow PG_INT64_MAX.
7182 : */
7183 156 : tmp = 0;
7184 156 : mul = 1;
7185 :
7186 156 : if (base == 16)
7187 : {
7188 828 : while (*cp)
7189 : {
7190 798 : if (isxdigit((unsigned char) *cp))
7191 : {
7192 708 : if (mul > PG_INT64_MAX / 16)
7193 : {
7194 : /* Add the contribution from this group of digits */
7195 30 : int64_to_numericvar(mul, &tmp_var);
7196 30 : mul_var(dest, &tmp_var, dest, 0);
7197 30 : int64_to_numericvar(tmp, &tmp_var);
7198 30 : add_var(dest, &tmp_var, dest);
7199 :
7200 : /* Result will overflow if weight overflows int16 */
7201 30 : if (dest->weight > SHRT_MAX)
7202 0 : goto out_of_range;
7203 :
7204 : /* Begin a new group */
7205 30 : tmp = 0;
7206 30 : mul = 1;
7207 : }
7208 :
7209 708 : tmp = tmp * 16 + xdigit_value(*cp++);
7210 708 : mul = mul * 16;
7211 : }
7212 90 : else if (*cp == '_')
7213 : {
7214 : /* Underscore must be followed by more digits */
7215 66 : cp++;
7216 66 : if (!isxdigit((unsigned char) *cp))
7217 18 : goto invalid_syntax;
7218 : }
7219 : else
7220 24 : break;
7221 : }
7222 : }
7223 84 : else if (base == 8)
7224 : {
7225 636 : while (*cp)
7226 : {
7227 606 : if (*cp >= '0' && *cp <= '7')
7228 : {
7229 558 : if (mul > PG_INT64_MAX / 8)
7230 : {
7231 : /* Add the contribution from this group of digits */
7232 18 : int64_to_numericvar(mul, &tmp_var);
7233 18 : mul_var(dest, &tmp_var, dest, 0);
7234 18 : int64_to_numericvar(tmp, &tmp_var);
7235 18 : add_var(dest, &tmp_var, dest);
7236 :
7237 : /* Result will overflow if weight overflows int16 */
7238 18 : if (dest->weight > SHRT_MAX)
7239 0 : goto out_of_range;
7240 :
7241 : /* Begin a new group */
7242 18 : tmp = 0;
7243 18 : mul = 1;
7244 : }
7245 :
7246 558 : tmp = tmp * 8 + (*cp++ - '0');
7247 558 : mul = mul * 8;
7248 : }
7249 48 : else if (*cp == '_')
7250 : {
7251 : /* Underscore must be followed by more digits */
7252 36 : cp++;
7253 36 : if (*cp < '0' || *cp > '7')
7254 0 : goto invalid_syntax;
7255 : }
7256 : else
7257 12 : break;
7258 : }
7259 : }
7260 42 : else if (base == 2)
7261 : {
7262 1560 : while (*cp)
7263 : {
7264 1530 : if (*cp >= '0' && *cp <= '1')
7265 : {
7266 1416 : if (mul > PG_INT64_MAX / 2)
7267 : {
7268 : /* Add the contribution from this group of digits */
7269 18 : int64_to_numericvar(mul, &tmp_var);
7270 18 : mul_var(dest, &tmp_var, dest, 0);
7271 18 : int64_to_numericvar(tmp, &tmp_var);
7272 18 : add_var(dest, &tmp_var, dest);
7273 :
7274 : /* Result will overflow if weight overflows int16 */
7275 18 : if (dest->weight > SHRT_MAX)
7276 0 : goto out_of_range;
7277 :
7278 : /* Begin a new group */
7279 18 : tmp = 0;
7280 18 : mul = 1;
7281 : }
7282 :
7283 1416 : tmp = tmp * 2 + (*cp++ - '0');
7284 1416 : mul = mul * 2;
7285 : }
7286 114 : else if (*cp == '_')
7287 : {
7288 : /* Underscore must be followed by more digits */
7289 102 : cp++;
7290 102 : if (*cp < '0' || *cp > '1')
7291 0 : goto invalid_syntax;
7292 : }
7293 : else
7294 12 : break;
7295 : }
7296 : }
7297 : else
7298 : /* Should never happen; treat as invalid input */
7299 0 : goto invalid_syntax;
7300 :
7301 : /* Check that we got at least one digit */
7302 138 : if (unlikely(cp == firstdigit))
7303 0 : goto invalid_syntax;
7304 :
7305 : /* Add the contribution from the final group of digits */
7306 138 : int64_to_numericvar(mul, &tmp_var);
7307 138 : mul_var(dest, &tmp_var, dest, 0);
7308 138 : int64_to_numericvar(tmp, &tmp_var);
7309 138 : add_var(dest, &tmp_var, dest);
7310 :
7311 138 : if (dest->weight > SHRT_MAX)
7312 0 : goto out_of_range;
7313 :
7314 138 : dest->sign = sign;
7315 :
7316 138 : free_var(&tmp_var);
7317 :
7318 : /* Return end+1 position for caller */
7319 138 : *endptr = cp;
7320 :
7321 138 : return true;
7322 :
7323 0 : out_of_range:
7324 0 : ereturn(escontext, false,
7325 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
7326 : errmsg("value overflows numeric format")));
7327 :
7328 18 : invalid_syntax:
7329 18 : ereturn(escontext, false,
7330 : (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
7331 : errmsg("invalid input syntax for type %s: \"%s\"",
7332 : "numeric", str)));
7333 : }
7334 :
7335 :
7336 : /*
7337 : * set_var_from_num() -
7338 : *
7339 : * Convert the packed db format into a variable
7340 : */
7341 : static void
7342 12396 : set_var_from_num(Numeric num, NumericVar *dest)
7343 : {
7344 : int ndigits;
7345 :
7346 12396 : ndigits = NUMERIC_NDIGITS(num);
7347 :
7348 12396 : alloc_var(dest, ndigits);
7349 :
7350 12396 : dest->weight = NUMERIC_WEIGHT(num);
7351 12396 : dest->sign = NUMERIC_SIGN(num);
7352 12396 : dest->dscale = NUMERIC_DSCALE(num);
7353 :
7354 12396 : memcpy(dest->digits, NUMERIC_DIGITS(num), ndigits * sizeof(NumericDigit));
7355 12396 : }
7356 :
7357 :
7358 : /*
7359 : * init_var_from_num() -
7360 : *
7361 : * Initialize a variable from packed db format. The digits array is not
7362 : * copied, which saves some cycles when the resulting var is not modified.
7363 : * Also, there's no need to call free_var(), as long as you don't assign any
7364 : * other value to it (with set_var_* functions, or by using the var as the
7365 : * destination of a function like add_var())
7366 : *
7367 : * CAUTION: Do not modify the digits buffer of a var initialized with this
7368 : * function, e.g by calling round_var() or trunc_var(), as the changes will
7369 : * propagate to the original Numeric! It's OK to use it as the destination
7370 : * argument of one of the calculational functions, though.
7371 : */
7372 : static void
7373 4865510 : init_var_from_num(Numeric num, NumericVar *dest)
7374 : {
7375 4865510 : dest->ndigits = NUMERIC_NDIGITS(num);
7376 4865510 : dest->weight = NUMERIC_WEIGHT(num);
7377 4865510 : dest->sign = NUMERIC_SIGN(num);
7378 4865510 : dest->dscale = NUMERIC_DSCALE(num);
7379 4865510 : dest->digits = NUMERIC_DIGITS(num);
7380 4865510 : dest->buf = NULL; /* digits array is not palloc'd */
7381 4865510 : }
7382 :
7383 :
7384 : /*
7385 : * set_var_from_var() -
7386 : *
7387 : * Copy one variable into another
7388 : */
7389 : static void
7390 34870 : set_var_from_var(const NumericVar *value, NumericVar *dest)
7391 : {
7392 : NumericDigit *newbuf;
7393 :
7394 34870 : newbuf = digitbuf_alloc(value->ndigits + 1);
7395 34870 : newbuf[0] = 0; /* spare digit for rounding */
7396 34870 : if (value->ndigits > 0) /* else value->digits might be null */
7397 34056 : memcpy(newbuf + 1, value->digits,
7398 34056 : value->ndigits * sizeof(NumericDigit));
7399 :
7400 34870 : digitbuf_free(dest->buf);
7401 :
7402 34870 : memmove(dest, value, sizeof(NumericVar));
7403 34870 : dest->buf = newbuf;
7404 34870 : dest->digits = newbuf + 1;
7405 34870 : }
7406 :
7407 :
7408 : /*
7409 : * get_str_from_var() -
7410 : *
7411 : * Convert a var to text representation (guts of numeric_out).
7412 : * The var is displayed to the number of digits indicated by its dscale.
7413 : * Returns a palloc'd string.
7414 : */
7415 : static char *
7416 792174 : get_str_from_var(const NumericVar *var)
7417 : {
7418 : int dscale;
7419 : char *str;
7420 : char *cp;
7421 : char *endcp;
7422 : int i;
7423 : int d;
7424 : NumericDigit dig;
7425 :
7426 : #if DEC_DIGITS > 1
7427 : NumericDigit d1;
7428 : #endif
7429 :
7430 792174 : dscale = var->dscale;
7431 :
7432 : /*
7433 : * Allocate space for the result.
7434 : *
7435 : * i is set to the # of decimal digits before decimal point. dscale is the
7436 : * # of decimal digits we will print after decimal point. We may generate
7437 : * as many as DEC_DIGITS-1 excess digits at the end, and in addition we
7438 : * need room for sign, decimal point, null terminator.
7439 : */
7440 792174 : i = (var->weight + 1) * DEC_DIGITS;
7441 792174 : if (i <= 0)
7442 138502 : i = 1;
7443 :
7444 792174 : str = palloc(i + dscale + DEC_DIGITS + 2);
7445 792174 : cp = str;
7446 :
7447 : /*
7448 : * Output a dash for negative values
7449 : */
7450 792174 : if (var->sign == NUMERIC_NEG)
7451 4814 : *cp++ = '-';
7452 :
7453 : /*
7454 : * Output all digits before the decimal point
7455 : */
7456 792174 : if (var->weight < 0)
7457 : {
7458 138502 : d = var->weight + 1;
7459 138502 : *cp++ = '0';
7460 : }
7461 : else
7462 : {
7463 1402298 : for (d = 0; d <= var->weight; d++)
7464 : {
7465 748626 : dig = (d < var->ndigits) ? var->digits[d] : 0;
7466 : /* In the first digit, suppress extra leading decimal zeroes */
7467 : #if DEC_DIGITS == 4
7468 : {
7469 748626 : bool putit = (d > 0);
7470 :
7471 748626 : d1 = dig / 1000;
7472 748626 : dig -= d1 * 1000;
7473 748626 : putit |= (d1 > 0);
7474 748626 : if (putit)
7475 100742 : *cp++ = d1 + '0';
7476 748626 : d1 = dig / 100;
7477 748626 : dig -= d1 * 100;
7478 748626 : putit |= (d1 > 0);
7479 748626 : if (putit)
7480 505186 : *cp++ = d1 + '0';
7481 748626 : d1 = dig / 10;
7482 748626 : dig -= d1 * 10;
7483 748626 : putit |= (d1 > 0);
7484 748626 : if (putit)
7485 631550 : *cp++ = d1 + '0';
7486 748626 : *cp++ = dig + '0';
7487 : }
7488 : #elif DEC_DIGITS == 2
7489 : d1 = dig / 10;
7490 : dig -= d1 * 10;
7491 : if (d1 > 0 || d > 0)
7492 : *cp++ = d1 + '0';
7493 : *cp++ = dig + '0';
7494 : #elif DEC_DIGITS == 1
7495 : *cp++ = dig + '0';
7496 : #else
7497 : #error unsupported NBASE
7498 : #endif
7499 : }
7500 : }
7501 :
7502 : /*
7503 : * If requested, output a decimal point and all the digits that follow it.
7504 : * We initially put out a multiple of DEC_DIGITS digits, then truncate if
7505 : * needed.
7506 : */
7507 792174 : if (dscale > 0)
7508 : {
7509 641638 : *cp++ = '.';
7510 641638 : endcp = cp + dscale;
7511 1891892 : for (i = 0; i < dscale; d++, i += DEC_DIGITS)
7512 : {
7513 1250254 : dig = (d >= 0 && d < var->ndigits) ? var->digits[d] : 0;
7514 : #if DEC_DIGITS == 4
7515 1250254 : d1 = dig / 1000;
7516 1250254 : dig -= d1 * 1000;
7517 1250254 : *cp++ = d1 + '0';
7518 1250254 : d1 = dig / 100;
7519 1250254 : dig -= d1 * 100;
7520 1250254 : *cp++ = d1 + '0';
7521 1250254 : d1 = dig / 10;
7522 1250254 : dig -= d1 * 10;
7523 1250254 : *cp++ = d1 + '0';
7524 1250254 : *cp++ = dig + '0';
7525 : #elif DEC_DIGITS == 2
7526 : d1 = dig / 10;
7527 : dig -= d1 * 10;
7528 : *cp++ = d1 + '0';
7529 : *cp++ = dig + '0';
7530 : #elif DEC_DIGITS == 1
7531 : *cp++ = dig + '0';
7532 : #else
7533 : #error unsupported NBASE
7534 : #endif
7535 : }
7536 641638 : cp = endcp;
7537 : }
7538 :
7539 : /*
7540 : * terminate the string and return it
7541 : */
7542 792174 : *cp = '\0';
7543 792174 : return str;
7544 : }
7545 :
7546 : /*
7547 : * get_str_from_var_sci() -
7548 : *
7549 : * Convert a var to a normalised scientific notation text representation.
7550 : * This function does the heavy lifting for numeric_out_sci().
7551 : *
7552 : * This notation has the general form a * 10^b, where a is known as the
7553 : * "significand" and b is known as the "exponent".
7554 : *
7555 : * Because we can't do superscript in ASCII (and because we want to copy
7556 : * printf's behaviour) we display the exponent using E notation, with a
7557 : * minimum of two exponent digits.
7558 : *
7559 : * For example, the value 1234 could be output as 1.2e+03.
7560 : *
7561 : * We assume that the exponent can fit into an int32.
7562 : *
7563 : * rscale is the number of decimal digits desired after the decimal point in
7564 : * the output, negative values will be treated as meaning zero.
7565 : *
7566 : * Returns a palloc'd string.
7567 : */
7568 : static char *
7569 216 : get_str_from_var_sci(const NumericVar *var, int rscale)
7570 : {
7571 : int32 exponent;
7572 : NumericVar tmp_var;
7573 : size_t len;
7574 : char *str;
7575 : char *sig_out;
7576 :
7577 216 : if (rscale < 0)
7578 0 : rscale = 0;
7579 :
7580 : /*
7581 : * Determine the exponent of this number in normalised form.
7582 : *
7583 : * This is the exponent required to represent the number with only one
7584 : * significant digit before the decimal place.
7585 : */
7586 216 : if (var->ndigits > 0)
7587 : {
7588 198 : exponent = (var->weight + 1) * DEC_DIGITS;
7589 :
7590 : /*
7591 : * Compensate for leading decimal zeroes in the first numeric digit by
7592 : * decrementing the exponent.
7593 : */
7594 198 : exponent -= DEC_DIGITS - (int) log10(var->digits[0]);
7595 : }
7596 : else
7597 : {
7598 : /*
7599 : * If var has no digits, then it must be zero.
7600 : *
7601 : * Zero doesn't technically have a meaningful exponent in normalised
7602 : * notation, but we just display the exponent as zero for consistency
7603 : * of output.
7604 : */
7605 18 : exponent = 0;
7606 : }
7607 :
7608 : /*
7609 : * Divide var by 10^exponent to get the significand, rounding to rscale
7610 : * decimal digits in the process.
7611 : */
7612 216 : init_var(&tmp_var);
7613 :
7614 216 : power_ten_int(exponent, &tmp_var);
7615 216 : div_var(var, &tmp_var, &tmp_var, rscale, true);
7616 216 : sig_out = get_str_from_var(&tmp_var);
7617 :
7618 216 : free_var(&tmp_var);
7619 :
7620 : /*
7621 : * Allocate space for the result.
7622 : *
7623 : * In addition to the significand, we need room for the exponent
7624 : * decoration ("e"), the sign of the exponent, up to 10 digits for the
7625 : * exponent itself, and of course the null terminator.
7626 : */
7627 216 : len = strlen(sig_out) + 13;
7628 216 : str = palloc(len);
7629 216 : snprintf(str, len, "%se%+03d", sig_out, exponent);
7630 :
7631 216 : pfree(sig_out);
7632 :
7633 216 : return str;
7634 : }
7635 :
7636 :
7637 : /*
7638 : * numericvar_serialize - serialize NumericVar to binary format
7639 : *
7640 : * At variable level, no checks are performed on the weight or dscale, allowing
7641 : * us to pass around intermediate values with higher precision than supported
7642 : * by the numeric type. Note: this is incompatible with numeric_send/recv(),
7643 : * which use 16-bit integers for these fields.
7644 : */
7645 : static void
7646 102 : numericvar_serialize(StringInfo buf, const NumericVar *var)
7647 : {
7648 : int i;
7649 :
7650 102 : pq_sendint32(buf, var->ndigits);
7651 102 : pq_sendint32(buf, var->weight);
7652 102 : pq_sendint32(buf, var->sign);
7653 102 : pq_sendint32(buf, var->dscale);
7654 637802 : for (i = 0; i < var->ndigits; i++)
7655 637700 : pq_sendint16(buf, var->digits[i]);
7656 102 : }
7657 :
7658 : /*
7659 : * numericvar_deserialize - deserialize binary format to NumericVar
7660 : */
7661 : static void
7662 102 : numericvar_deserialize(StringInfo buf, NumericVar *var)
7663 : {
7664 : int len,
7665 : i;
7666 :
7667 102 : len = pq_getmsgint(buf, sizeof(int32));
7668 :
7669 102 : alloc_var(var, len); /* sets var->ndigits */
7670 :
7671 102 : var->weight = pq_getmsgint(buf, sizeof(int32));
7672 102 : var->sign = pq_getmsgint(buf, sizeof(int32));
7673 102 : var->dscale = pq_getmsgint(buf, sizeof(int32));
7674 637802 : for (i = 0; i < len; i++)
7675 637700 : var->digits[i] = pq_getmsgint(buf, sizeof(int16));
7676 102 : }
7677 :
7678 :
7679 : /*
7680 : * duplicate_numeric() - copy a packed-format Numeric
7681 : *
7682 : * This will handle NaN and Infinity cases.
7683 : */
7684 : static Numeric
7685 10218 : duplicate_numeric(Numeric num)
7686 : {
7687 : Numeric res;
7688 :
7689 10218 : res = (Numeric) palloc(VARSIZE(num));
7690 10218 : memcpy(res, num, VARSIZE(num));
7691 10218 : return res;
7692 : }
7693 :
7694 : /*
7695 : * make_result_opt_error() -
7696 : *
7697 : * Create the packed db numeric format in palloc()'d memory from
7698 : * a variable. This will handle NaN and Infinity cases.
7699 : *
7700 : * If "have_error" isn't NULL, on overflow *have_error is set to true and
7701 : * NULL is returned. This is helpful when caller needs to handle errors.
7702 : */
7703 : static Numeric
7704 3131136 : make_result_opt_error(const NumericVar *var, bool *have_error)
7705 : {
7706 : Numeric result;
7707 3131136 : NumericDigit *digits = var->digits;
7708 3131136 : int weight = var->weight;
7709 3131136 : int sign = var->sign;
7710 : int n;
7711 : Size len;
7712 :
7713 3131136 : if (have_error)
7714 98126 : *have_error = false;
7715 :
7716 3131136 : if ((sign & NUMERIC_SIGN_MASK) == NUMERIC_SPECIAL)
7717 : {
7718 : /*
7719 : * Verify valid special value. This could be just an Assert, perhaps,
7720 : * but it seems worthwhile to expend a few cycles to ensure that we
7721 : * never write any nonzero reserved bits to disk.
7722 : */
7723 5342 : if (!(sign == NUMERIC_NAN ||
7724 : sign == NUMERIC_PINF ||
7725 : sign == NUMERIC_NINF))
7726 0 : elog(ERROR, "invalid numeric sign value 0x%x", sign);
7727 :
7728 5342 : result = (Numeric) palloc(NUMERIC_HDRSZ_SHORT);
7729 :
7730 5342 : SET_VARSIZE(result, NUMERIC_HDRSZ_SHORT);
7731 5342 : result->choice.n_header = sign;
7732 : /* the header word is all we need */
7733 :
7734 : dump_numeric("make_result()", result);
7735 5342 : return result;
7736 : }
7737 :
7738 3125794 : n = var->ndigits;
7739 :
7740 : /* truncate leading zeroes */
7741 3125818 : while (n > 0 && *digits == 0)
7742 : {
7743 24 : digits++;
7744 24 : weight--;
7745 24 : n--;
7746 : }
7747 : /* truncate trailing zeroes */
7748 3210956 : while (n > 0 && digits[n - 1] == 0)
7749 85162 : n--;
7750 :
7751 : /* If zero result, force to weight=0 and positive sign */
7752 3125794 : if (n == 0)
7753 : {
7754 92130 : weight = 0;
7755 92130 : sign = NUMERIC_POS;
7756 : }
7757 :
7758 : /* Build the result */
7759 3125794 : if (NUMERIC_CAN_BE_SHORT(var->dscale, weight))
7760 : {
7761 3124054 : len = NUMERIC_HDRSZ_SHORT + n * sizeof(NumericDigit);
7762 3124054 : result = (Numeric) palloc(len);
7763 3124054 : SET_VARSIZE(result, len);
7764 3124054 : result->choice.n_short.n_header =
7765 : (sign == NUMERIC_NEG ? (NUMERIC_SHORT | NUMERIC_SHORT_SIGN_MASK)
7766 : : NUMERIC_SHORT)
7767 3124054 : | (var->dscale << NUMERIC_SHORT_DSCALE_SHIFT)
7768 3124054 : | (weight < 0 ? NUMERIC_SHORT_WEIGHT_SIGN_MASK : 0)
7769 3124054 : | (weight & NUMERIC_SHORT_WEIGHT_MASK);
7770 : }
7771 : else
7772 : {
7773 1740 : len = NUMERIC_HDRSZ + n * sizeof(NumericDigit);
7774 1740 : result = (Numeric) palloc(len);
7775 1740 : SET_VARSIZE(result, len);
7776 1740 : result->choice.n_long.n_sign_dscale =
7777 1740 : sign | (var->dscale & NUMERIC_DSCALE_MASK);
7778 1740 : result->choice.n_long.n_weight = weight;
7779 : }
7780 :
7781 : Assert(NUMERIC_NDIGITS(result) == n);
7782 3125794 : if (n > 0)
7783 3033664 : memcpy(NUMERIC_DIGITS(result), digits, n * sizeof(NumericDigit));
7784 :
7785 : /* Check for overflow of int16 fields */
7786 3125794 : if (NUMERIC_WEIGHT(result) != weight ||
7787 3125770 : NUMERIC_DSCALE(result) != var->dscale)
7788 : {
7789 24 : if (have_error)
7790 : {
7791 18 : *have_error = true;
7792 18 : return NULL;
7793 : }
7794 : else
7795 : {
7796 6 : ereport(ERROR,
7797 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
7798 : errmsg("value overflows numeric format")));
7799 : }
7800 : }
7801 :
7802 : dump_numeric("make_result()", result);
7803 3125770 : return result;
7804 : }
7805 :
7806 :
7807 : /*
7808 : * make_result() -
7809 : *
7810 : * An interface to make_result_opt_error() without "have_error" argument.
7811 : */
7812 : static Numeric
7813 2061910 : make_result(const NumericVar *var)
7814 : {
7815 2061910 : return make_result_opt_error(var, NULL);
7816 : }
7817 :
7818 :
7819 : /*
7820 : * apply_typmod() -
7821 : *
7822 : * Do bounds checking and rounding according to the specified typmod.
7823 : * Note that this is only applied to normal finite values.
7824 : *
7825 : * Returns true on success, false on failure (if escontext points to an
7826 : * ErrorSaveContext; otherwise errors are thrown).
7827 : */
7828 : static bool
7829 102568 : apply_typmod(NumericVar *var, int32 typmod, Node *escontext)
7830 : {
7831 : int precision;
7832 : int scale;
7833 : int maxdigits;
7834 : int ddigits;
7835 : int i;
7836 :
7837 : /* Do nothing if we have an invalid typmod */
7838 102568 : if (!is_valid_numeric_typmod(typmod))
7839 97934 : return true;
7840 :
7841 4634 : precision = numeric_typmod_precision(typmod);
7842 4634 : scale = numeric_typmod_scale(typmod);
7843 4634 : maxdigits = precision - scale;
7844 :
7845 : /* Round to target scale (and set var->dscale) */
7846 4634 : round_var(var, scale);
7847 :
7848 : /* but don't allow var->dscale to be negative */
7849 4634 : if (var->dscale < 0)
7850 108 : var->dscale = 0;
7851 :
7852 : /*
7853 : * Check for overflow - note we can't do this before rounding, because
7854 : * rounding could raise the weight. Also note that the var's weight could
7855 : * be inflated by leading zeroes, which will be stripped before storage
7856 : * but perhaps might not have been yet. In any case, we must recognize a
7857 : * true zero, whose weight doesn't mean anything.
7858 : */
7859 4634 : ddigits = (var->weight + 1) * DEC_DIGITS;
7860 4634 : if (ddigits > maxdigits)
7861 : {
7862 : /* Determine true weight; and check for all-zero result */
7863 374 : for (i = 0; i < var->ndigits; i++)
7864 : {
7865 358 : NumericDigit dig = var->digits[i];
7866 :
7867 358 : if (dig)
7868 : {
7869 : /* Adjust for any high-order decimal zero digits */
7870 : #if DEC_DIGITS == 4
7871 358 : if (dig < 10)
7872 234 : ddigits -= 3;
7873 124 : else if (dig < 100)
7874 60 : ddigits -= 2;
7875 64 : else if (dig < 1000)
7876 46 : ddigits -= 1;
7877 : #elif DEC_DIGITS == 2
7878 : if (dig < 10)
7879 : ddigits -= 1;
7880 : #elif DEC_DIGITS == 1
7881 : /* no adjustment */
7882 : #else
7883 : #error unsupported NBASE
7884 : #endif
7885 358 : if (ddigits > maxdigits)
7886 72 : ereturn(escontext, false,
7887 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
7888 : errmsg("numeric field overflow"),
7889 : errdetail("A field with precision %d, scale %d must round to an absolute value less than %s%d.",
7890 : precision, scale,
7891 : /* Display 10^0 as 1 */
7892 : maxdigits ? "10^" : "",
7893 : maxdigits ? maxdigits : 1
7894 : )));
7895 286 : break;
7896 : }
7897 0 : ddigits -= DEC_DIGITS;
7898 : }
7899 : }
7900 :
7901 4562 : return true;
7902 : }
7903 :
7904 : /*
7905 : * apply_typmod_special() -
7906 : *
7907 : * Do bounds checking according to the specified typmod, for an Inf or NaN.
7908 : * For convenience of most callers, the value is presented in packed form.
7909 : *
7910 : * Returns true on success, false on failure (if escontext points to an
7911 : * ErrorSaveContext; otherwise errors are thrown).
7912 : */
7913 : static bool
7914 1684 : apply_typmod_special(Numeric num, int32 typmod, Node *escontext)
7915 : {
7916 : int precision;
7917 : int scale;
7918 :
7919 : Assert(NUMERIC_IS_SPECIAL(num)); /* caller error if not */
7920 :
7921 : /*
7922 : * NaN is allowed regardless of the typmod; that's rather dubious perhaps,
7923 : * but it's a longstanding behavior. Inf is rejected if we have any
7924 : * typmod restriction, since an infinity shouldn't be claimed to fit in
7925 : * any finite number of digits.
7926 : */
7927 1684 : if (NUMERIC_IS_NAN(num))
7928 742 : return true;
7929 :
7930 : /* Do nothing if we have a default typmod (-1) */
7931 942 : if (!is_valid_numeric_typmod(typmod))
7932 924 : return true;
7933 :
7934 18 : precision = numeric_typmod_precision(typmod);
7935 18 : scale = numeric_typmod_scale(typmod);
7936 :
7937 18 : ereturn(escontext, false,
7938 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
7939 : errmsg("numeric field overflow"),
7940 : errdetail("A field with precision %d, scale %d cannot hold an infinite value.",
7941 : precision, scale)));
7942 : }
7943 :
7944 :
7945 : /*
7946 : * Convert numeric to int8, rounding if needed.
7947 : *
7948 : * If overflow, return false (no error is raised). Return true if okay.
7949 : */
7950 : static bool
7951 9538 : numericvar_to_int64(const NumericVar *var, int64 *result)
7952 : {
7953 : NumericDigit *digits;
7954 : int ndigits;
7955 : int weight;
7956 : int i;
7957 : int64 val;
7958 : bool neg;
7959 : NumericVar rounded;
7960 :
7961 : /* Round to nearest integer */
7962 9538 : init_var(&rounded);
7963 9538 : set_var_from_var(var, &rounded);
7964 9538 : round_var(&rounded, 0);
7965 :
7966 : /* Check for zero input */
7967 9538 : strip_var(&rounded);
7968 9538 : ndigits = rounded.ndigits;
7969 9538 : if (ndigits == 0)
7970 : {
7971 352 : *result = 0;
7972 352 : free_var(&rounded);
7973 352 : return true;
7974 : }
7975 :
7976 : /*
7977 : * For input like 10000000000, we must treat stripped digits as real. So
7978 : * the loop assumes there are weight+1 digits before the decimal point.
7979 : */
7980 9186 : weight = rounded.weight;
7981 : Assert(weight >= 0 && ndigits <= weight + 1);
7982 :
7983 : /*
7984 : * Construct the result. To avoid issues with converting a value
7985 : * corresponding to INT64_MIN (which can't be represented as a positive 64
7986 : * bit two's complement integer), accumulate value as a negative number.
7987 : */
7988 9186 : digits = rounded.digits;
7989 9186 : neg = (rounded.sign == NUMERIC_NEG);
7990 9186 : val = -digits[0];
7991 13960 : for (i = 1; i <= weight; i++)
7992 : {
7993 4804 : if (unlikely(pg_mul_s64_overflow(val, NBASE, &val)))
7994 : {
7995 12 : free_var(&rounded);
7996 12 : return false;
7997 : }
7998 :
7999 4792 : if (i < ndigits)
8000 : {
8001 4582 : if (unlikely(pg_sub_s64_overflow(val, digits[i], &val)))
8002 : {
8003 18 : free_var(&rounded);
8004 18 : return false;
8005 : }
8006 : }
8007 : }
8008 :
8009 9156 : free_var(&rounded);
8010 :
8011 9156 : if (!neg)
8012 : {
8013 8550 : if (unlikely(val == PG_INT64_MIN))
8014 24 : return false;
8015 8526 : val = -val;
8016 : }
8017 9132 : *result = val;
8018 :
8019 9132 : return true;
8020 : }
8021 :
8022 : /*
8023 : * Convert int8 value to numeric.
8024 : */
8025 : static void
8026 1847844 : int64_to_numericvar(int64 val, NumericVar *var)
8027 : {
8028 : uint64 uval,
8029 : newuval;
8030 : NumericDigit *ptr;
8031 : int ndigits;
8032 :
8033 : /* int64 can require at most 19 decimal digits; add one for safety */
8034 1847844 : alloc_var(var, 20 / DEC_DIGITS);
8035 1847844 : if (val < 0)
8036 : {
8037 1472 : var->sign = NUMERIC_NEG;
8038 1472 : uval = -val;
8039 : }
8040 : else
8041 : {
8042 1846372 : var->sign = NUMERIC_POS;
8043 1846372 : uval = val;
8044 : }
8045 1847844 : var->dscale = 0;
8046 1847844 : if (val == 0)
8047 : {
8048 34148 : var->ndigits = 0;
8049 34148 : var->weight = 0;
8050 34148 : return;
8051 : }
8052 1813696 : ptr = var->digits + var->ndigits;
8053 1813696 : ndigits = 0;
8054 : do
8055 : {
8056 2120748 : ptr--;
8057 2120748 : ndigits++;
8058 2120748 : newuval = uval / NBASE;
8059 2120748 : *ptr = uval - newuval * NBASE;
8060 2120748 : uval = newuval;
8061 2120748 : } while (uval);
8062 1813696 : var->digits = ptr;
8063 1813696 : var->ndigits = ndigits;
8064 1813696 : var->weight = ndigits - 1;
8065 : }
8066 :
8067 : /*
8068 : * Convert numeric to uint64, rounding if needed.
8069 : *
8070 : * If overflow, return false (no error is raised). Return true if okay.
8071 : */
8072 : static bool
8073 114 : numericvar_to_uint64(const NumericVar *var, uint64 *result)
8074 : {
8075 : NumericDigit *digits;
8076 : int ndigits;
8077 : int weight;
8078 : int i;
8079 : uint64 val;
8080 : NumericVar rounded;
8081 :
8082 : /* Round to nearest integer */
8083 114 : init_var(&rounded);
8084 114 : set_var_from_var(var, &rounded);
8085 114 : round_var(&rounded, 0);
8086 :
8087 : /* Check for zero input */
8088 114 : strip_var(&rounded);
8089 114 : ndigits = rounded.ndigits;
8090 114 : if (ndigits == 0)
8091 : {
8092 18 : *result = 0;
8093 18 : free_var(&rounded);
8094 18 : return true;
8095 : }
8096 :
8097 : /* Check for negative input */
8098 96 : if (rounded.sign == NUMERIC_NEG)
8099 : {
8100 12 : free_var(&rounded);
8101 12 : return false;
8102 : }
8103 :
8104 : /*
8105 : * For input like 10000000000, we must treat stripped digits as real. So
8106 : * the loop assumes there are weight+1 digits before the decimal point.
8107 : */
8108 84 : weight = rounded.weight;
8109 : Assert(weight >= 0 && ndigits <= weight + 1);
8110 :
8111 : /* Construct the result */
8112 84 : digits = rounded.digits;
8113 84 : val = digits[0];
8114 246 : for (i = 1; i <= weight; i++)
8115 : {
8116 174 : if (unlikely(pg_mul_u64_overflow(val, NBASE, &val)))
8117 : {
8118 0 : free_var(&rounded);
8119 0 : return false;
8120 : }
8121 :
8122 174 : if (i < ndigits)
8123 : {
8124 174 : if (unlikely(pg_add_u64_overflow(val, digits[i], &val)))
8125 : {
8126 12 : free_var(&rounded);
8127 12 : return false;
8128 : }
8129 : }
8130 : }
8131 :
8132 72 : free_var(&rounded);
8133 :
8134 72 : *result = val;
8135 :
8136 72 : return true;
8137 : }
8138 :
8139 : #ifdef HAVE_INT128
8140 : /*
8141 : * Convert numeric to int128, rounding if needed.
8142 : *
8143 : * If overflow, return false (no error is raised). Return true if okay.
8144 : */
8145 : static bool
8146 36 : numericvar_to_int128(const NumericVar *var, int128 *result)
8147 : {
8148 : NumericDigit *digits;
8149 : int ndigits;
8150 : int weight;
8151 : int i;
8152 : int128 val,
8153 : oldval;
8154 : bool neg;
8155 : NumericVar rounded;
8156 :
8157 : /* Round to nearest integer */
8158 36 : init_var(&rounded);
8159 36 : set_var_from_var(var, &rounded);
8160 36 : round_var(&rounded, 0);
8161 :
8162 : /* Check for zero input */
8163 36 : strip_var(&rounded);
8164 36 : ndigits = rounded.ndigits;
8165 36 : if (ndigits == 0)
8166 : {
8167 0 : *result = 0;
8168 0 : free_var(&rounded);
8169 0 : return true;
8170 : }
8171 :
8172 : /*
8173 : * For input like 10000000000, we must treat stripped digits as real. So
8174 : * the loop assumes there are weight+1 digits before the decimal point.
8175 : */
8176 36 : weight = rounded.weight;
8177 : Assert(weight >= 0 && ndigits <= weight + 1);
8178 :
8179 : /* Construct the result */
8180 36 : digits = rounded.digits;
8181 36 : neg = (rounded.sign == NUMERIC_NEG);
8182 36 : val = digits[0];
8183 96 : for (i = 1; i <= weight; i++)
8184 : {
8185 60 : oldval = val;
8186 60 : val *= NBASE;
8187 60 : if (i < ndigits)
8188 54 : val += digits[i];
8189 :
8190 : /*
8191 : * The overflow check is a bit tricky because we want to accept
8192 : * INT128_MIN, which will overflow the positive accumulator. We can
8193 : * detect this case easily though because INT128_MIN is the only
8194 : * nonzero value for which -val == val (on a two's complement machine,
8195 : * anyway).
8196 : */
8197 60 : if ((val / NBASE) != oldval) /* possible overflow? */
8198 : {
8199 0 : if (!neg || (-val) != val || val == 0 || oldval < 0)
8200 : {
8201 0 : free_var(&rounded);
8202 0 : return false;
8203 : }
8204 : }
8205 : }
8206 :
8207 36 : free_var(&rounded);
8208 :
8209 36 : *result = neg ? -val : val;
8210 36 : return true;
8211 : }
8212 :
8213 : /*
8214 : * Convert 128 bit integer to numeric.
8215 : */
8216 : static void
8217 8552 : int128_to_numericvar(int128 val, NumericVar *var)
8218 : {
8219 : uint128 uval,
8220 : newuval;
8221 : NumericDigit *ptr;
8222 : int ndigits;
8223 :
8224 : /* int128 can require at most 39 decimal digits; add one for safety */
8225 8552 : alloc_var(var, 40 / DEC_DIGITS);
8226 8552 : if (val < 0)
8227 : {
8228 0 : var->sign = NUMERIC_NEG;
8229 0 : uval = -val;
8230 : }
8231 : else
8232 : {
8233 8552 : var->sign = NUMERIC_POS;
8234 8552 : uval = val;
8235 : }
8236 8552 : var->dscale = 0;
8237 8552 : if (val == 0)
8238 : {
8239 122 : var->ndigits = 0;
8240 122 : var->weight = 0;
8241 122 : return;
8242 : }
8243 8430 : ptr = var->digits + var->ndigits;
8244 8430 : ndigits = 0;
8245 : do
8246 : {
8247 44906 : ptr--;
8248 44906 : ndigits++;
8249 44906 : newuval = uval / NBASE;
8250 44906 : *ptr = uval - newuval * NBASE;
8251 44906 : uval = newuval;
8252 44906 : } while (uval);
8253 8430 : var->digits = ptr;
8254 8430 : var->ndigits = ndigits;
8255 8430 : var->weight = ndigits - 1;
8256 : }
8257 : #endif
8258 :
8259 : /*
8260 : * Convert a NumericVar to float8; if out of range, return +/- HUGE_VAL
8261 : */
8262 : static double
8263 3234 : numericvar_to_double_no_overflow(const NumericVar *var)
8264 : {
8265 : char *tmp;
8266 : double val;
8267 : char *endptr;
8268 :
8269 3234 : tmp = get_str_from_var(var);
8270 :
8271 : /* unlike float8in, we ignore ERANGE from strtod */
8272 3234 : val = strtod(tmp, &endptr);
8273 3234 : if (*endptr != '\0')
8274 : {
8275 : /* shouldn't happen ... */
8276 0 : ereport(ERROR,
8277 : (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
8278 : errmsg("invalid input syntax for type %s: \"%s\"",
8279 : "double precision", tmp)));
8280 : }
8281 :
8282 3234 : pfree(tmp);
8283 :
8284 3234 : return val;
8285 : }
8286 :
8287 :
8288 : /*
8289 : * cmp_var() -
8290 : *
8291 : * Compare two values on variable level. We assume zeroes have been
8292 : * truncated to no digits.
8293 : */
8294 : static int
8295 16766 : cmp_var(const NumericVar *var1, const NumericVar *var2)
8296 : {
8297 33532 : return cmp_var_common(var1->digits, var1->ndigits,
8298 : var1->weight, var1->sign,
8299 16766 : var2->digits, var2->ndigits,
8300 : var2->weight, var2->sign);
8301 : }
8302 :
8303 : /*
8304 : * cmp_var_common() -
8305 : *
8306 : * Main routine of cmp_var(). This function can be used by both
8307 : * NumericVar and Numeric.
8308 : */
8309 : static int
8310 6025132 : cmp_var_common(const NumericDigit *var1digits, int var1ndigits,
8311 : int var1weight, int var1sign,
8312 : const NumericDigit *var2digits, int var2ndigits,
8313 : int var2weight, int var2sign)
8314 : {
8315 6025132 : if (var1ndigits == 0)
8316 : {
8317 185534 : if (var2ndigits == 0)
8318 157242 : return 0;
8319 28292 : if (var2sign == NUMERIC_NEG)
8320 4384 : return 1;
8321 23908 : return -1;
8322 : }
8323 5839598 : if (var2ndigits == 0)
8324 : {
8325 32548 : if (var1sign == NUMERIC_POS)
8326 25270 : return 1;
8327 7278 : return -1;
8328 : }
8329 :
8330 5807050 : if (var1sign == NUMERIC_POS)
8331 : {
8332 5752520 : if (var2sign == NUMERIC_NEG)
8333 11482 : return 1;
8334 5741038 : return cmp_abs_common(var1digits, var1ndigits, var1weight,
8335 : var2digits, var2ndigits, var2weight);
8336 : }
8337 :
8338 54530 : if (var2sign == NUMERIC_POS)
8339 12628 : return -1;
8340 :
8341 41902 : return cmp_abs_common(var2digits, var2ndigits, var2weight,
8342 : var1digits, var1ndigits, var1weight);
8343 : }
8344 :
8345 :
8346 : /*
8347 : * add_var() -
8348 : *
8349 : * Full version of add functionality on variable level (handling signs).
8350 : * result might point to one of the operands too without danger.
8351 : */
8352 : static void
8353 463892 : add_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
8354 : {
8355 : /*
8356 : * Decide on the signs of the two variables what to do
8357 : */
8358 463892 : if (var1->sign == NUMERIC_POS)
8359 : {
8360 462326 : if (var2->sign == NUMERIC_POS)
8361 : {
8362 : /*
8363 : * Both are positive result = +(ABS(var1) + ABS(var2))
8364 : */
8365 289280 : add_abs(var1, var2, result);
8366 289280 : result->sign = NUMERIC_POS;
8367 : }
8368 : else
8369 : {
8370 : /*
8371 : * var1 is positive, var2 is negative Must compare absolute values
8372 : */
8373 173046 : switch (cmp_abs(var1, var2))
8374 : {
8375 32 : case 0:
8376 : /* ----------
8377 : * ABS(var1) == ABS(var2)
8378 : * result = ZERO
8379 : * ----------
8380 : */
8381 32 : zero_var(result);
8382 32 : result->dscale = Max(var1->dscale, var2->dscale);
8383 32 : break;
8384 :
8385 172726 : case 1:
8386 : /* ----------
8387 : * ABS(var1) > ABS(var2)
8388 : * result = +(ABS(var1) - ABS(var2))
8389 : * ----------
8390 : */
8391 172726 : sub_abs(var1, var2, result);
8392 172726 : result->sign = NUMERIC_POS;
8393 172726 : break;
8394 :
8395 288 : case -1:
8396 : /* ----------
8397 : * ABS(var1) < ABS(var2)
8398 : * result = -(ABS(var2) - ABS(var1))
8399 : * ----------
8400 : */
8401 288 : sub_abs(var2, var1, result);
8402 288 : result->sign = NUMERIC_NEG;
8403 288 : break;
8404 : }
8405 462326 : }
8406 : }
8407 : else
8408 : {
8409 1566 : if (var2->sign == NUMERIC_POS)
8410 : {
8411 : /* ----------
8412 : * var1 is negative, var2 is positive
8413 : * Must compare absolute values
8414 : * ----------
8415 : */
8416 468 : switch (cmp_abs(var1, var2))
8417 : {
8418 30 : case 0:
8419 : /* ----------
8420 : * ABS(var1) == ABS(var2)
8421 : * result = ZERO
8422 : * ----------
8423 : */
8424 30 : zero_var(result);
8425 30 : result->dscale = Max(var1->dscale, var2->dscale);
8426 30 : break;
8427 :
8428 294 : case 1:
8429 : /* ----------
8430 : * ABS(var1) > ABS(var2)
8431 : * result = -(ABS(var1) - ABS(var2))
8432 : * ----------
8433 : */
8434 294 : sub_abs(var1, var2, result);
8435 294 : result->sign = NUMERIC_NEG;
8436 294 : break;
8437 :
8438 144 : case -1:
8439 : /* ----------
8440 : * ABS(var1) < ABS(var2)
8441 : * result = +(ABS(var2) - ABS(var1))
8442 : * ----------
8443 : */
8444 144 : sub_abs(var2, var1, result);
8445 144 : result->sign = NUMERIC_POS;
8446 144 : break;
8447 : }
8448 468 : }
8449 : else
8450 : {
8451 : /* ----------
8452 : * Both are negative
8453 : * result = -(ABS(var1) + ABS(var2))
8454 : * ----------
8455 : */
8456 1098 : add_abs(var1, var2, result);
8457 1098 : result->sign = NUMERIC_NEG;
8458 : }
8459 : }
8460 463892 : }
8461 :
8462 :
8463 : /*
8464 : * sub_var() -
8465 : *
8466 : * Full version of sub functionality on variable level (handling signs).
8467 : * result might point to one of the operands too without danger.
8468 : */
8469 : static void
8470 118060 : sub_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
8471 : {
8472 : /*
8473 : * Decide on the signs of the two variables what to do
8474 : */
8475 118060 : if (var1->sign == NUMERIC_POS)
8476 : {
8477 115320 : if (var2->sign == NUMERIC_NEG)
8478 : {
8479 : /* ----------
8480 : * var1 is positive, var2 is negative
8481 : * result = +(ABS(var1) + ABS(var2))
8482 : * ----------
8483 : */
8484 5802 : add_abs(var1, var2, result);
8485 5802 : result->sign = NUMERIC_POS;
8486 : }
8487 : else
8488 : {
8489 : /* ----------
8490 : * Both are positive
8491 : * Must compare absolute values
8492 : * ----------
8493 : */
8494 109518 : switch (cmp_abs(var1, var2))
8495 : {
8496 29516 : case 0:
8497 : /* ----------
8498 : * ABS(var1) == ABS(var2)
8499 : * result = ZERO
8500 : * ----------
8501 : */
8502 29516 : zero_var(result);
8503 29516 : result->dscale = Max(var1->dscale, var2->dscale);
8504 29516 : break;
8505 :
8506 79476 : case 1:
8507 : /* ----------
8508 : * ABS(var1) > ABS(var2)
8509 : * result = +(ABS(var1) - ABS(var2))
8510 : * ----------
8511 : */
8512 79476 : sub_abs(var1, var2, result);
8513 79476 : result->sign = NUMERIC_POS;
8514 79476 : break;
8515 :
8516 526 : case -1:
8517 : /* ----------
8518 : * ABS(var1) < ABS(var2)
8519 : * result = -(ABS(var2) - ABS(var1))
8520 : * ----------
8521 : */
8522 526 : sub_abs(var2, var1, result);
8523 526 : result->sign = NUMERIC_NEG;
8524 526 : break;
8525 : }
8526 115320 : }
8527 : }
8528 : else
8529 : {
8530 2740 : if (var2->sign == NUMERIC_NEG)
8531 : {
8532 : /* ----------
8533 : * Both are negative
8534 : * Must compare absolute values
8535 : * ----------
8536 : */
8537 2290 : switch (cmp_abs(var1, var2))
8538 : {
8539 166 : case 0:
8540 : /* ----------
8541 : * ABS(var1) == ABS(var2)
8542 : * result = ZERO
8543 : * ----------
8544 : */
8545 166 : zero_var(result);
8546 166 : result->dscale = Max(var1->dscale, var2->dscale);
8547 166 : break;
8548 :
8549 234 : case 1:
8550 : /* ----------
8551 : * ABS(var1) > ABS(var2)
8552 : * result = -(ABS(var1) - ABS(var2))
8553 : * ----------
8554 : */
8555 234 : sub_abs(var1, var2, result);
8556 234 : result->sign = NUMERIC_NEG;
8557 234 : break;
8558 :
8559 1890 : case -1:
8560 : /* ----------
8561 : * ABS(var1) < ABS(var2)
8562 : * result = +(ABS(var2) - ABS(var1))
8563 : * ----------
8564 : */
8565 1890 : sub_abs(var2, var1, result);
8566 1890 : result->sign = NUMERIC_POS;
8567 1890 : break;
8568 : }
8569 2290 : }
8570 : else
8571 : {
8572 : /* ----------
8573 : * var1 is negative, var2 is positive
8574 : * result = -(ABS(var1) + ABS(var2))
8575 : * ----------
8576 : */
8577 450 : add_abs(var1, var2, result);
8578 450 : result->sign = NUMERIC_NEG;
8579 : }
8580 : }
8581 118060 : }
8582 :
8583 :
8584 : /*
8585 : * mul_var() -
8586 : *
8587 : * Multiplication on variable level. Product of var1 * var2 is stored
8588 : * in result. Result is rounded to no more than rscale fractional digits.
8589 : */
8590 : static void
8591 829498 : mul_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result,
8592 : int rscale)
8593 : {
8594 : int res_ndigits;
8595 : int res_sign;
8596 : int res_weight;
8597 : int maxdigits;
8598 : int *dig;
8599 : int carry;
8600 : int maxdig;
8601 : int newdig;
8602 : int var1ndigits;
8603 : int var2ndigits;
8604 : NumericDigit *var1digits;
8605 : NumericDigit *var2digits;
8606 : NumericDigit *res_digits;
8607 : int i,
8608 : i1,
8609 : i2;
8610 :
8611 : /*
8612 : * Arrange for var1 to be the shorter of the two numbers. This improves
8613 : * performance because the inner multiplication loop is much simpler than
8614 : * the outer loop, so it's better to have a smaller number of iterations
8615 : * of the outer loop. This also reduces the number of times that the
8616 : * accumulator array needs to be normalized.
8617 : */
8618 829498 : if (var1->ndigits > var2->ndigits)
8619 : {
8620 14812 : const NumericVar *tmp = var1;
8621 :
8622 14812 : var1 = var2;
8623 14812 : var2 = tmp;
8624 : }
8625 :
8626 : /* copy these values into local vars for speed in inner loop */
8627 829498 : var1ndigits = var1->ndigits;
8628 829498 : var2ndigits = var2->ndigits;
8629 829498 : var1digits = var1->digits;
8630 829498 : var2digits = var2->digits;
8631 :
8632 829498 : if (var1ndigits == 0 || var2ndigits == 0)
8633 : {
8634 : /* one or both inputs is zero; so is result */
8635 1712 : zero_var(result);
8636 1712 : result->dscale = rscale;
8637 1712 : return;
8638 : }
8639 :
8640 : /* Determine result sign and (maximum possible) weight */
8641 827786 : if (var1->sign == var2->sign)
8642 825256 : res_sign = NUMERIC_POS;
8643 : else
8644 2530 : res_sign = NUMERIC_NEG;
8645 827786 : res_weight = var1->weight + var2->weight + 2;
8646 :
8647 : /*
8648 : * Determine the number of result digits to compute. If the exact result
8649 : * would have more than rscale fractional digits, truncate the computation
8650 : * with MUL_GUARD_DIGITS guard digits, i.e., ignore input digits that
8651 : * would only contribute to the right of that. (This will give the exact
8652 : * rounded-to-rscale answer unless carries out of the ignored positions
8653 : * would have propagated through more than MUL_GUARD_DIGITS digits.)
8654 : *
8655 : * Note: an exact computation could not produce more than var1ndigits +
8656 : * var2ndigits digits, but we allocate one extra output digit in case
8657 : * rscale-driven rounding produces a carry out of the highest exact digit.
8658 : */
8659 827786 : res_ndigits = var1ndigits + var2ndigits + 1;
8660 827786 : maxdigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS +
8661 : MUL_GUARD_DIGITS;
8662 827786 : res_ndigits = Min(res_ndigits, maxdigits);
8663 :
8664 827786 : if (res_ndigits < 3)
8665 : {
8666 : /* All input digits will be ignored; so result is zero */
8667 12 : zero_var(result);
8668 12 : result->dscale = rscale;
8669 12 : return;
8670 : }
8671 :
8672 : /*
8673 : * We do the arithmetic in an array "dig[]" of signed int's. Since
8674 : * INT_MAX is noticeably larger than NBASE*NBASE, this gives us headroom
8675 : * to avoid normalizing carries immediately.
8676 : *
8677 : * maxdig tracks the maximum possible value of any dig[] entry; when this
8678 : * threatens to exceed INT_MAX, we take the time to propagate carries.
8679 : * Furthermore, we need to ensure that overflow doesn't occur during the
8680 : * carry propagation passes either. The carry values could be as much as
8681 : * INT_MAX/NBASE, so really we must normalize when digits threaten to
8682 : * exceed INT_MAX - INT_MAX/NBASE.
8683 : *
8684 : * To avoid overflow in maxdig itself, it actually represents the max
8685 : * possible value divided by NBASE-1, ie, at the top of the loop it is
8686 : * known that no dig[] entry exceeds maxdig * (NBASE-1).
8687 : */
8688 827774 : dig = (int *) palloc0(res_ndigits * sizeof(int));
8689 827774 : maxdig = 0;
8690 :
8691 : /*
8692 : * The least significant digits of var1 should be ignored if they don't
8693 : * contribute directly to the first res_ndigits digits of the result that
8694 : * we are computing.
8695 : *
8696 : * Digit i1 of var1 and digit i2 of var2 are multiplied and added to digit
8697 : * i1+i2+2 of the accumulator array, so we need only consider digits of
8698 : * var1 for which i1 <= res_ndigits - 3.
8699 : */
8700 4631416 : for (i1 = Min(var1ndigits - 1, res_ndigits - 3); i1 >= 0; i1--)
8701 : {
8702 3803642 : NumericDigit var1digit = var1digits[i1];
8703 :
8704 3803642 : if (var1digit == 0)
8705 2359440 : continue;
8706 :
8707 : /* Time to normalize? */
8708 1444202 : maxdig += var1digit;
8709 1444202 : if (maxdig > (INT_MAX - INT_MAX / NBASE) / (NBASE - 1))
8710 : {
8711 : /* Yes, do it */
8712 9144 : carry = 0;
8713 45810696 : for (i = res_ndigits - 1; i >= 0; i--)
8714 : {
8715 45801552 : newdig = dig[i] + carry;
8716 45801552 : if (newdig >= NBASE)
8717 : {
8718 23065602 : carry = newdig / NBASE;
8719 23065602 : newdig -= carry * NBASE;
8720 : }
8721 : else
8722 22735950 : carry = 0;
8723 45801552 : dig[i] = newdig;
8724 : }
8725 : Assert(carry == 0);
8726 : /* Reset maxdig to indicate new worst-case */
8727 9144 : maxdig = 1 + var1digit;
8728 : }
8729 :
8730 : /*
8731 : * Add the appropriate multiple of var2 into the accumulator.
8732 : *
8733 : * As above, digits of var2 can be ignored if they don't contribute,
8734 : * so we only include digits for which i1+i2+2 < res_ndigits.
8735 : *
8736 : * This inner loop is the performance bottleneck for multiplication,
8737 : * so we want to keep it simple enough so that it can be
8738 : * auto-vectorized. Accordingly, process the digits left-to-right
8739 : * even though schoolbook multiplication would suggest right-to-left.
8740 : * Since we aren't propagating carries in this loop, the order does
8741 : * not matter.
8742 : */
8743 : {
8744 1444202 : int i2limit = Min(var2ndigits, res_ndigits - i1 - 2);
8745 1444202 : int *dig_i1_2 = &dig[i1 + 2];
8746 :
8747 499116046 : for (i2 = 0; i2 < i2limit; i2++)
8748 497671844 : dig_i1_2[i2] += var1digit * var2digits[i2];
8749 : }
8750 : }
8751 :
8752 : /*
8753 : * Now we do a final carry propagation pass to normalize the result, which
8754 : * we combine with storing the result digits into the output. Note that
8755 : * this is still done at full precision w/guard digits.
8756 : */
8757 827774 : alloc_var(result, res_ndigits);
8758 827774 : res_digits = result->digits;
8759 827774 : carry = 0;
8760 10237346 : for (i = res_ndigits - 1; i >= 0; i--)
8761 : {
8762 9409572 : newdig = dig[i] + carry;
8763 9409572 : if (newdig >= NBASE)
8764 : {
8765 1983020 : carry = newdig / NBASE;
8766 1983020 : newdig -= carry * NBASE;
8767 : }
8768 : else
8769 7426552 : carry = 0;
8770 9409572 : res_digits[i] = newdig;
8771 : }
8772 : Assert(carry == 0);
8773 :
8774 827774 : pfree(dig);
8775 :
8776 : /*
8777 : * Finally, round the result to the requested precision.
8778 : */
8779 827774 : result->weight = res_weight;
8780 827774 : result->sign = res_sign;
8781 :
8782 : /* Round to target rscale (and set result->dscale) */
8783 827774 : round_var(result, rscale);
8784 :
8785 : /* Strip leading and trailing zeroes */
8786 827774 : strip_var(result);
8787 : }
8788 :
8789 :
8790 : /*
8791 : * div_var() -
8792 : *
8793 : * Division on variable level. Quotient of var1 / var2 is stored in result.
8794 : * The quotient is figured to exactly rscale fractional digits.
8795 : * If round is true, it is rounded at the rscale'th digit; if false, it
8796 : * is truncated (towards zero) at that digit.
8797 : */
8798 : static void
8799 178806 : div_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result,
8800 : int rscale, bool round)
8801 : {
8802 : int div_ndigits;
8803 : int res_ndigits;
8804 : int res_sign;
8805 : int res_weight;
8806 : int carry;
8807 : int borrow;
8808 : int divisor1;
8809 : int divisor2;
8810 : NumericDigit *dividend;
8811 : NumericDigit *divisor;
8812 : NumericDigit *res_digits;
8813 : int i;
8814 : int j;
8815 :
8816 : /* copy these values into local vars for speed in inner loop */
8817 178806 : int var1ndigits = var1->ndigits;
8818 178806 : int var2ndigits = var2->ndigits;
8819 :
8820 : /*
8821 : * First of all division by zero check; we must not be handed an
8822 : * unnormalized divisor.
8823 : */
8824 178806 : if (var2ndigits == 0 || var2->digits[0] == 0)
8825 56 : ereport(ERROR,
8826 : (errcode(ERRCODE_DIVISION_BY_ZERO),
8827 : errmsg("division by zero")));
8828 :
8829 : /*
8830 : * If the divisor has just one or two digits, delegate to div_var_int(),
8831 : * which uses fast short division.
8832 : *
8833 : * Similarly, on platforms with 128-bit integer support, delegate to
8834 : * div_var_int64() for divisors with three or four digits.
8835 : */
8836 178750 : if (var2ndigits <= 2)
8837 : {
8838 : int idivisor;
8839 : int idivisor_weight;
8840 :
8841 175304 : idivisor = var2->digits[0];
8842 175304 : idivisor_weight = var2->weight;
8843 175304 : if (var2ndigits == 2)
8844 : {
8845 4704 : idivisor = idivisor * NBASE + var2->digits[1];
8846 4704 : idivisor_weight--;
8847 : }
8848 175304 : if (var2->sign == NUMERIC_NEG)
8849 486 : idivisor = -idivisor;
8850 :
8851 175304 : div_var_int(var1, idivisor, idivisor_weight, result, rscale, round);
8852 175304 : return;
8853 : }
8854 : #ifdef HAVE_INT128
8855 3446 : if (var2ndigits <= 4)
8856 : {
8857 : int64 idivisor;
8858 : int idivisor_weight;
8859 :
8860 494 : idivisor = var2->digits[0];
8861 494 : idivisor_weight = var2->weight;
8862 1856 : for (i = 1; i < var2ndigits; i++)
8863 : {
8864 1362 : idivisor = idivisor * NBASE + var2->digits[i];
8865 1362 : idivisor_weight--;
8866 : }
8867 494 : if (var2->sign == NUMERIC_NEG)
8868 120 : idivisor = -idivisor;
8869 :
8870 494 : div_var_int64(var1, idivisor, idivisor_weight, result, rscale, round);
8871 494 : return;
8872 : }
8873 : #endif
8874 :
8875 : /*
8876 : * Otherwise, perform full long division.
8877 : */
8878 :
8879 : /* Result zero check */
8880 2952 : if (var1ndigits == 0)
8881 : {
8882 24 : zero_var(result);
8883 24 : result->dscale = rscale;
8884 24 : return;
8885 : }
8886 :
8887 : /*
8888 : * Determine the result sign, weight and number of digits to calculate.
8889 : * The weight figured here is correct if the emitted quotient has no
8890 : * leading zero digits; otherwise strip_var() will fix things up.
8891 : */
8892 2928 : if (var1->sign == var2->sign)
8893 2868 : res_sign = NUMERIC_POS;
8894 : else
8895 60 : res_sign = NUMERIC_NEG;
8896 2928 : res_weight = var1->weight - var2->weight;
8897 : /* The number of accurate result digits we need to produce: */
8898 2928 : res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
8899 : /* ... but always at least 1 */
8900 2928 : res_ndigits = Max(res_ndigits, 1);
8901 : /* If rounding needed, figure one more digit to ensure correct result */
8902 2928 : if (round)
8903 2928 : res_ndigits++;
8904 :
8905 : /*
8906 : * The working dividend normally requires res_ndigits + var2ndigits
8907 : * digits, but make it at least var1ndigits so we can load all of var1
8908 : * into it. (There will be an additional digit dividend[0] in the
8909 : * dividend space, but for consistency with Knuth's notation we don't
8910 : * count that in div_ndigits.)
8911 : */
8912 2928 : div_ndigits = res_ndigits + var2ndigits;
8913 2928 : div_ndigits = Max(div_ndigits, var1ndigits);
8914 :
8915 : /*
8916 : * We need a workspace with room for the working dividend (div_ndigits+1
8917 : * digits) plus room for the possibly-normalized divisor (var2ndigits
8918 : * digits). It is convenient also to have a zero at divisor[0] with the
8919 : * actual divisor data in divisor[1 .. var2ndigits]. Transferring the
8920 : * digits into the workspace also allows us to realloc the result (which
8921 : * might be the same as either input var) before we begin the main loop.
8922 : * Note that we use palloc0 to ensure that divisor[0], dividend[0], and
8923 : * any additional dividend positions beyond var1ndigits, start out 0.
8924 : */
8925 : dividend = (NumericDigit *)
8926 2928 : palloc0((div_ndigits + var2ndigits + 2) * sizeof(NumericDigit));
8927 2928 : divisor = dividend + (div_ndigits + 1);
8928 2928 : memcpy(dividend + 1, var1->digits, var1ndigits * sizeof(NumericDigit));
8929 2928 : memcpy(divisor + 1, var2->digits, var2ndigits * sizeof(NumericDigit));
8930 :
8931 : /*
8932 : * Now we can realloc the result to hold the generated quotient digits.
8933 : */
8934 2928 : alloc_var(result, res_ndigits);
8935 2928 : res_digits = result->digits;
8936 :
8937 : /*
8938 : * The full multiple-place algorithm is taken from Knuth volume 2,
8939 : * Algorithm 4.3.1D.
8940 : *
8941 : * We need the first divisor digit to be >= NBASE/2. If it isn't, make it
8942 : * so by scaling up both the divisor and dividend by the factor "d". (The
8943 : * reason for allocating dividend[0] above is to leave room for possible
8944 : * carry here.)
8945 : */
8946 2928 : if (divisor[1] < HALF_NBASE)
8947 : {
8948 2928 : int d = NBASE / (divisor[1] + 1);
8949 :
8950 2928 : carry = 0;
8951 25110 : for (i = var2ndigits; i > 0; i--)
8952 : {
8953 22182 : carry += divisor[i] * d;
8954 22182 : divisor[i] = carry % NBASE;
8955 22182 : carry = carry / NBASE;
8956 : }
8957 : Assert(carry == 0);
8958 2928 : carry = 0;
8959 : /* at this point only var1ndigits of dividend can be nonzero */
8960 26026 : for (i = var1ndigits; i >= 0; i--)
8961 : {
8962 23098 : carry += dividend[i] * d;
8963 23098 : dividend[i] = carry % NBASE;
8964 23098 : carry = carry / NBASE;
8965 : }
8966 : Assert(carry == 0);
8967 : Assert(divisor[1] >= HALF_NBASE);
8968 : }
8969 : /* First 2 divisor digits are used repeatedly in main loop */
8970 2928 : divisor1 = divisor[1];
8971 2928 : divisor2 = divisor[2];
8972 :
8973 : /*
8974 : * Begin the main loop. Each iteration of this loop produces the j'th
8975 : * quotient digit by dividing dividend[j .. j + var2ndigits] by the
8976 : * divisor; this is essentially the same as the common manual procedure
8977 : * for long division.
8978 : */
8979 23138 : for (j = 0; j < res_ndigits; j++)
8980 : {
8981 : /* Estimate quotient digit from the first two dividend digits */
8982 20210 : int next2digits = dividend[j] * NBASE + dividend[j + 1];
8983 : int qhat;
8984 :
8985 : /*
8986 : * If next2digits are 0, then quotient digit must be 0 and there's no
8987 : * need to adjust the working dividend. It's worth testing here to
8988 : * fall out ASAP when processing trailing zeroes in a dividend.
8989 : */
8990 20210 : if (next2digits == 0)
8991 : {
8992 72 : res_digits[j] = 0;
8993 72 : continue;
8994 : }
8995 :
8996 20138 : if (dividend[j] == divisor1)
8997 120 : qhat = NBASE - 1;
8998 : else
8999 20018 : qhat = next2digits / divisor1;
9000 :
9001 : /*
9002 : * Adjust quotient digit if it's too large. Knuth proves that after
9003 : * this step, the quotient digit will be either correct or just one
9004 : * too large. (Note: it's OK to use dividend[j+2] here because we
9005 : * know the divisor length is at least 2.)
9006 : */
9007 20138 : while (divisor2 * qhat >
9008 23508 : (next2digits - qhat * divisor1) * NBASE + dividend[j + 2])
9009 3370 : qhat--;
9010 :
9011 : /* As above, need do nothing more when quotient digit is 0 */
9012 20138 : if (qhat > 0)
9013 : {
9014 17696 : NumericDigit *dividend_j = ÷nd[j];
9015 :
9016 : /*
9017 : * Multiply the divisor by qhat, and subtract that from the
9018 : * working dividend. The multiplication and subtraction are
9019 : * folded together here, noting that qhat <= NBASE (since it might
9020 : * be one too large), and so the intermediate result "tmp_result"
9021 : * is in the range [-NBASE^2, NBASE - 1], and "borrow" is in the
9022 : * range [0, NBASE].
9023 : */
9024 17696 : borrow = 0;
9025 174316 : for (i = var2ndigits; i >= 0; i--)
9026 : {
9027 : int tmp_result;
9028 :
9029 156620 : tmp_result = dividend_j[i] - borrow - divisor[i] * qhat;
9030 156620 : borrow = (NBASE - 1 - tmp_result) / NBASE;
9031 156620 : dividend_j[i] = tmp_result + borrow * NBASE;
9032 : }
9033 :
9034 : /*
9035 : * If we got a borrow out of the top dividend digit, then indeed
9036 : * qhat was one too large. Fix it, and add back the divisor to
9037 : * correct the working dividend. (Knuth proves that this will
9038 : * occur only about 3/NBASE of the time; hence, it's a good idea
9039 : * to test this code with small NBASE to be sure this section gets
9040 : * exercised.)
9041 : */
9042 17696 : if (borrow)
9043 : {
9044 26 : qhat--;
9045 26 : carry = 0;
9046 2308 : for (i = var2ndigits; i >= 0; i--)
9047 : {
9048 2282 : carry += dividend_j[i] + divisor[i];
9049 2282 : if (carry >= NBASE)
9050 : {
9051 2094 : dividend_j[i] = carry - NBASE;
9052 2094 : carry = 1;
9053 : }
9054 : else
9055 : {
9056 188 : dividend_j[i] = carry;
9057 188 : carry = 0;
9058 : }
9059 : }
9060 : /* A carry should occur here to cancel the borrow above */
9061 : Assert(carry == 1);
9062 : }
9063 : }
9064 :
9065 : /* And we're done with this quotient digit */
9066 20138 : res_digits[j] = qhat;
9067 : }
9068 :
9069 2928 : pfree(dividend);
9070 :
9071 : /*
9072 : * Finally, round or truncate the result to the requested precision.
9073 : */
9074 2928 : result->weight = res_weight;
9075 2928 : result->sign = res_sign;
9076 :
9077 : /* Round or truncate to target rscale (and set result->dscale) */
9078 2928 : if (round)
9079 2928 : round_var(result, rscale);
9080 : else
9081 0 : trunc_var(result, rscale);
9082 :
9083 : /* Strip leading and trailing zeroes */
9084 2928 : strip_var(result);
9085 : }
9086 :
9087 :
9088 : /*
9089 : * div_var_fast() -
9090 : *
9091 : * This has the same API as div_var, but is implemented using the division
9092 : * algorithm from the "FM" library, rather than Knuth's schoolbook-division
9093 : * approach. This is significantly faster but can produce inaccurate
9094 : * results, because it sometimes has to propagate rounding to the left,
9095 : * and so we can never be entirely sure that we know the requested digits
9096 : * exactly. We compute DIV_GUARD_DIGITS extra digits, but there is
9097 : * no certainty that that's enough. We use this only in the transcendental
9098 : * function calculation routines, where everything is approximate anyway.
9099 : *
9100 : * Although we provide a "round" argument for consistency with div_var,
9101 : * it is unwise to use this function with round=false. In truncation mode
9102 : * it is possible to get a result with no significant digits, for example
9103 : * with rscale=0 we might compute 0.99999... and truncate that to 0 when
9104 : * the correct answer is 1.
9105 : */
9106 : static void
9107 5802 : div_var_fast(const NumericVar *var1, const NumericVar *var2,
9108 : NumericVar *result, int rscale, bool round)
9109 : {
9110 : int div_ndigits;
9111 : int load_ndigits;
9112 : int res_sign;
9113 : int res_weight;
9114 : int *div;
9115 : int qdigit;
9116 : int carry;
9117 : int maxdiv;
9118 : int newdig;
9119 : NumericDigit *res_digits;
9120 : double fdividend,
9121 : fdivisor,
9122 : fdivisorinverse,
9123 : fquotient;
9124 : int qi;
9125 : int i;
9126 :
9127 : /* copy these values into local vars for speed in inner loop */
9128 5802 : int var1ndigits = var1->ndigits;
9129 5802 : int var2ndigits = var2->ndigits;
9130 5802 : NumericDigit *var1digits = var1->digits;
9131 5802 : NumericDigit *var2digits = var2->digits;
9132 :
9133 : /*
9134 : * First of all division by zero check; we must not be handed an
9135 : * unnormalized divisor.
9136 : */
9137 5802 : if (var2ndigits == 0 || var2digits[0] == 0)
9138 6 : ereport(ERROR,
9139 : (errcode(ERRCODE_DIVISION_BY_ZERO),
9140 : errmsg("division by zero")));
9141 :
9142 : /*
9143 : * If the divisor has just one or two digits, delegate to div_var_int(),
9144 : * which uses fast short division.
9145 : *
9146 : * Similarly, on platforms with 128-bit integer support, delegate to
9147 : * div_var_int64() for divisors with three or four digits.
9148 : */
9149 5796 : if (var2ndigits <= 2)
9150 : {
9151 : int idivisor;
9152 : int idivisor_weight;
9153 :
9154 414 : idivisor = var2->digits[0];
9155 414 : idivisor_weight = var2->weight;
9156 414 : if (var2ndigits == 2)
9157 : {
9158 0 : idivisor = idivisor * NBASE + var2->digits[1];
9159 0 : idivisor_weight--;
9160 : }
9161 414 : if (var2->sign == NUMERIC_NEG)
9162 0 : idivisor = -idivisor;
9163 :
9164 414 : div_var_int(var1, idivisor, idivisor_weight, result, rscale, round);
9165 414 : return;
9166 : }
9167 : #ifdef HAVE_INT128
9168 5382 : if (var2ndigits <= 4)
9169 : {
9170 : int64 idivisor;
9171 : int idivisor_weight;
9172 :
9173 42 : idivisor = var2->digits[0];
9174 42 : idivisor_weight = var2->weight;
9175 150 : for (i = 1; i < var2ndigits; i++)
9176 : {
9177 108 : idivisor = idivisor * NBASE + var2->digits[i];
9178 108 : idivisor_weight--;
9179 : }
9180 42 : if (var2->sign == NUMERIC_NEG)
9181 0 : idivisor = -idivisor;
9182 :
9183 42 : div_var_int64(var1, idivisor, idivisor_weight, result, rscale, round);
9184 42 : return;
9185 : }
9186 : #endif
9187 :
9188 : /*
9189 : * Otherwise, perform full long division.
9190 : */
9191 :
9192 : /* Result zero check */
9193 5340 : if (var1ndigits == 0)
9194 : {
9195 12 : zero_var(result);
9196 12 : result->dscale = rscale;
9197 12 : return;
9198 : }
9199 :
9200 : /*
9201 : * Determine the result sign, weight and number of digits to calculate
9202 : */
9203 5328 : if (var1->sign == var2->sign)
9204 5256 : res_sign = NUMERIC_POS;
9205 : else
9206 72 : res_sign = NUMERIC_NEG;
9207 5328 : res_weight = var1->weight - var2->weight + 1;
9208 : /* The number of accurate result digits we need to produce: */
9209 5328 : div_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
9210 : /* Add guard digits for roundoff error */
9211 5328 : div_ndigits += DIV_GUARD_DIGITS;
9212 5328 : if (div_ndigits < DIV_GUARD_DIGITS)
9213 0 : div_ndigits = DIV_GUARD_DIGITS;
9214 :
9215 : /*
9216 : * We do the arithmetic in an array "div[]" of signed int's. Since
9217 : * INT_MAX is noticeably larger than NBASE*NBASE, this gives us headroom
9218 : * to avoid normalizing carries immediately.
9219 : *
9220 : * We start with div[] containing one zero digit followed by the
9221 : * dividend's digits (plus appended zeroes to reach the desired precision
9222 : * including guard digits). Each step of the main loop computes an
9223 : * (approximate) quotient digit and stores it into div[], removing one
9224 : * position of dividend space. A final pass of carry propagation takes
9225 : * care of any mistaken quotient digits.
9226 : *
9227 : * Note that div[] doesn't necessarily contain all of the digits from the
9228 : * dividend --- the desired precision plus guard digits might be less than
9229 : * the dividend's precision. This happens, for example, in the square
9230 : * root algorithm, where we typically divide a 2N-digit number by an
9231 : * N-digit number, and only require a result with N digits of precision.
9232 : */
9233 5328 : div = (int *) palloc0((div_ndigits + 1) * sizeof(int));
9234 5328 : load_ndigits = Min(div_ndigits, var1ndigits);
9235 72708 : for (i = 0; i < load_ndigits; i++)
9236 67380 : div[i + 1] = var1digits[i];
9237 :
9238 : /*
9239 : * We estimate each quotient digit using floating-point arithmetic, taking
9240 : * the first four digits of the (current) dividend and divisor. This must
9241 : * be float to avoid overflow. The quotient digits will generally be off
9242 : * by no more than one from the exact answer.
9243 : */
9244 5328 : fdivisor = (double) var2digits[0];
9245 21312 : for (i = 1; i < 4; i++)
9246 : {
9247 15984 : fdivisor *= NBASE;
9248 15984 : if (i < var2ndigits)
9249 15984 : fdivisor += (double) var2digits[i];
9250 : }
9251 5328 : fdivisorinverse = 1.0 / fdivisor;
9252 :
9253 : /*
9254 : * maxdiv tracks the maximum possible absolute value of any div[] entry;
9255 : * when this threatens to exceed INT_MAX, we take the time to propagate
9256 : * carries. Furthermore, we need to ensure that overflow doesn't occur
9257 : * during the carry propagation passes either. The carry values may have
9258 : * an absolute value as high as INT_MAX/NBASE + 1, so really we must
9259 : * normalize when digits threaten to exceed INT_MAX - INT_MAX/NBASE - 1.
9260 : *
9261 : * To avoid overflow in maxdiv itself, it represents the max absolute
9262 : * value divided by NBASE-1, ie, at the top of the loop it is known that
9263 : * no div[] entry has an absolute value exceeding maxdiv * (NBASE-1).
9264 : *
9265 : * Actually, though, that holds good only for div[] entries after div[qi];
9266 : * the adjustment done at the bottom of the loop may cause div[qi + 1] to
9267 : * exceed the maxdiv limit, so that div[qi] in the next iteration is
9268 : * beyond the limit. This does not cause problems, as explained below.
9269 : */
9270 5328 : maxdiv = 1;
9271 :
9272 : /*
9273 : * Outer loop computes next quotient digit, which will go into div[qi]
9274 : */
9275 90288 : for (qi = 0; qi < div_ndigits; qi++)
9276 : {
9277 : /* Approximate the current dividend value */
9278 84960 : fdividend = (double) div[qi];
9279 339840 : for (i = 1; i < 4; i++)
9280 : {
9281 254880 : fdividend *= NBASE;
9282 254880 : if (qi + i <= div_ndigits)
9283 238896 : fdividend += (double) div[qi + i];
9284 : }
9285 : /* Compute the (approximate) quotient digit */
9286 84960 : fquotient = fdividend * fdivisorinverse;
9287 84960 : qdigit = (fquotient >= 0.0) ? ((int) fquotient) :
9288 6 : (((int) fquotient) - 1); /* truncate towards -infinity */
9289 :
9290 84960 : if (qdigit != 0)
9291 : {
9292 : /* Do we need to normalize now? */
9293 75966 : maxdiv += abs(qdigit);
9294 75966 : if (maxdiv > (INT_MAX - INT_MAX / NBASE - 1) / (NBASE - 1))
9295 : {
9296 : /*
9297 : * Yes, do it. Note that if var2ndigits is much smaller than
9298 : * div_ndigits, we can save a significant amount of effort
9299 : * here by noting that we only need to normalise those div[]
9300 : * entries touched where prior iterations subtracted multiples
9301 : * of the divisor.
9302 : */
9303 96 : carry = 0;
9304 1896 : for (i = Min(qi + var2ndigits - 2, div_ndigits); i > qi; i--)
9305 : {
9306 1800 : newdig = div[i] + carry;
9307 1800 : if (newdig < 0)
9308 : {
9309 1800 : carry = -((-newdig - 1) / NBASE) - 1;
9310 1800 : newdig -= carry * NBASE;
9311 : }
9312 0 : else if (newdig >= NBASE)
9313 : {
9314 0 : carry = newdig / NBASE;
9315 0 : newdig -= carry * NBASE;
9316 : }
9317 : else
9318 0 : carry = 0;
9319 1800 : div[i] = newdig;
9320 : }
9321 96 : newdig = div[qi] + carry;
9322 96 : div[qi] = newdig;
9323 :
9324 : /*
9325 : * All the div[] digits except possibly div[qi] are now in the
9326 : * range 0..NBASE-1. We do not need to consider div[qi] in
9327 : * the maxdiv value anymore, so we can reset maxdiv to 1.
9328 : */
9329 96 : maxdiv = 1;
9330 :
9331 : /*
9332 : * Recompute the quotient digit since new info may have
9333 : * propagated into the top four dividend digits
9334 : */
9335 96 : fdividend = (double) div[qi];
9336 384 : for (i = 1; i < 4; i++)
9337 : {
9338 288 : fdividend *= NBASE;
9339 288 : if (qi + i <= div_ndigits)
9340 288 : fdividend += (double) div[qi + i];
9341 : }
9342 : /* Compute the (approximate) quotient digit */
9343 96 : fquotient = fdividend * fdivisorinverse;
9344 96 : qdigit = (fquotient >= 0.0) ? ((int) fquotient) :
9345 0 : (((int) fquotient) - 1); /* truncate towards -infinity */
9346 96 : maxdiv += abs(qdigit);
9347 : }
9348 :
9349 : /*
9350 : * Subtract off the appropriate multiple of the divisor.
9351 : *
9352 : * The digits beyond div[qi] cannot overflow, because we know they
9353 : * will fall within the maxdiv limit. As for div[qi] itself, note
9354 : * that qdigit is approximately trunc(div[qi] / vardigits[0]),
9355 : * which would make the new value simply div[qi] mod vardigits[0].
9356 : * The lower-order terms in qdigit can change this result by not
9357 : * more than about twice INT_MAX/NBASE, so overflow is impossible.
9358 : *
9359 : * This inner loop is the performance bottleneck for division, so
9360 : * code it in the same way as the inner loop of mul_var() so that
9361 : * it can be auto-vectorized. We cast qdigit to NumericDigit
9362 : * before multiplying to allow the compiler to generate more
9363 : * efficient code (using 16-bit multiplication), which is safe
9364 : * since we know that the quotient digit is off by at most one, so
9365 : * there is no overflow risk.
9366 : */
9367 75966 : if (qdigit != 0)
9368 : {
9369 75966 : int istop = Min(var2ndigits, div_ndigits - qi + 1);
9370 75966 : int *div_qi = &div[qi];
9371 :
9372 930036 : for (i = 0; i < istop; i++)
9373 854070 : div_qi[i] -= ((NumericDigit) qdigit) * var2digits[i];
9374 : }
9375 : }
9376 :
9377 : /*
9378 : * The dividend digit we are about to replace might still be nonzero.
9379 : * Fold it into the next digit position.
9380 : *
9381 : * There is no risk of overflow here, although proving that requires
9382 : * some care. Much as with the argument for div[qi] not overflowing,
9383 : * if we consider the first two terms in the numerator and denominator
9384 : * of qdigit, we can see that the final value of div[qi + 1] will be
9385 : * approximately a remainder mod (vardigits[0]*NBASE + vardigits[1]).
9386 : * Accounting for the lower-order terms is a bit complicated but ends
9387 : * up adding not much more than INT_MAX/NBASE to the possible range.
9388 : * Thus, div[qi + 1] cannot overflow here, and in its role as div[qi]
9389 : * in the next loop iteration, it can't be large enough to cause
9390 : * overflow in the carry propagation step (if any), either.
9391 : *
9392 : * But having said that: div[qi] can be more than INT_MAX/NBASE, as
9393 : * noted above, which means that the product div[qi] * NBASE *can*
9394 : * overflow. When that happens, adding it to div[qi + 1] will always
9395 : * cause a canceling overflow so that the end result is correct. We
9396 : * could avoid the intermediate overflow by doing the multiplication
9397 : * and addition in int64 arithmetic, but so far there appears no need.
9398 : */
9399 84960 : div[qi + 1] += div[qi] * NBASE;
9400 :
9401 84960 : div[qi] = qdigit;
9402 : }
9403 :
9404 : /*
9405 : * Approximate and store the last quotient digit (div[div_ndigits])
9406 : */
9407 5328 : fdividend = (double) div[qi];
9408 21312 : for (i = 1; i < 4; i++)
9409 15984 : fdividend *= NBASE;
9410 5328 : fquotient = fdividend * fdivisorinverse;
9411 5328 : qdigit = (fquotient >= 0.0) ? ((int) fquotient) :
9412 0 : (((int) fquotient) - 1); /* truncate towards -infinity */
9413 5328 : div[qi] = qdigit;
9414 :
9415 : /*
9416 : * Because the quotient digits might be off by one, some of them might be
9417 : * -1 or NBASE at this point. The represented value is correct in a
9418 : * mathematical sense, but it doesn't look right. We do a final carry
9419 : * propagation pass to normalize the digits, which we combine with storing
9420 : * the result digits into the output. Note that this is still done at
9421 : * full precision w/guard digits.
9422 : */
9423 5328 : alloc_var(result, div_ndigits + 1);
9424 5328 : res_digits = result->digits;
9425 5328 : carry = 0;
9426 95616 : for (i = div_ndigits; i >= 0; i--)
9427 : {
9428 90288 : newdig = div[i] + carry;
9429 90288 : if (newdig < 0)
9430 : {
9431 12 : carry = -((-newdig - 1) / NBASE) - 1;
9432 12 : newdig -= carry * NBASE;
9433 : }
9434 90276 : else if (newdig >= NBASE)
9435 : {
9436 348 : carry = newdig / NBASE;
9437 348 : newdig -= carry * NBASE;
9438 : }
9439 : else
9440 89928 : carry = 0;
9441 90288 : res_digits[i] = newdig;
9442 : }
9443 : Assert(carry == 0);
9444 :
9445 5328 : pfree(div);
9446 :
9447 : /*
9448 : * Finally, round the result to the requested precision.
9449 : */
9450 5328 : result->weight = res_weight;
9451 5328 : result->sign = res_sign;
9452 :
9453 : /* Round to target rscale (and set result->dscale) */
9454 5328 : if (round)
9455 810 : round_var(result, rscale);
9456 : else
9457 4518 : trunc_var(result, rscale);
9458 :
9459 : /* Strip leading and trailing zeroes */
9460 5328 : strip_var(result);
9461 : }
9462 :
9463 :
9464 : /*
9465 : * div_var_int() -
9466 : *
9467 : * Divide a numeric variable by a 32-bit integer with the specified weight.
9468 : * The quotient var / (ival * NBASE^ival_weight) is stored in result.
9469 : */
9470 : static void
9471 194876 : div_var_int(const NumericVar *var, int ival, int ival_weight,
9472 : NumericVar *result, int rscale, bool round)
9473 : {
9474 194876 : NumericDigit *var_digits = var->digits;
9475 194876 : int var_ndigits = var->ndigits;
9476 : int res_sign;
9477 : int res_weight;
9478 : int res_ndigits;
9479 : NumericDigit *res_buf;
9480 : NumericDigit *res_digits;
9481 : uint32 divisor;
9482 : int i;
9483 :
9484 : /* Guard against division by zero */
9485 194876 : if (ival == 0)
9486 0 : ereport(ERROR,
9487 : errcode(ERRCODE_DIVISION_BY_ZERO),
9488 : errmsg("division by zero"));
9489 :
9490 : /* Result zero check */
9491 194876 : if (var_ndigits == 0)
9492 : {
9493 2282 : zero_var(result);
9494 2282 : result->dscale = rscale;
9495 2282 : return;
9496 : }
9497 :
9498 : /*
9499 : * Determine the result sign, weight and number of digits to calculate.
9500 : * The weight figured here is correct if the emitted quotient has no
9501 : * leading zero digits; otherwise strip_var() will fix things up.
9502 : */
9503 192594 : if (var->sign == NUMERIC_POS)
9504 189768 : res_sign = ival > 0 ? NUMERIC_POS : NUMERIC_NEG;
9505 : else
9506 2826 : res_sign = ival > 0 ? NUMERIC_NEG : NUMERIC_POS;
9507 192594 : res_weight = var->weight - ival_weight;
9508 : /* The number of accurate result digits we need to produce: */
9509 192594 : res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
9510 : /* ... but always at least 1 */
9511 192594 : res_ndigits = Max(res_ndigits, 1);
9512 : /* If rounding needed, figure one more digit to ensure correct result */
9513 192594 : if (round)
9514 136962 : res_ndigits++;
9515 :
9516 192594 : res_buf = digitbuf_alloc(res_ndigits + 1);
9517 192594 : res_buf[0] = 0; /* spare digit for later rounding */
9518 192594 : res_digits = res_buf + 1;
9519 :
9520 : /*
9521 : * Now compute the quotient digits. This is the short division algorithm
9522 : * described in Knuth volume 2, section 4.3.1 exercise 16, except that we
9523 : * allow the divisor to exceed the internal base.
9524 : *
9525 : * In this algorithm, the carry from one digit to the next is at most
9526 : * divisor - 1. Therefore, while processing the next digit, carry may
9527 : * become as large as divisor * NBASE - 1, and so it requires a 64-bit
9528 : * integer if this exceeds UINT_MAX.
9529 : */
9530 192594 : divisor = abs(ival);
9531 :
9532 192594 : if (divisor <= UINT_MAX / NBASE)
9533 : {
9534 : /* carry cannot overflow 32 bits */
9535 188478 : uint32 carry = 0;
9536 :
9537 1891908 : for (i = 0; i < res_ndigits; i++)
9538 : {
9539 1703430 : carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
9540 1703430 : res_digits[i] = (NumericDigit) (carry / divisor);
9541 1703430 : carry = carry % divisor;
9542 : }
9543 : }
9544 : else
|