PostgreSQL Source Code  git master
numeric.c
Go to the documentation of this file.
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-2018, 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 "access/hash.h"
30 #include "catalog/pg_type.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 "utils/array.h"
38 #include "utils/builtins.h"
39 #include "utils/guc.h"
40 #include "utils/int8.h"
41 #include "utils/numeric.h"
42 #include "utils/sortsupport.h"
43 
44 /* ----------
45  * Uncomment the following to enable compilation of dump_numeric()
46  * and dump_var() and to get a dump of any result produced by make_result().
47  * ----------
48 #define NUMERIC_DEBUG
49  */
50 
51 
52 /* ----------
53  * Local data types
54  *
55  * Numeric values are represented in a base-NBASE floating point format.
56  * Each "digit" ranges from 0 to NBASE-1. The type NumericDigit is signed
57  * and wide enough to store a digit. We assume that NBASE*NBASE can fit in
58  * an int. Although the purely calculational routines could handle any even
59  * NBASE that's less than sqrt(INT_MAX), in practice we are only interested
60  * in NBASE a power of ten, so that I/O conversions and decimal rounding
61  * are easy. Also, it's actually more efficient if NBASE is rather less than
62  * sqrt(INT_MAX), so that there is "headroom" for mul_var and div_var_fast to
63  * postpone processing carries.
64  *
65  * Values of NBASE other than 10000 are considered of historical interest only
66  * and are no longer supported in any sense; no mechanism exists for the client
67  * to discover the base, so every client supporting binary mode expects the
68  * base-10000 format. If you plan to change this, also note the numeric
69  * abbreviation code, which assumes NBASE=10000.
70  * ----------
71  */
72 
73 #if 0
74 #define NBASE 10
75 #define HALF_NBASE 5
76 #define DEC_DIGITS 1 /* decimal digits per NBASE digit */
77 #define MUL_GUARD_DIGITS 4 /* these are measured in NBASE digits */
78 #define DIV_GUARD_DIGITS 8
79 
80 typedef signed char NumericDigit;
81 #endif
82 
83 #if 0
84 #define NBASE 100
85 #define HALF_NBASE 50
86 #define DEC_DIGITS 2 /* decimal digits per NBASE digit */
87 #define MUL_GUARD_DIGITS 3 /* these are measured in NBASE digits */
88 #define DIV_GUARD_DIGITS 6
89 
90 typedef signed char NumericDigit;
91 #endif
92 
93 #if 1
94 #define NBASE 10000
95 #define HALF_NBASE 5000
96 #define DEC_DIGITS 4 /* decimal digits per NBASE digit */
97 #define MUL_GUARD_DIGITS 2 /* these are measured in NBASE digits */
98 #define DIV_GUARD_DIGITS 4
99 
101 #endif
102 
103 /*
104  * The Numeric type as stored on disk.
105  *
106  * If the high bits of the first word of a NumericChoice (n_header, or
107  * n_short.n_header, or n_long.n_sign_dscale) are NUMERIC_SHORT, then the
108  * numeric follows the NumericShort format; if they are NUMERIC_POS or
109  * NUMERIC_NEG, it follows the NumericLong format. If they are NUMERIC_NAN,
110  * it is a NaN. We currently always store a NaN using just two bytes (i.e.
111  * only n_header), but previous releases used only the NumericLong format,
112  * so we might find 4-byte NaNs on disk if a database has been migrated using
113  * pg_upgrade. In either case, when the high bits indicate a NaN, the
114  * remaining bits are never examined. Currently, we always initialize these
115  * to zero, but it might be possible to use them for some other purpose in
116  * the future.
117  *
118  * In the NumericShort format, the remaining 14 bits of the header word
119  * (n_short.n_header) are allocated as follows: 1 for sign (positive or
120  * negative), 6 for dynamic scale, and 7 for weight. In practice, most
121  * commonly-encountered values can be represented this way.
122  *
123  * In the NumericLong format, the remaining 14 bits of the header word
124  * (n_long.n_sign_dscale) represent the display scale; and the weight is
125  * stored separately in n_weight.
126  *
127  * NOTE: by convention, values in the packed form have been stripped of
128  * all leading and trailing zero digits (where a "digit" is of base NBASE).
129  * In particular, if the value is zero, there will be no digits at all!
130  * The weight is arbitrary in that case, but we normally set it to zero.
131  */
132 
134 {
135  uint16 n_header; /* Sign + display scale + weight */
136  NumericDigit n_data[FLEXIBLE_ARRAY_MEMBER]; /* Digits */
137 };
138 
140 {
141  uint16 n_sign_dscale; /* Sign + display scale */
142  int16 n_weight; /* Weight of 1st digit */
143  NumericDigit n_data[FLEXIBLE_ARRAY_MEMBER]; /* Digits */
144 };
145 
147 {
148  uint16 n_header; /* Header word */
149  struct NumericLong n_long; /* Long form (4-byte header) */
150  struct NumericShort n_short; /* Short form (2-byte header) */
151 };
152 
154 {
155  int32 vl_len_; /* varlena header (do not touch directly!) */
156  union NumericChoice choice; /* choice of format */
157 };
158 
159 
160 /*
161  * Interpretation of high bits.
162  */
163 
164 #define NUMERIC_SIGN_MASK 0xC000
165 #define NUMERIC_POS 0x0000
166 #define NUMERIC_NEG 0x4000
167 #define NUMERIC_SHORT 0x8000
168 #define NUMERIC_NAN 0xC000
169 
170 #define NUMERIC_FLAGBITS(n) ((n)->choice.n_header & NUMERIC_SIGN_MASK)
171 #define NUMERIC_IS_NAN(n) (NUMERIC_FLAGBITS(n) == NUMERIC_NAN)
172 #define NUMERIC_IS_SHORT(n) (NUMERIC_FLAGBITS(n) == NUMERIC_SHORT)
173 
174 #define NUMERIC_HDRSZ (VARHDRSZ + sizeof(uint16) + sizeof(int16))
175 #define NUMERIC_HDRSZ_SHORT (VARHDRSZ + sizeof(uint16))
176 
177 /*
178  * If the flag bits are NUMERIC_SHORT or NUMERIC_NAN, we want the short header;
179  * otherwise, we want the long one. Instead of testing against each value, we
180  * can just look at the high bit, for a slight efficiency gain.
181  */
182 #define NUMERIC_HEADER_IS_SHORT(n) (((n)->choice.n_header & 0x8000) != 0)
183 #define NUMERIC_HEADER_SIZE(n) \
184  (VARHDRSZ + sizeof(uint16) + \
185  (NUMERIC_HEADER_IS_SHORT(n) ? 0 : sizeof(int16)))
186 
187 /*
188  * Short format definitions.
189  */
190 
191 #define NUMERIC_SHORT_SIGN_MASK 0x2000
192 #define NUMERIC_SHORT_DSCALE_MASK 0x1F80
193 #define NUMERIC_SHORT_DSCALE_SHIFT 7
194 #define NUMERIC_SHORT_DSCALE_MAX \
195  (NUMERIC_SHORT_DSCALE_MASK >> NUMERIC_SHORT_DSCALE_SHIFT)
196 #define NUMERIC_SHORT_WEIGHT_SIGN_MASK 0x0040
197 #define NUMERIC_SHORT_WEIGHT_MASK 0x003F
198 #define NUMERIC_SHORT_WEIGHT_MAX NUMERIC_SHORT_WEIGHT_MASK
199 #define NUMERIC_SHORT_WEIGHT_MIN (-(NUMERIC_SHORT_WEIGHT_MASK+1))
200 
201 /*
202  * Extract sign, display scale, weight.
203  */
204 
205 #define NUMERIC_DSCALE_MASK 0x3FFF
206 
207 #define NUMERIC_SIGN(n) \
208  (NUMERIC_IS_SHORT(n) ? \
209  (((n)->choice.n_short.n_header & NUMERIC_SHORT_SIGN_MASK) ? \
210  NUMERIC_NEG : NUMERIC_POS) : NUMERIC_FLAGBITS(n))
211 #define NUMERIC_DSCALE(n) (NUMERIC_HEADER_IS_SHORT((n)) ? \
212  ((n)->choice.n_short.n_header & NUMERIC_SHORT_DSCALE_MASK) \
213  >> NUMERIC_SHORT_DSCALE_SHIFT \
214  : ((n)->choice.n_long.n_sign_dscale & NUMERIC_DSCALE_MASK))
215 #define NUMERIC_WEIGHT(n) (NUMERIC_HEADER_IS_SHORT((n)) ? \
216  (((n)->choice.n_short.n_header & NUMERIC_SHORT_WEIGHT_SIGN_MASK ? \
217  ~NUMERIC_SHORT_WEIGHT_MASK : 0) \
218  | ((n)->choice.n_short.n_header & NUMERIC_SHORT_WEIGHT_MASK)) \
219  : ((n)->choice.n_long.n_weight))
220 
221 /* ----------
222  * NumericVar is the format we use for arithmetic. The digit-array part
223  * is the same as the NumericData storage format, but the header is more
224  * complex.
225  *
226  * The value represented by a NumericVar is determined by the sign, weight,
227  * ndigits, and digits[] array.
228  *
229  * Note: the first digit of a NumericVar's value is assumed to be multiplied
230  * by NBASE ** weight. Another way to say it is that there are weight+1
231  * digits before the decimal point. It is possible to have weight < 0.
232  *
233  * buf points at the physical start of the palloc'd digit buffer for the
234  * NumericVar. digits points at the first digit in actual use (the one
235  * with the specified weight). We normally leave an unused digit or two
236  * (preset to zeroes) between buf and digits, so that there is room to store
237  * a carry out of the top digit without reallocating space. We just need to
238  * decrement digits (and increment weight) to make room for the carry digit.
239  * (There is no such extra space in a numeric value stored in the database,
240  * only in a NumericVar in memory.)
241  *
242  * If buf is NULL then the digit buffer isn't actually palloc'd and should
243  * not be freed --- see the constants below for an example.
244  *
245  * dscale, or display scale, is the nominal precision expressed as number
246  * of digits after the decimal point (it must always be >= 0 at present).
247  * dscale may be more than the number of physically stored fractional digits,
248  * implying that we have suppressed storage of significant trailing zeroes.
249  * It should never be less than the number of stored digits, since that would
250  * imply hiding digits that are present. NOTE that dscale is always expressed
251  * in *decimal* digits, and so it may correspond to a fractional number of
252  * base-NBASE digits --- divide by DEC_DIGITS to convert to NBASE digits.
253  *
254  * rscale, or result scale, is the target precision for a computation.
255  * Like dscale it is expressed as number of *decimal* digits after the decimal
256  * point, and is always >= 0 at present.
257  * Note that rscale is not stored in variables --- it's figured on-the-fly
258  * from the dscales of the inputs.
259  *
260  * While we consistently use "weight" to refer to the base-NBASE weight of
261  * a numeric value, it is convenient in some scale-related calculations to
262  * make use of the base-10 weight (ie, the approximate log10 of the value).
263  * To avoid confusion, such a decimal-units weight is called a "dweight".
264  *
265  * NB: All the variable-level functions are written in a style that makes it
266  * possible to give one and the same variable as argument and destination.
267  * This is feasible because the digit buffer is separate from the variable.
268  * ----------
269  */
270 typedef struct NumericVar
271 {
272  int ndigits; /* # of digits in digits[] - can be 0! */
273  int weight; /* weight of first digit */
274  int sign; /* NUMERIC_POS, NUMERIC_NEG, or NUMERIC_NAN */
275  int dscale; /* display scale */
276  NumericDigit *buf; /* start of palloc'd space for digits[] */
277  NumericDigit *digits; /* base-NBASE digits */
278 } NumericVar;
279 
280 
281 /* ----------
282  * Data for generate_series
283  * ----------
284  */
285 typedef struct
286 {
291 
292 
293 /* ----------
294  * Sort support.
295  * ----------
296  */
297 typedef struct
298 {
299  void *buf; /* buffer for short varlenas */
300  int64 input_count; /* number of non-null values seen */
301  bool estimating; /* true if estimating cardinality */
302 
303  hyperLogLogState abbr_card; /* cardinality estimator */
305 
306 
307 /* ----------
308  * Fast sum accumulator.
309  *
310  * NumericSumAccum is used to implement SUM(), and other standard aggregates
311  * that track the sum of input values. It uses 32-bit integers to store the
312  * digits, instead of the normal 16-bit integers (with NBASE=10000). This
313  * way, we can safely accumulate up to NBASE - 1 values without propagating
314  * carry, before risking overflow of any of the digits. 'num_uncarried'
315  * tracks how many values have been accumulated without propagating carry.
316  *
317  * Positive and negative values are accumulated separately, in 'pos_digits'
318  * and 'neg_digits'. This is simpler and faster than deciding whether to add
319  * or subtract from the current value, for each new value (see sub_var() for
320  * the logic we avoid by doing this). Both buffers are of same size, and
321  * have the same weight and scale. In accum_sum_final(), the positive and
322  * negative sums are added together to produce the final result.
323  *
324  * When a new value has a larger ndigits or weight than the accumulator
325  * currently does, the accumulator is enlarged to accommodate the new value.
326  * We normally have one zero digit reserved for carry propagation, and that
327  * is indicated by the 'have_carry_space' flag. When accum_sum_carry() uses
328  * up the reserved digit, it clears the 'have_carry_space' flag. The next
329  * call to accum_sum_add() will enlarge the buffer, to make room for the
330  * extra digit, and set the flag again.
331  *
332  * To initialize a new accumulator, simply reset all fields to zeros.
333  *
334  * The accumulator does not handle NaNs.
335  * ----------
336  */
337 typedef struct NumericSumAccum
338 {
339  int ndigits;
340  int weight;
341  int dscale;
347 
348 
349 /*
350  * We define our own macros for packing and unpacking abbreviated-key
351  * representations for numeric values in order to avoid depending on
352  * USE_FLOAT8_BYVAL. The type of abbreviation we use is based only on
353  * the size of a datum, not the argument-passing convention for float8.
354  */
355 #define NUMERIC_ABBREV_BITS (SIZEOF_DATUM * BITS_PER_BYTE)
356 #if SIZEOF_DATUM == 8
357 #define NumericAbbrevGetDatum(X) ((Datum) (X))
358 #define DatumGetNumericAbbrev(X) ((int64) (X))
359 #define NUMERIC_ABBREV_NAN NumericAbbrevGetDatum(PG_INT64_MIN)
360 #else
361 #define NumericAbbrevGetDatum(X) ((Datum) (X))
362 #define DatumGetNumericAbbrev(X) ((int32) (X))
363 #define NUMERIC_ABBREV_NAN NumericAbbrevGetDatum(PG_INT32_MIN)
364 #endif
365 
366 
367 /* ----------
368  * Some preinitialized constants
369  * ----------
370  */
371 static const NumericDigit const_zero_data[1] = {0};
372 static const NumericVar const_zero =
373 {0, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_zero_data};
374 
375 static const NumericDigit const_one_data[1] = {1};
376 static const NumericVar const_one =
377 {1, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_one_data};
378 
379 static const NumericDigit const_two_data[1] = {2};
380 static const NumericVar const_two =
381 {1, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_two_data};
382 
383 #if DEC_DIGITS == 4 || DEC_DIGITS == 2
384 static const NumericDigit const_ten_data[1] = {10};
385 static const NumericVar const_ten =
386 {1, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_ten_data};
387 #elif DEC_DIGITS == 1
388 static const NumericDigit const_ten_data[1] = {1};
389 static const NumericVar const_ten =
390 {1, 1, NUMERIC_POS, 0, NULL, (NumericDigit *) const_ten_data};
391 #endif
392 
393 #if DEC_DIGITS == 4
394 static const NumericDigit const_zero_point_five_data[1] = {5000};
395 #elif DEC_DIGITS == 2
396 static const NumericDigit const_zero_point_five_data[1] = {50};
397 #elif DEC_DIGITS == 1
398 static const NumericDigit const_zero_point_five_data[1] = {5};
399 #endif
402 
403 #if DEC_DIGITS == 4
404 static const NumericDigit const_zero_point_nine_data[1] = {9000};
405 #elif DEC_DIGITS == 2
406 static const NumericDigit const_zero_point_nine_data[1] = {90};
407 #elif DEC_DIGITS == 1
408 static const NumericDigit const_zero_point_nine_data[1] = {9};
409 #endif
412 
413 #if DEC_DIGITS == 4
414 static const NumericDigit const_one_point_one_data[2] = {1, 1000};
415 #elif DEC_DIGITS == 2
416 static const NumericDigit const_one_point_one_data[2] = {1, 10};
417 #elif DEC_DIGITS == 1
418 static const NumericDigit const_one_point_one_data[2] = {1, 1};
419 #endif
422 
423 static const NumericVar const_nan =
424 {0, 0, NUMERIC_NAN, 0, NULL, NULL};
425 
426 #if DEC_DIGITS == 4
427 static const int round_powers[4] = {0, 1000, 100, 10};
428 #endif
429 
430 
431 /* ----------
432  * Local functions
433  * ----------
434  */
435 
436 #ifdef NUMERIC_DEBUG
437 static void dump_numeric(const char *str, Numeric num);
438 static void dump_var(const char *str, NumericVar *var);
439 #else
440 #define dump_numeric(s,n)
441 #define dump_var(s,v)
442 #endif
443 
444 #define digitbuf_alloc(ndigits) \
445  ((NumericDigit *) palloc((ndigits) * sizeof(NumericDigit)))
446 #define digitbuf_free(buf) \
447  do { \
448  if ((buf) != NULL) \
449  pfree(buf); \
450  } while (0)
451 
452 #define init_var(v) MemSetAligned(v, 0, sizeof(NumericVar))
453 
454 #define NUMERIC_DIGITS(num) (NUMERIC_HEADER_IS_SHORT(num) ? \
455  (num)->choice.n_short.n_data : (num)->choice.n_long.n_data)
456 #define NUMERIC_NDIGITS(num) \
457  ((VARSIZE(num) - NUMERIC_HEADER_SIZE(num)) / sizeof(NumericDigit))
458 #define NUMERIC_CAN_BE_SHORT(scale,weight) \
459  ((scale) <= NUMERIC_SHORT_DSCALE_MAX && \
460  (weight) <= NUMERIC_SHORT_WEIGHT_MAX && \
461  (weight) >= NUMERIC_SHORT_WEIGHT_MIN)
462 
463 static void alloc_var(NumericVar *var, int ndigits);
464 static void free_var(NumericVar *var);
465 static void zero_var(NumericVar *var);
466 
467 static const char *set_var_from_str(const char *str, const char *cp,
468  NumericVar *dest);
470 static void init_var_from_num(Numeric num, NumericVar *dest);
471 static void set_var_from_var(const NumericVar *value, NumericVar *dest);
472 static char *get_str_from_var(const NumericVar *var);
473 static char *get_str_from_var_sci(const NumericVar *var, int rscale);
474 
475 static Numeric make_result(const NumericVar *var);
476 
477 static void apply_typmod(NumericVar *var, int32 typmod);
478 
479 static int32 numericvar_to_int32(const NumericVar *var);
480 static bool numericvar_to_int64(const NumericVar *var, int64 *result);
481 static void int64_to_numericvar(int64 val, NumericVar *var);
482 #ifdef HAVE_INT128
483 static bool numericvar_to_int128(const NumericVar *var, int128 *result);
484 static void int128_to_numericvar(int128 val, NumericVar *var);
485 #endif
486 static double numeric_to_double_no_overflow(Numeric num);
487 static double numericvar_to_double_no_overflow(const NumericVar *var);
488 
489 static Datum numeric_abbrev_convert(Datum original_datum, SortSupport ssup);
490 static bool numeric_abbrev_abort(int memtupcount, SortSupport ssup);
491 static int numeric_fast_cmp(Datum x, Datum y, SortSupport ssup);
492 static int numeric_cmp_abbrev(Datum x, Datum y, SortSupport ssup);
493 
495  NumericSortSupport *nss);
496 
497 static int cmp_numerics(Numeric num1, Numeric num2);
498 static int cmp_var(const NumericVar *var1, const NumericVar *var2);
499 static int cmp_var_common(const NumericDigit *var1digits, int var1ndigits,
500  int var1weight, int var1sign,
501  const NumericDigit *var2digits, int var2ndigits,
502  int var2weight, int var2sign);
503 static void add_var(const NumericVar *var1, const NumericVar *var2,
504  NumericVar *result);
505 static void sub_var(const NumericVar *var1, const NumericVar *var2,
506  NumericVar *result);
507 static void mul_var(const NumericVar *var1, const NumericVar *var2,
508  NumericVar *result,
509  int rscale);
510 static void div_var(const NumericVar *var1, const NumericVar *var2,
511  NumericVar *result,
512  int rscale, bool round);
513 static void div_var_fast(const NumericVar *var1, const NumericVar *var2,
514  NumericVar *result, int rscale, bool round);
515 static int select_div_scale(const NumericVar *var1, const NumericVar *var2);
516 static void mod_var(const NumericVar *var1, const NumericVar *var2,
517  NumericVar *result);
518 static void ceil_var(const NumericVar *var, NumericVar *result);
519 static void floor_var(const NumericVar *var, NumericVar *result);
520 
521 static void sqrt_var(const NumericVar *arg, NumericVar *result, int rscale);
522 static void exp_var(const NumericVar *arg, NumericVar *result, int rscale);
523 static int estimate_ln_dweight(const NumericVar *var);
524 static void ln_var(const NumericVar *arg, NumericVar *result, int rscale);
525 static void log_var(const NumericVar *base, const NumericVar *num,
526  NumericVar *result);
527 static void power_var(const NumericVar *base, const NumericVar *exp,
528  NumericVar *result);
529 static void power_var_int(const NumericVar *base, int exp, NumericVar *result,
530  int rscale);
531 
532 static int cmp_abs(const NumericVar *var1, const NumericVar *var2);
533 static int cmp_abs_common(const NumericDigit *var1digits, int var1ndigits,
534  int var1weight,
535  const NumericDigit *var2digits, int var2ndigits,
536  int var2weight);
537 static void add_abs(const NumericVar *var1, const NumericVar *var2,
538  NumericVar *result);
539 static void sub_abs(const NumericVar *var1, const NumericVar *var2,
540  NumericVar *result);
541 static void round_var(NumericVar *var, int rscale);
542 static void trunc_var(NumericVar *var, int rscale);
543 static void strip_var(NumericVar *var);
544 static void compute_bucket(Numeric operand, Numeric bound1, Numeric bound2,
545  const NumericVar *count_var, NumericVar *result_var);
546 
547 static void accum_sum_add(NumericSumAccum *accum, const NumericVar *var1);
548 static void accum_sum_rescale(NumericSumAccum *accum, const NumericVar *val);
549 static void accum_sum_carry(NumericSumAccum *accum);
550 static void accum_sum_reset(NumericSumAccum *accum);
551 static void accum_sum_final(NumericSumAccum *accum, NumericVar *result);
552 static void accum_sum_copy(NumericSumAccum *dst, NumericSumAccum *src);
553 static void accum_sum_combine(NumericSumAccum *accum, NumericSumAccum *accum2);
554 
555 
556 /* ----------------------------------------------------------------------
557  *
558  * Input-, output- and rounding-functions
559  *
560  * ----------------------------------------------------------------------
561  */
562 
563 
564 /*
565  * numeric_in() -
566  *
567  * Input function for numeric data type
568  */
569 Datum
571 {
572  char *str = PG_GETARG_CSTRING(0);
573 
574 #ifdef NOT_USED
575  Oid typelem = PG_GETARG_OID(1);
576 #endif
577  int32 typmod = PG_GETARG_INT32(2);
578  Numeric res;
579  const char *cp;
580 
581  /* Skip leading spaces */
582  cp = str;
583  while (*cp)
584  {
585  if (!isspace((unsigned char) *cp))
586  break;
587  cp++;
588  }
589 
590  /*
591  * Check for NaN
592  */
593  if (pg_strncasecmp(cp, "NaN", 3) == 0)
594  {
595  res = make_result(&const_nan);
596 
597  /* Should be nothing left but spaces */
598  cp += 3;
599  while (*cp)
600  {
601  if (!isspace((unsigned char) *cp))
602  ereport(ERROR,
603  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
604  errmsg("invalid input syntax for type %s: \"%s\"",
605  "numeric", str)));
606  cp++;
607  }
608  }
609  else
610  {
611  /*
612  * Use set_var_from_str() to parse a normal numeric value
613  */
615 
616  init_var(&value);
617 
618  cp = set_var_from_str(str, cp, &value);
619 
620  /*
621  * We duplicate a few lines of code here because we would like to
622  * throw any trailing-junk syntax error before any semantic error
623  * resulting from apply_typmod. We can't easily fold the two cases
624  * together because we mustn't apply apply_typmod to a NaN.
625  */
626  while (*cp)
627  {
628  if (!isspace((unsigned char) *cp))
629  ereport(ERROR,
630  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
631  errmsg("invalid input syntax for type %s: \"%s\"",
632  "numeric", str)));
633  cp++;
634  }
635 
636  apply_typmod(&value, typmod);
637 
638  res = make_result(&value);
639  free_var(&value);
640  }
641 
642  PG_RETURN_NUMERIC(res);
643 }
644 
645 
646 /*
647  * numeric_out() -
648  *
649  * Output function for numeric data type
650  */
651 Datum
653 {
654  Numeric num = PG_GETARG_NUMERIC(0);
655  NumericVar x;
656  char *str;
657 
658  /*
659  * Handle NaN
660  */
661  if (NUMERIC_IS_NAN(num))
662  PG_RETURN_CSTRING(pstrdup("NaN"));
663 
664  /*
665  * Get the number in the variable format.
666  */
667  init_var_from_num(num, &x);
668 
669  str = get_str_from_var(&x);
670 
671  PG_RETURN_CSTRING(str);
672 }
673 
674 /*
675  * numeric_is_nan() -
676  *
677  * Is Numeric value a NaN?
678  */
679 bool
681 {
682  return NUMERIC_IS_NAN(num);
683 }
684 
685 /*
686  * numeric_maximum_size() -
687  *
688  * Maximum size of a numeric with given typmod, or -1 if unlimited/unknown.
689  */
690 int32
692 {
693  int precision;
694  int numeric_digits;
695 
696  if (typmod < (int32) (VARHDRSZ))
697  return -1;
698 
699  /* precision (ie, max # of digits) is in upper bits of typmod */
700  precision = ((typmod - VARHDRSZ) >> 16) & 0xffff;
701 
702  /*
703  * This formula computes the maximum number of NumericDigits we could need
704  * in order to store the specified number of decimal digits. Because the
705  * weight is stored as a number of NumericDigits rather than a number of
706  * decimal digits, it's possible that the first NumericDigit will contain
707  * only a single decimal digit. Thus, the first two decimal digits can
708  * require two NumericDigits to store, but it isn't until we reach
709  * DEC_DIGITS + 2 decimal digits that we potentially need a third
710  * NumericDigit.
711  */
712  numeric_digits = (precision + 2 * (DEC_DIGITS - 1)) / DEC_DIGITS;
713 
714  /*
715  * In most cases, the size of a numeric will be smaller than the value
716  * computed below, because the varlena header will typically get toasted
717  * down to a single byte before being stored on disk, and it may also be
718  * possible to use a short numeric header. But our job here is to compute
719  * the worst case.
720  */
721  return NUMERIC_HDRSZ + (numeric_digits * sizeof(NumericDigit));
722 }
723 
724 /*
725  * numeric_out_sci() -
726  *
727  * Output function for numeric data type in scientific notation.
728  */
729 char *
731 {
732  NumericVar x;
733  char *str;
734 
735  /*
736  * Handle NaN
737  */
738  if (NUMERIC_IS_NAN(num))
739  return pstrdup("NaN");
740 
741  init_var_from_num(num, &x);
742 
743  str = get_str_from_var_sci(&x, scale);
744 
745  return str;
746 }
747 
748 /*
749  * numeric_normalize() -
750  *
751  * Output function for numeric data type, suppressing insignificant trailing
752  * zeroes and then any trailing decimal point. The intent of this is to
753  * produce strings that are equal if and only if the input numeric values
754  * compare equal.
755  */
756 char *
758 {
759  NumericVar x;
760  char *str;
761  int last;
762 
763  /*
764  * Handle NaN
765  */
766  if (NUMERIC_IS_NAN(num))
767  return pstrdup("NaN");
768 
769  init_var_from_num(num, &x);
770 
771  str = get_str_from_var(&x);
772 
773  /* If there's no decimal point, there's certainly nothing to remove. */
774  if (strchr(str, '.') != NULL)
775  {
776  /*
777  * Back up over trailing fractional zeroes. Since there is a decimal
778  * point, this loop will terminate safely.
779  */
780  last = strlen(str) - 1;
781  while (str[last] == '0')
782  last--;
783 
784  /* We want to get rid of the decimal point too, if it's now last. */
785  if (str[last] == '.')
786  last--;
787 
788  /* Delete whatever we backed up over. */
789  str[last + 1] = '\0';
790  }
791 
792  return str;
793 }
794 
795 /*
796  * numeric_recv - converts external binary format to numeric
797  *
798  * External format is a sequence of int16's:
799  * ndigits, weight, sign, dscale, NumericDigits.
800  */
801 Datum
803 {
805 
806 #ifdef NOT_USED
807  Oid typelem = PG_GETARG_OID(1);
808 #endif
809  int32 typmod = PG_GETARG_INT32(2);
811  Numeric res;
812  int len,
813  i;
814 
815  init_var(&value);
816 
817  len = (uint16) pq_getmsgint(buf, sizeof(uint16));
818 
819  alloc_var(&value, len);
820 
821  value.weight = (int16) pq_getmsgint(buf, sizeof(int16));
822  /* we allow any int16 for weight --- OK? */
823 
824  value.sign = (uint16) pq_getmsgint(buf, sizeof(uint16));
825  if (!(value.sign == NUMERIC_POS ||
826  value.sign == NUMERIC_NEG ||
827  value.sign == NUMERIC_NAN))
828  ereport(ERROR,
829  (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
830  errmsg("invalid sign in external \"numeric\" value")));
831 
832  value.dscale = (uint16) pq_getmsgint(buf, sizeof(uint16));
833  if ((value.dscale & NUMERIC_DSCALE_MASK) != value.dscale)
834  ereport(ERROR,
835  (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
836  errmsg("invalid scale in external \"numeric\" value")));
837 
838  for (i = 0; i < len; i++)
839  {
840  NumericDigit d = pq_getmsgint(buf, sizeof(NumericDigit));
841 
842  if (d < 0 || d >= NBASE)
843  ereport(ERROR,
844  (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
845  errmsg("invalid digit in external \"numeric\" value")));
846  value.digits[i] = d;
847  }
848 
849  /*
850  * If the given dscale would hide any digits, truncate those digits away.
851  * We could alternatively throw an error, but that would take a bunch of
852  * extra code (about as much as trunc_var involves), and it might cause
853  * client compatibility issues.
854  */
855  trunc_var(&value, value.dscale);
856 
857  apply_typmod(&value, typmod);
858 
859  res = make_result(&value);
860  free_var(&value);
861 
862  PG_RETURN_NUMERIC(res);
863 }
864 
865 /*
866  * numeric_send - converts numeric to binary format
867  */
868 Datum
870 {
871  Numeric num = PG_GETARG_NUMERIC(0);
872  NumericVar x;
874  int i;
875 
876  init_var_from_num(num, &x);
877 
878  pq_begintypsend(&buf);
879 
880  pq_sendint16(&buf, x.ndigits);
881  pq_sendint16(&buf, x.weight);
882  pq_sendint16(&buf, x.sign);
883  pq_sendint16(&buf, x.dscale);
884  for (i = 0; i < x.ndigits; i++)
885  pq_sendint16(&buf, x.digits[i]);
886 
888 }
889 
890 
891 /*
892  * numeric_transform() -
893  *
894  * Flatten calls to numeric's length coercion function that solely represent
895  * increases in allowable precision. Scale changes mutate every datum, so
896  * they are unoptimizable. Some values, e.g. 1E-1001, can only fit into an
897  * unconstrained numeric, so a change from an unconstrained numeric to any
898  * constrained numeric is also unoptimizable.
899  */
900 Datum
902 {
904  Node *ret = NULL;
905  Node *typmod;
906 
907  Assert(list_length(expr->args) >= 2);
908 
909  typmod = (Node *) lsecond(expr->args);
910 
911  if (IsA(typmod, Const) &&!((Const *) typmod)->constisnull)
912  {
913  Node *source = (Node *) linitial(expr->args);
914  int32 old_typmod = exprTypmod(source);
915  int32 new_typmod = DatumGetInt32(((Const *) typmod)->constvalue);
916  int32 old_scale = (old_typmod - VARHDRSZ) & 0xffff;
917  int32 new_scale = (new_typmod - VARHDRSZ) & 0xffff;
918  int32 old_precision = (old_typmod - VARHDRSZ) >> 16 & 0xffff;
919  int32 new_precision = (new_typmod - VARHDRSZ) >> 16 & 0xffff;
920 
921  /*
922  * If new_typmod < VARHDRSZ, the destination is unconstrained; that's
923  * always OK. If old_typmod >= VARHDRSZ, the source is constrained,
924  * and we're OK if the scale is unchanged and the precision is not
925  * decreasing. See further notes in function header comment.
926  */
927  if (new_typmod < (int32) VARHDRSZ ||
928  (old_typmod >= (int32) VARHDRSZ &&
929  new_scale == old_scale && new_precision >= old_precision))
930  ret = relabel_to_typmod(source, new_typmod);
931  }
932 
933  PG_RETURN_POINTER(ret);
934 }
935 
936 /*
937  * numeric() -
938  *
939  * This is a special function called by the Postgres database system
940  * before a value is stored in a tuple's attribute. The precision and
941  * scale of the attribute have to be applied on the value.
942  */
943 Datum
945 {
946  Numeric num = PG_GETARG_NUMERIC(0);
947  int32 typmod = PG_GETARG_INT32(1);
948  Numeric new;
949  int32 tmp_typmod;
950  int precision;
951  int scale;
952  int ddigits;
953  int maxdigits;
954  NumericVar var;
955 
956  /*
957  * Handle NaN
958  */
959  if (NUMERIC_IS_NAN(num))
960  PG_RETURN_NUMERIC(make_result(&const_nan));
961 
962  /*
963  * If the value isn't a valid type modifier, simply return a copy of the
964  * input value
965  */
966  if (typmod < (int32) (VARHDRSZ))
967  {
968  new = (Numeric) palloc(VARSIZE(num));
969  memcpy(new, num, VARSIZE(num));
970  PG_RETURN_NUMERIC(new);
971  }
972 
973  /*
974  * Get the precision and scale out of the typmod value
975  */
976  tmp_typmod = typmod - VARHDRSZ;
977  precision = (tmp_typmod >> 16) & 0xffff;
978  scale = tmp_typmod & 0xffff;
979  maxdigits = precision - scale;
980 
981  /*
982  * If the number is certainly in bounds and due to the target scale no
983  * rounding could be necessary, just make a copy of the input and modify
984  * its scale fields, unless the larger scale forces us to abandon the
985  * short representation. (Note we assume the existing dscale is
986  * honest...)
987  */
988  ddigits = (NUMERIC_WEIGHT(num) + 1) * DEC_DIGITS;
989  if (ddigits <= maxdigits && scale >= NUMERIC_DSCALE(num)
990  && (NUMERIC_CAN_BE_SHORT(scale, NUMERIC_WEIGHT(num))
991  || !NUMERIC_IS_SHORT(num)))
992  {
993  new = (Numeric) palloc(VARSIZE(num));
994  memcpy(new, num, VARSIZE(num));
995  if (NUMERIC_IS_SHORT(num))
996  new->choice.n_short.n_header =
998  | (scale << NUMERIC_SHORT_DSCALE_SHIFT);
999  else
1000  new->choice.n_long.n_sign_dscale = NUMERIC_SIGN(new) |
1001  ((uint16) scale & NUMERIC_DSCALE_MASK);
1002  PG_RETURN_NUMERIC(new);
1003  }
1004 
1005  /*
1006  * We really need to fiddle with things - unpack the number into a
1007  * variable and let apply_typmod() do it.
1008  */
1009  init_var(&var);
1010 
1011  set_var_from_num(num, &var);
1012  apply_typmod(&var, typmod);
1013  new = make_result(&var);
1014 
1015  free_var(&var);
1016 
1017  PG_RETURN_NUMERIC(new);
1018 }
1019 
1020 Datum
1022 {
1024  int32 *tl;
1025  int n;
1026  int32 typmod;
1027 
1028  tl = ArrayGetIntegerTypmods(ta, &n);
1029 
1030  if (n == 2)
1031  {
1032  if (tl[0] < 1 || tl[0] > NUMERIC_MAX_PRECISION)
1033  ereport(ERROR,
1034  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1035  errmsg("NUMERIC precision %d must be between 1 and %d",
1036  tl[0], NUMERIC_MAX_PRECISION)));
1037  if (tl[1] < 0 || tl[1] > tl[0])
1038  ereport(ERROR,
1039  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1040  errmsg("NUMERIC scale %d must be between 0 and precision %d",
1041  tl[1], tl[0])));
1042  typmod = ((tl[0] << 16) | tl[1]) + VARHDRSZ;
1043  }
1044  else if (n == 1)
1045  {
1046  if (tl[0] < 1 || tl[0] > NUMERIC_MAX_PRECISION)
1047  ereport(ERROR,
1048  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1049  errmsg("NUMERIC precision %d must be between 1 and %d",
1050  tl[0], NUMERIC_MAX_PRECISION)));
1051  /* scale defaults to zero */
1052  typmod = (tl[0] << 16) + VARHDRSZ;
1053  }
1054  else
1055  {
1056  ereport(ERROR,
1057  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1058  errmsg("invalid NUMERIC type modifier")));
1059  typmod = 0; /* keep compiler quiet */
1060  }
1061 
1062  PG_RETURN_INT32(typmod);
1063 }
1064 
1065 Datum
1067 {
1068  int32 typmod = PG_GETARG_INT32(0);
1069  char *res = (char *) palloc(64);
1070 
1071  if (typmod >= 0)
1072  snprintf(res, 64, "(%d,%d)",
1073  ((typmod - VARHDRSZ) >> 16) & 0xffff,
1074  (typmod - VARHDRSZ) & 0xffff);
1075  else
1076  *res = '\0';
1077 
1078  PG_RETURN_CSTRING(res);
1079 }
1080 
1081 
1082 /* ----------------------------------------------------------------------
1083  *
1084  * Sign manipulation, rounding and the like
1085  *
1086  * ----------------------------------------------------------------------
1087  */
1088 
1089 Datum
1091 {
1092  Numeric num = PG_GETARG_NUMERIC(0);
1093  Numeric res;
1094 
1095  /*
1096  * Handle NaN
1097  */
1098  if (NUMERIC_IS_NAN(num))
1099  PG_RETURN_NUMERIC(make_result(&const_nan));
1100 
1101  /*
1102  * Do it the easy way directly on the packed format
1103  */
1104  res = (Numeric) palloc(VARSIZE(num));
1105  memcpy(res, num, VARSIZE(num));
1106 
1107  if (NUMERIC_IS_SHORT(num))
1108  res->choice.n_short.n_header =
1110  else
1112 
1113  PG_RETURN_NUMERIC(res);
1114 }
1115 
1116 
1117 Datum
1119 {
1120  Numeric num = PG_GETARG_NUMERIC(0);
1121  Numeric res;
1122 
1123  /*
1124  * Handle NaN
1125  */
1126  if (NUMERIC_IS_NAN(num))
1127  PG_RETURN_NUMERIC(make_result(&const_nan));
1128 
1129  /*
1130  * Do it the easy way directly on the packed format
1131  */
1132  res = (Numeric) palloc(VARSIZE(num));
1133  memcpy(res, num, VARSIZE(num));
1134 
1135  /*
1136  * The packed format is known to be totally zero digit trimmed always. So
1137  * we can identify a ZERO by the fact that there are no digits at all. Do
1138  * nothing to a zero.
1139  */
1140  if (NUMERIC_NDIGITS(num) != 0)
1141  {
1142  /* Else, flip the sign */
1143  if (NUMERIC_IS_SHORT(num))
1144  res->choice.n_short.n_header =
1146  else if (NUMERIC_SIGN(num) == NUMERIC_POS)
1147  res->choice.n_long.n_sign_dscale =
1148  NUMERIC_NEG | NUMERIC_DSCALE(num);
1149  else
1150  res->choice.n_long.n_sign_dscale =
1151  NUMERIC_POS | NUMERIC_DSCALE(num);
1152  }
1153 
1154  PG_RETURN_NUMERIC(res);
1155 }
1156 
1157 
1158 Datum
1160 {
1161  Numeric num = PG_GETARG_NUMERIC(0);
1162  Numeric res;
1163 
1164  res = (Numeric) palloc(VARSIZE(num));
1165  memcpy(res, num, VARSIZE(num));
1166 
1167  PG_RETURN_NUMERIC(res);
1168 }
1169 
1170 /*
1171  * numeric_sign() -
1172  *
1173  * returns -1 if the argument is less than 0, 0 if the argument is equal
1174  * to 0, and 1 if the argument is greater than zero.
1175  */
1176 Datum
1178 {
1179  Numeric num = PG_GETARG_NUMERIC(0);
1180  Numeric res;
1181  NumericVar result;
1182 
1183  /*
1184  * Handle NaN
1185  */
1186  if (NUMERIC_IS_NAN(num))
1187  PG_RETURN_NUMERIC(make_result(&const_nan));
1188 
1189  init_var(&result);
1190 
1191  /*
1192  * The packed format is known to be totally zero digit trimmed always. So
1193  * we can identify a ZERO by the fact that there are no digits at all.
1194  */
1195  if (NUMERIC_NDIGITS(num) == 0)
1196  set_var_from_var(&const_zero, &result);
1197  else
1198  {
1199  /*
1200  * And if there are some, we return a copy of ONE with the sign of our
1201  * argument
1202  */
1203  set_var_from_var(&const_one, &result);
1204  result.sign = NUMERIC_SIGN(num);
1205  }
1206 
1207  res = make_result(&result);
1208  free_var(&result);
1209 
1210  PG_RETURN_NUMERIC(res);
1211 }
1212 
1213 
1214 /*
1215  * numeric_round() -
1216  *
1217  * Round a value to have 'scale' digits after the decimal point.
1218  * We allow negative 'scale', implying rounding before the decimal
1219  * point --- Oracle interprets rounding that way.
1220  */
1221 Datum
1223 {
1224  Numeric num = PG_GETARG_NUMERIC(0);
1226  Numeric res;
1227  NumericVar arg;
1228 
1229  /*
1230  * Handle NaN
1231  */
1232  if (NUMERIC_IS_NAN(num))
1233  PG_RETURN_NUMERIC(make_result(&const_nan));
1234 
1235  /*
1236  * Limit the scale value to avoid possible overflow in calculations
1237  */
1238  scale = Max(scale, -NUMERIC_MAX_RESULT_SCALE);
1239  scale = Min(scale, NUMERIC_MAX_RESULT_SCALE);
1240 
1241  /*
1242  * Unpack the argument and round it at the proper digit position
1243  */
1244  init_var(&arg);
1245  set_var_from_num(num, &arg);
1246 
1247  round_var(&arg, scale);
1248 
1249  /* We don't allow negative output dscale */
1250  if (scale < 0)
1251  arg.dscale = 0;
1252 
1253  /*
1254  * Return the rounded result
1255  */
1256  res = make_result(&arg);
1257 
1258  free_var(&arg);
1259  PG_RETURN_NUMERIC(res);
1260 }
1261 
1262 
1263 /*
1264  * numeric_trunc() -
1265  *
1266  * Truncate a value to have 'scale' digits after the decimal point.
1267  * We allow negative 'scale', implying a truncation before the decimal
1268  * point --- Oracle interprets truncation that way.
1269  */
1270 Datum
1272 {
1273  Numeric num = PG_GETARG_NUMERIC(0);
1275  Numeric res;
1276  NumericVar arg;
1277 
1278  /*
1279  * Handle NaN
1280  */
1281  if (NUMERIC_IS_NAN(num))
1282  PG_RETURN_NUMERIC(make_result(&const_nan));
1283 
1284  /*
1285  * Limit the scale value to avoid possible overflow in calculations
1286  */
1287  scale = Max(scale, -NUMERIC_MAX_RESULT_SCALE);
1288  scale = Min(scale, NUMERIC_MAX_RESULT_SCALE);
1289 
1290  /*
1291  * Unpack the argument and truncate it at the proper digit position
1292  */
1293  init_var(&arg);
1294  set_var_from_num(num, &arg);
1295 
1296  trunc_var(&arg, scale);
1297 
1298  /* We don't allow negative output dscale */
1299  if (scale < 0)
1300  arg.dscale = 0;
1301 
1302  /*
1303  * Return the truncated result
1304  */
1305  res = make_result(&arg);
1306 
1307  free_var(&arg);
1308  PG_RETURN_NUMERIC(res);
1309 }
1310 
1311 
1312 /*
1313  * numeric_ceil() -
1314  *
1315  * Return the smallest integer greater than or equal to the argument
1316  */
1317 Datum
1319 {
1320  Numeric num = PG_GETARG_NUMERIC(0);
1321  Numeric res;
1322  NumericVar result;
1323 
1324  if (NUMERIC_IS_NAN(num))
1325  PG_RETURN_NUMERIC(make_result(&const_nan));
1326 
1327  init_var_from_num(num, &result);
1328  ceil_var(&result, &result);
1329 
1330  res = make_result(&result);
1331  free_var(&result);
1332 
1333  PG_RETURN_NUMERIC(res);
1334 }
1335 
1336 
1337 /*
1338  * numeric_floor() -
1339  *
1340  * Return the largest integer equal to or less than the argument
1341  */
1342 Datum
1344 {
1345  Numeric num = PG_GETARG_NUMERIC(0);
1346  Numeric res;
1347  NumericVar result;
1348 
1349  if (NUMERIC_IS_NAN(num))
1350  PG_RETURN_NUMERIC(make_result(&const_nan));
1351 
1352  init_var_from_num(num, &result);
1353  floor_var(&result, &result);
1354 
1355  res = make_result(&result);
1356  free_var(&result);
1357 
1358  PG_RETURN_NUMERIC(res);
1359 }
1360 
1361 
1362 /*
1363  * generate_series_numeric() -
1364  *
1365  * Generate series of numeric.
1366  */
1367 Datum
1369 {
1370  return generate_series_step_numeric(fcinfo);
1371 }
1372 
1373 Datum
1375 {
1377  FuncCallContext *funcctx;
1378  MemoryContext oldcontext;
1379 
1380  if (SRF_IS_FIRSTCALL())
1381  {
1382  Numeric start_num = PG_GETARG_NUMERIC(0);
1383  Numeric stop_num = PG_GETARG_NUMERIC(1);
1384  NumericVar steploc = const_one;
1385 
1386  /* handle NaN in start and stop values */
1387  if (NUMERIC_IS_NAN(start_num))
1388  ereport(ERROR,
1389  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1390  errmsg("start value cannot be NaN")));
1391 
1392  if (NUMERIC_IS_NAN(stop_num))
1393  ereport(ERROR,
1394  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1395  errmsg("stop value cannot be NaN")));
1396 
1397  /* see if we were given an explicit step size */
1398  if (PG_NARGS() == 3)
1399  {
1400  Numeric step_num = PG_GETARG_NUMERIC(2);
1401 
1402  if (NUMERIC_IS_NAN(step_num))
1403  ereport(ERROR,
1404  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1405  errmsg("step size cannot be NaN")));
1406 
1407  init_var_from_num(step_num, &steploc);
1408 
1409  if (cmp_var(&steploc, &const_zero) == 0)
1410  ereport(ERROR,
1411  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1412  errmsg("step size cannot equal zero")));
1413  }
1414 
1415  /* create a function context for cross-call persistence */
1416  funcctx = SRF_FIRSTCALL_INIT();
1417 
1418  /*
1419  * Switch to memory context appropriate for multiple function calls.
1420  */
1421  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
1422 
1423  /* allocate memory for user context */
1424  fctx = (generate_series_numeric_fctx *)
1426 
1427  /*
1428  * Use fctx to keep state from call to call. Seed current with the
1429  * original start value. We must copy the start_num and stop_num
1430  * values rather than pointing to them, since we may have detoasted
1431  * them in the per-call context.
1432  */
1433  init_var(&fctx->current);
1434  init_var(&fctx->stop);
1435  init_var(&fctx->step);
1436 
1437  set_var_from_num(start_num, &fctx->current);
1438  set_var_from_num(stop_num, &fctx->stop);
1439  set_var_from_var(&steploc, &fctx->step);
1440 
1441  funcctx->user_fctx = fctx;
1442  MemoryContextSwitchTo(oldcontext);
1443  }
1444 
1445  /* stuff done on every call of the function */
1446  funcctx = SRF_PERCALL_SETUP();
1447 
1448  /*
1449  * Get the saved state and use current state as the result of this
1450  * iteration.
1451  */
1452  fctx = funcctx->user_fctx;
1453 
1454  if ((fctx->step.sign == NUMERIC_POS &&
1455  cmp_var(&fctx->current, &fctx->stop) <= 0) ||
1456  (fctx->step.sign == NUMERIC_NEG &&
1457  cmp_var(&fctx->current, &fctx->stop) >= 0))
1458  {
1459  Numeric result = make_result(&fctx->current);
1460 
1461  /* switch to memory context appropriate for iteration calculation */
1462  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
1463 
1464  /* increment current in preparation for next iteration */
1465  add_var(&fctx->current, &fctx->step, &fctx->current);
1466  MemoryContextSwitchTo(oldcontext);
1467 
1468  /* do when there is more left to send */
1469  SRF_RETURN_NEXT(funcctx, NumericGetDatum(result));
1470  }
1471  else
1472  /* do when there is no more left */
1473  SRF_RETURN_DONE(funcctx);
1474 }
1475 
1476 
1477 /*
1478  * Implements the numeric version of the width_bucket() function
1479  * defined by SQL2003. See also width_bucket_float8().
1480  *
1481  * 'bound1' and 'bound2' are the lower and upper bounds of the
1482  * histogram's range, respectively. 'count' is the number of buckets
1483  * in the histogram. width_bucket() returns an integer indicating the
1484  * bucket number that 'operand' belongs to in an equiwidth histogram
1485  * with the specified characteristics. An operand smaller than the
1486  * lower bound is assigned to bucket 0. An operand greater than the
1487  * upper bound is assigned to an additional bucket (with number
1488  * count+1). We don't allow "NaN" for any of the numeric arguments.
1489  */
1490 Datum
1492 {
1493  Numeric operand = PG_GETARG_NUMERIC(0);
1494  Numeric bound1 = PG_GETARG_NUMERIC(1);
1495  Numeric bound2 = PG_GETARG_NUMERIC(2);
1496  int32 count = PG_GETARG_INT32(3);
1497  NumericVar count_var;
1498  NumericVar result_var;
1499  int32 result;
1500 
1501  if (count <= 0)
1502  ereport(ERROR,
1503  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
1504  errmsg("count must be greater than zero")));
1505 
1506  if (NUMERIC_IS_NAN(operand) ||
1507  NUMERIC_IS_NAN(bound1) ||
1508  NUMERIC_IS_NAN(bound2))
1509  ereport(ERROR,
1510  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
1511  errmsg("operand, lower bound, and upper bound cannot be NaN")));
1512 
1513  init_var(&result_var);
1514  init_var(&count_var);
1515 
1516  /* Convert 'count' to a numeric, for ease of use later */
1517  int64_to_numericvar((int64) count, &count_var);
1518 
1519  switch (cmp_numerics(bound1, bound2))
1520  {
1521  case 0:
1522  ereport(ERROR,
1523  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
1524  errmsg("lower bound cannot equal upper bound")));
1525 
1526  /* bound1 < bound2 */
1527  case -1:
1528  if (cmp_numerics(operand, bound1) < 0)
1529  set_var_from_var(&const_zero, &result_var);
1530  else if (cmp_numerics(operand, bound2) >= 0)
1531  add_var(&count_var, &const_one, &result_var);
1532  else
1533  compute_bucket(operand, bound1, bound2,
1534  &count_var, &result_var);
1535  break;
1536 
1537  /* bound1 > bound2 */
1538  case 1:
1539  if (cmp_numerics(operand, bound1) > 0)
1540  set_var_from_var(&const_zero, &result_var);
1541  else if (cmp_numerics(operand, bound2) <= 0)
1542  add_var(&count_var, &const_one, &result_var);
1543  else
1544  compute_bucket(operand, bound1, bound2,
1545  &count_var, &result_var);
1546  break;
1547  }
1548 
1549  /* if result exceeds the range of a legal int4, we ereport here */
1550  result = numericvar_to_int32(&result_var);
1551 
1552  free_var(&count_var);
1553  free_var(&result_var);
1554 
1555  PG_RETURN_INT32(result);
1556 }
1557 
1558 /*
1559  * If 'operand' is not outside the bucket range, determine the correct
1560  * bucket for it to go. The calculations performed by this function
1561  * are derived directly from the SQL2003 spec.
1562  */
1563 static void
1564 compute_bucket(Numeric operand, Numeric bound1, Numeric bound2,
1565  const NumericVar *count_var, NumericVar *result_var)
1566 {
1567  NumericVar bound1_var;
1568  NumericVar bound2_var;
1569  NumericVar operand_var;
1570 
1571  init_var_from_num(bound1, &bound1_var);
1572  init_var_from_num(bound2, &bound2_var);
1573  init_var_from_num(operand, &operand_var);
1574 
1575  if (cmp_var(&bound1_var, &bound2_var) < 0)
1576  {
1577  sub_var(&operand_var, &bound1_var, &operand_var);
1578  sub_var(&bound2_var, &bound1_var, &bound2_var);
1579  div_var(&operand_var, &bound2_var, result_var,
1580  select_div_scale(&operand_var, &bound2_var), true);
1581  }
1582  else
1583  {
1584  sub_var(&bound1_var, &operand_var, &operand_var);
1585  sub_var(&bound1_var, &bound2_var, &bound1_var);
1586  div_var(&operand_var, &bound1_var, result_var,
1587  select_div_scale(&operand_var, &bound1_var), true);
1588  }
1589 
1590  mul_var(result_var, count_var, result_var,
1591  result_var->dscale + count_var->dscale);
1592  add_var(result_var, &const_one, result_var);
1593  floor_var(result_var, result_var);
1594 
1595  free_var(&bound1_var);
1596  free_var(&bound2_var);
1597  free_var(&operand_var);
1598 }
1599 
1600 /* ----------------------------------------------------------------------
1601  *
1602  * Comparison functions
1603  *
1604  * Note: btree indexes need these routines not to leak memory; therefore,
1605  * be careful to free working copies of toasted datums. Most places don't
1606  * need to be so careful.
1607  *
1608  * Sort support:
1609  *
1610  * We implement the sortsupport strategy routine in order to get the benefit of
1611  * abbreviation. The ordinary numeric comparison can be quite slow as a result
1612  * of palloc/pfree cycles (due to detoasting packed values for alignment);
1613  * while this could be worked on itself, the abbreviation strategy gives more
1614  * speedup in many common cases.
1615  *
1616  * Two different representations are used for the abbreviated form, one in
1617  * int32 and one in int64, whichever fits into a by-value Datum. In both cases
1618  * the representation is negated relative to the original value, because we use
1619  * the largest negative value for NaN, which sorts higher than other values. We
1620  * convert the absolute value of the numeric to a 31-bit or 63-bit positive
1621  * value, and then negate it if the original number was positive.
1622  *
1623  * We abort the abbreviation process if the abbreviation cardinality is below
1624  * 0.01% of the row count (1 per 10k non-null rows). The actual break-even
1625  * point is somewhat below that, perhaps 1 per 30k (at 1 per 100k there's a
1626  * very small penalty), but we don't want to build up too many abbreviated
1627  * values before first testing for abort, so we take the slightly pessimistic
1628  * number. We make no attempt to estimate the cardinality of the real values,
1629  * since it plays no part in the cost model here (if the abbreviation is equal,
1630  * the cost of comparing equal and unequal underlying values is comparable).
1631  * We discontinue even checking for abort (saving us the hashing overhead) if
1632  * the estimated cardinality gets to 100k; that would be enough to support many
1633  * billions of rows while doing no worse than breaking even.
1634  *
1635  * ----------------------------------------------------------------------
1636  */
1637 
1638 /*
1639  * Sort support strategy routine.
1640  */
1641 Datum
1643 {
1645 
1646  ssup->comparator = numeric_fast_cmp;
1647 
1648  if (ssup->abbreviate)
1649  {
1650  NumericSortSupport *nss;
1651  MemoryContext oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
1652 
1653  nss = palloc(sizeof(NumericSortSupport));
1654 
1655  /*
1656  * palloc a buffer for handling unaligned packed values in addition to
1657  * the support struct
1658  */
1659  nss->buf = palloc(VARATT_SHORT_MAX + VARHDRSZ + 1);
1660 
1661  nss->input_count = 0;
1662  nss->estimating = true;
1663  initHyperLogLog(&nss->abbr_card, 10);
1664 
1665  ssup->ssup_extra = nss;
1666 
1667  ssup->abbrev_full_comparator = ssup->comparator;
1671 
1672  MemoryContextSwitchTo(oldcontext);
1673  }
1674 
1675  PG_RETURN_VOID();
1676 }
1677 
1678 /*
1679  * Abbreviate a numeric datum, handling NaNs and detoasting
1680  * (must not leak memory!)
1681  */
1682 static Datum
1684 {
1685  NumericSortSupport *nss = ssup->ssup_extra;
1686  void *original_varatt = PG_DETOAST_DATUM_PACKED(original_datum);
1687  Numeric value;
1688  Datum result;
1689 
1690  nss->input_count += 1;
1691 
1692  /*
1693  * This is to handle packed datums without needing a palloc/pfree cycle;
1694  * we keep and reuse a buffer large enough to handle any short datum.
1695  */
1696  if (VARATT_IS_SHORT(original_varatt))
1697  {
1698  void *buf = nss->buf;
1699  Size sz = VARSIZE_SHORT(original_varatt) - VARHDRSZ_SHORT;
1700 
1702 
1703  SET_VARSIZE(buf, VARHDRSZ + sz);
1704  memcpy(VARDATA(buf), VARDATA_SHORT(original_varatt), sz);
1705 
1706  value = (Numeric) buf;
1707  }
1708  else
1709  value = (Numeric) original_varatt;
1710 
1711  if (NUMERIC_IS_NAN(value))
1712  {
1713  result = NUMERIC_ABBREV_NAN;
1714  }
1715  else
1716  {
1717  NumericVar var;
1718 
1719  init_var_from_num(value, &var);
1720 
1721  result = numeric_abbrev_convert_var(&var, nss);
1722  }
1723 
1724  /* should happen only for external/compressed toasts */
1725  if ((Pointer) original_varatt != DatumGetPointer(original_datum))
1726  pfree(original_varatt);
1727 
1728  return result;
1729 }
1730 
1731 /*
1732  * Consider whether to abort abbreviation.
1733  *
1734  * We pay no attention to the cardinality of the non-abbreviated data. There is
1735  * no reason to do so: unlike text, we have no fast check for equal values, so
1736  * we pay the full overhead whenever the abbreviations are equal regardless of
1737  * whether the underlying values are also equal.
1738  */
1739 static bool
1740 numeric_abbrev_abort(int memtupcount, SortSupport ssup)
1741 {
1742  NumericSortSupport *nss = ssup->ssup_extra;
1743  double abbr_card;
1744 
1745  if (memtupcount < 10000 || nss->input_count < 10000 || !nss->estimating)
1746  return false;
1747 
1748  abbr_card = estimateHyperLogLog(&nss->abbr_card);
1749 
1750  /*
1751  * If we have >100k distinct values, then even if we were sorting many
1752  * billion rows we'd likely still break even, and the penalty of undoing
1753  * that many rows of abbrevs would probably not be worth it. Stop even
1754  * counting at that point.
1755  */
1756  if (abbr_card > 100000.0)
1757  {
1758 #ifdef TRACE_SORT
1759  if (trace_sort)
1760  elog(LOG,
1761  "numeric_abbrev: estimation ends at cardinality %f"
1762  " after " INT64_FORMAT " values (%d rows)",
1763  abbr_card, nss->input_count, memtupcount);
1764 #endif
1765  nss->estimating = false;
1766  return false;
1767  }
1768 
1769  /*
1770  * Target minimum cardinality is 1 per ~10k of non-null inputs. (The
1771  * break even point is somewhere between one per 100k rows, where
1772  * abbreviation has a very slight penalty, and 1 per 10k where it wins by
1773  * a measurable percentage.) We use the relatively pessimistic 10k
1774  * threshold, and add a 0.5 row fudge factor, because it allows us to
1775  * abort earlier on genuinely pathological data where we've had exactly
1776  * one abbreviated value in the first 10k (non-null) rows.
1777  */
1778  if (abbr_card < nss->input_count / 10000.0 + 0.5)
1779  {
1780 #ifdef TRACE_SORT
1781  if (trace_sort)
1782  elog(LOG,
1783  "numeric_abbrev: aborting abbreviation at cardinality %f"
1784  " below threshold %f after " INT64_FORMAT " values (%d rows)",
1785  abbr_card, nss->input_count / 10000.0 + 0.5,
1786  nss->input_count, memtupcount);
1787 #endif
1788  return true;
1789  }
1790 
1791 #ifdef TRACE_SORT
1792  if (trace_sort)
1793  elog(LOG,
1794  "numeric_abbrev: cardinality %f"
1795  " after " INT64_FORMAT " values (%d rows)",
1796  abbr_card, nss->input_count, memtupcount);
1797 #endif
1798 
1799  return false;
1800 }
1801 
1802 /*
1803  * Non-fmgr interface to the comparison routine to allow sortsupport to elide
1804  * the fmgr call. The saving here is small given how slow numeric comparisons
1805  * are, but it is a required part of the sort support API when abbreviations
1806  * are performed.
1807  *
1808  * Two palloc/pfree cycles could be saved here by using persistent buffers for
1809  * aligning short-varlena inputs, but this has not so far been considered to
1810  * be worth the effort.
1811  */
1812 static int
1814 {
1815  Numeric nx = DatumGetNumeric(x);
1816  Numeric ny = DatumGetNumeric(y);
1817  int result;
1818 
1819  result = cmp_numerics(nx, ny);
1820 
1821  if ((Pointer) nx != DatumGetPointer(x))
1822  pfree(nx);
1823  if ((Pointer) ny != DatumGetPointer(y))
1824  pfree(ny);
1825 
1826  return result;
1827 }
1828 
1829 /*
1830  * Compare abbreviations of values. (Abbreviations may be equal where the true
1831  * values differ, but if the abbreviations differ, they must reflect the
1832  * ordering of the true values.)
1833  */
1834 static int
1836 {
1837  /*
1838  * NOTE WELL: this is intentionally backwards, because the abbreviation is
1839  * negated relative to the original value, to handle NaN.
1840  */
1842  return 1;
1844  return -1;
1845  return 0;
1846 }
1847 
1848 /*
1849  * Abbreviate a NumericVar according to the available bit size.
1850  *
1851  * The 31-bit value is constructed as:
1852  *
1853  * 0 + 7bits digit weight + 24 bits digit value
1854  *
1855  * where the digit weight is in single decimal digits, not digit words, and
1856  * stored in excess-44 representation[1]. The 24-bit digit value is the 7 most
1857  * significant decimal digits of the value converted to binary. Values whose
1858  * weights would fall outside the representable range are rounded off to zero
1859  * (which is also used to represent actual zeros) or to 0x7FFFFFFF (which
1860  * otherwise cannot occur). Abbreviation therefore fails to gain any advantage
1861  * where values are outside the range 10^-44 to 10^83, which is not considered
1862  * to be a serious limitation, or when values are of the same magnitude and
1863  * equal in the first 7 decimal digits, which is considered to be an
1864  * unavoidable limitation given the available bits. (Stealing three more bits
1865  * to compare another digit would narrow the range of representable weights by
1866  * a factor of 8, which starts to look like a real limiting factor.)
1867  *
1868  * (The value 44 for the excess is essentially arbitrary)
1869  *
1870  * The 63-bit value is constructed as:
1871  *
1872  * 0 + 7bits weight + 4 x 14-bit packed digit words
1873  *
1874  * The weight in this case is again stored in excess-44, but this time it is
1875  * the original weight in digit words (i.e. powers of 10000). The first four
1876  * digit words of the value (if present; trailing zeros are assumed as needed)
1877  * are packed into 14 bits each to form the rest of the value. Again,
1878  * out-of-range values are rounded off to 0 or 0x7FFFFFFFFFFFFFFF. The
1879  * representable range in this case is 10^-176 to 10^332, which is considered
1880  * to be good enough for all practical purposes, and comparison of 4 words
1881  * means that at least 13 decimal digits are compared, which is considered to
1882  * be a reasonable compromise between effectiveness and efficiency in computing
1883  * the abbreviation.
1884  *
1885  * (The value 44 for the excess is even more arbitrary here, it was chosen just
1886  * to match the value used in the 31-bit case)
1887  *
1888  * [1] - Excess-k representation means that the value is offset by adding 'k'
1889  * and then treated as unsigned, so the smallest representable value is stored
1890  * with all bits zero. This allows simple comparisons to work on the composite
1891  * value.
1892  */
1893 
1894 #if NUMERIC_ABBREV_BITS == 64
1895 
1896 static Datum
1898 {
1899  int ndigits = var->ndigits;
1900  int weight = var->weight;
1901  int64 result;
1902 
1903  if (ndigits == 0 || weight < -44)
1904  {
1905  result = 0;
1906  }
1907  else if (weight > 83)
1908  {
1909  result = PG_INT64_MAX;
1910  }
1911  else
1912  {
1913  result = ((int64) (weight + 44) << 56);
1914 
1915  switch (ndigits)
1916  {
1917  default:
1918  result |= ((int64) var->digits[3]);
1919  /* FALLTHROUGH */
1920  case 3:
1921  result |= ((int64) var->digits[2]) << 14;
1922  /* FALLTHROUGH */
1923  case 2:
1924  result |= ((int64) var->digits[1]) << 28;
1925  /* FALLTHROUGH */
1926  case 1:
1927  result |= ((int64) var->digits[0]) << 42;
1928  break;
1929  }
1930  }
1931 
1932  /* the abbrev is negated relative to the original */
1933  if (var->sign == NUMERIC_POS)
1934  result = -result;
1935 
1936  if (nss->estimating)
1937  {
1938  uint32 tmp = ((uint32) result
1939  ^ (uint32) ((uint64) result >> 32));
1940 
1942  }
1943 
1944  return NumericAbbrevGetDatum(result);
1945 }
1946 
1947 #endif /* NUMERIC_ABBREV_BITS == 64 */
1948 
1949 #if NUMERIC_ABBREV_BITS == 32
1950 
1951 static Datum
1953 {
1954  int ndigits = var->ndigits;
1955  int weight = var->weight;
1956  int32 result;
1957 
1958  if (ndigits == 0 || weight < -11)
1959  {
1960  result = 0;
1961  }
1962  else if (weight > 20)
1963  {
1964  result = PG_INT32_MAX;
1965  }
1966  else
1967  {
1968  NumericDigit nxt1 = (ndigits > 1) ? var->digits[1] : 0;
1969 
1970  weight = (weight + 11) * 4;
1971 
1972  result = var->digits[0];
1973 
1974  /*
1975  * "result" now has 1 to 4 nonzero decimal digits. We pack in more
1976  * digits to make 7 in total (largest we can fit in 24 bits)
1977  */
1978 
1979  if (result > 999)
1980  {
1981  /* already have 4 digits, add 3 more */
1982  result = (result * 1000) + (nxt1 / 10);
1983  weight += 3;
1984  }
1985  else if (result > 99)
1986  {
1987  /* already have 3 digits, add 4 more */
1988  result = (result * 10000) + nxt1;
1989  weight += 2;
1990  }
1991  else if (result > 9)
1992  {
1993  NumericDigit nxt2 = (ndigits > 2) ? var->digits[2] : 0;
1994 
1995  /* already have 2 digits, add 5 more */
1996  result = (result * 100000) + (nxt1 * 10) + (nxt2 / 1000);
1997  weight += 1;
1998  }
1999  else
2000  {
2001  NumericDigit nxt2 = (ndigits > 2) ? var->digits[2] : 0;
2002 
2003  /* already have 1 digit, add 6 more */
2004  result = (result * 1000000) + (nxt1 * 100) + (nxt2 / 100);
2005  }
2006 
2007  result = result | (weight << 24);
2008  }
2009 
2010  /* the abbrev is negated relative to the original */
2011  if (var->sign == NUMERIC_POS)
2012  result = -result;
2013 
2014  if (nss->estimating)
2015  {
2016  uint32 tmp = (uint32) result;
2017 
2019  }
2020 
2021  return NumericAbbrevGetDatum(result);
2022 }
2023 
2024 #endif /* NUMERIC_ABBREV_BITS == 32 */
2025 
2026 /*
2027  * Ordinary (non-sortsupport) comparisons follow.
2028  */
2029 
2030 Datum
2032 {
2033  Numeric num1 = PG_GETARG_NUMERIC(0);
2034  Numeric num2 = PG_GETARG_NUMERIC(1);
2035  int result;
2036 
2037  result = cmp_numerics(num1, num2);
2038 
2039  PG_FREE_IF_COPY(num1, 0);
2040  PG_FREE_IF_COPY(num2, 1);
2041 
2042  PG_RETURN_INT32(result);
2043 }
2044 
2045 
2046 Datum
2048 {
2049  Numeric num1 = PG_GETARG_NUMERIC(0);
2050  Numeric num2 = PG_GETARG_NUMERIC(1);
2051  bool result;
2052 
2053  result = cmp_numerics(num1, num2) == 0;
2054 
2055  PG_FREE_IF_COPY(num1, 0);
2056  PG_FREE_IF_COPY(num2, 1);
2057 
2058  PG_RETURN_BOOL(result);
2059 }
2060 
2061 Datum
2063 {
2064  Numeric num1 = PG_GETARG_NUMERIC(0);
2065  Numeric num2 = PG_GETARG_NUMERIC(1);
2066  bool result;
2067 
2068  result = cmp_numerics(num1, num2) != 0;
2069 
2070  PG_FREE_IF_COPY(num1, 0);
2071  PG_FREE_IF_COPY(num2, 1);
2072 
2073  PG_RETURN_BOOL(result);
2074 }
2075 
2076 Datum
2078 {
2079  Numeric num1 = PG_GETARG_NUMERIC(0);
2080  Numeric num2 = PG_GETARG_NUMERIC(1);
2081  bool result;
2082 
2083  result = cmp_numerics(num1, num2) > 0;
2084 
2085  PG_FREE_IF_COPY(num1, 0);
2086  PG_FREE_IF_COPY(num2, 1);
2087 
2088  PG_RETURN_BOOL(result);
2089 }
2090 
2091 Datum
2093 {
2094  Numeric num1 = PG_GETARG_NUMERIC(0);
2095  Numeric num2 = PG_GETARG_NUMERIC(1);
2096  bool result;
2097 
2098  result = cmp_numerics(num1, num2) >= 0;
2099 
2100  PG_FREE_IF_COPY(num1, 0);
2101  PG_FREE_IF_COPY(num2, 1);
2102 
2103  PG_RETURN_BOOL(result);
2104 }
2105 
2106 Datum
2108 {
2109  Numeric num1 = PG_GETARG_NUMERIC(0);
2110  Numeric num2 = PG_GETARG_NUMERIC(1);
2111  bool result;
2112 
2113  result = cmp_numerics(num1, num2) < 0;
2114 
2115  PG_FREE_IF_COPY(num1, 0);
2116  PG_FREE_IF_COPY(num2, 1);
2117 
2118  PG_RETURN_BOOL(result);
2119 }
2120 
2121 Datum
2123 {
2124  Numeric num1 = PG_GETARG_NUMERIC(0);
2125  Numeric num2 = PG_GETARG_NUMERIC(1);
2126  bool result;
2127 
2128  result = cmp_numerics(num1, num2) <= 0;
2129 
2130  PG_FREE_IF_COPY(num1, 0);
2131  PG_FREE_IF_COPY(num2, 1);
2132 
2133  PG_RETURN_BOOL(result);
2134 }
2135 
2136 static int
2138 {
2139  int result;
2140 
2141  /*
2142  * We consider all NANs to be equal and larger than any non-NAN. This is
2143  * somewhat arbitrary; the important thing is to have a consistent sort
2144  * order.
2145  */
2146  if (NUMERIC_IS_NAN(num1))
2147  {
2148  if (NUMERIC_IS_NAN(num2))
2149  result = 0; /* NAN = NAN */
2150  else
2151  result = 1; /* NAN > non-NAN */
2152  }
2153  else if (NUMERIC_IS_NAN(num2))
2154  {
2155  result = -1; /* non-NAN < NAN */
2156  }
2157  else
2158  {
2159  result = cmp_var_common(NUMERIC_DIGITS(num1), NUMERIC_NDIGITS(num1),
2160  NUMERIC_WEIGHT(num1), NUMERIC_SIGN(num1),
2161  NUMERIC_DIGITS(num2), NUMERIC_NDIGITS(num2),
2162  NUMERIC_WEIGHT(num2), NUMERIC_SIGN(num2));
2163  }
2164 
2165  return result;
2166 }
2167 
2168 /*
2169  * in_range support function for numeric.
2170  */
2171 Datum
2173 {
2175  Numeric base = PG_GETARG_NUMERIC(1);
2176  Numeric offset = PG_GETARG_NUMERIC(2);
2177  bool sub = PG_GETARG_BOOL(3);
2178  bool less = PG_GETARG_BOOL(4);
2179  bool result;
2180 
2181  /*
2182  * Reject negative or NaN offset. Negative is per spec, and NaN is
2183  * because appropriate semantics for that seem non-obvious.
2184  */
2185  if (NUMERIC_IS_NAN(offset) || NUMERIC_SIGN(offset) == NUMERIC_NEG)
2186  ereport(ERROR,
2187  (errcode(ERRCODE_INVALID_PRECEDING_FOLLOWING_SIZE),
2188  errmsg("invalid preceding or following size in window function")));
2189 
2190  /*
2191  * Deal with cases where val and/or base is NaN, following the rule that
2192  * NaN sorts after non-NaN (cf cmp_numerics). The offset cannot affect
2193  * the conclusion.
2194  */
2195  if (NUMERIC_IS_NAN(val))
2196  {
2197  if (NUMERIC_IS_NAN(base))
2198  result = true; /* NAN = NAN */
2199  else
2200  result = !less; /* NAN > non-NAN */
2201  }
2202  else if (NUMERIC_IS_NAN(base))
2203  {
2204  result = less; /* non-NAN < NAN */
2205  }
2206  else
2207  {
2208  /*
2209  * Otherwise go ahead and compute base +/- offset. While it's
2210  * possible for this to overflow the numeric format, it's unlikely
2211  * enough that we don't take measures to prevent it.
2212  */
2213  NumericVar valv;
2214  NumericVar basev;
2215  NumericVar offsetv;
2216  NumericVar sum;
2217 
2218  init_var_from_num(val, &valv);
2219  init_var_from_num(base, &basev);
2220  init_var_from_num(offset, &offsetv);
2221  init_var(&sum);
2222 
2223  if (sub)
2224  sub_var(&basev, &offsetv, &sum);
2225  else
2226  add_var(&basev, &offsetv, &sum);
2227 
2228  if (less)
2229  result = (cmp_var(&valv, &sum) <= 0);
2230  else
2231  result = (cmp_var(&valv, &sum) >= 0);
2232 
2233  free_var(&sum);
2234  }
2235 
2236  PG_FREE_IF_COPY(val, 0);
2237  PG_FREE_IF_COPY(base, 1);
2238  PG_FREE_IF_COPY(offset, 2);
2239 
2240  PG_RETURN_BOOL(result);
2241 }
2242 
2243 Datum
2245 {
2246  Numeric key = PG_GETARG_NUMERIC(0);
2247  Datum digit_hash;
2248  Datum result;
2249  int weight;
2250  int start_offset;
2251  int end_offset;
2252  int i;
2253  int hash_len;
2255 
2256  /* If it's NaN, don't try to hash the rest of the fields */
2257  if (NUMERIC_IS_NAN(key))
2258  PG_RETURN_UINT32(0);
2259 
2260  weight = NUMERIC_WEIGHT(key);
2261  start_offset = 0;
2262  end_offset = 0;
2263 
2264  /*
2265  * Omit any leading or trailing zeros from the input to the hash. The
2266  * numeric implementation *should* guarantee that leading and trailing
2267  * zeros are suppressed, but we're paranoid. Note that we measure the
2268  * starting and ending offsets in units of NumericDigits, not bytes.
2269  */
2270  digits = NUMERIC_DIGITS(key);
2271  for (i = 0; i < NUMERIC_NDIGITS(key); i++)
2272  {
2273  if (digits[i] != (NumericDigit) 0)
2274  break;
2275 
2276  start_offset++;
2277 
2278  /*
2279  * The weight is effectively the # of digits before the decimal point,
2280  * so decrement it for each leading zero we skip.
2281  */
2282  weight--;
2283  }
2284 
2285  /*
2286  * If there are no non-zero digits, then the value of the number is zero,
2287  * regardless of any other fields.
2288  */
2289  if (NUMERIC_NDIGITS(key) == start_offset)
2290  PG_RETURN_UINT32(-1);
2291 
2292  for (i = NUMERIC_NDIGITS(key) - 1; i >= 0; i--)
2293  {
2294  if (digits[i] != (NumericDigit) 0)
2295  break;
2296 
2297  end_offset++;
2298  }
2299 
2300  /* If we get here, there should be at least one non-zero digit */
2301  Assert(start_offset + end_offset < NUMERIC_NDIGITS(key));
2302 
2303  /*
2304  * Note that we don't hash on the Numeric's scale, since two numerics can
2305  * compare equal but have different scales. We also don't hash on the
2306  * sign, although we could: since a sign difference implies inequality,
2307  * this shouldn't affect correctness.
2308  */
2309  hash_len = NUMERIC_NDIGITS(key) - start_offset - end_offset;
2310  digit_hash = hash_any((unsigned char *) (NUMERIC_DIGITS(key) + start_offset),
2311  hash_len * sizeof(NumericDigit));
2312 
2313  /* Mix in the weight, via XOR */
2314  result = digit_hash ^ weight;
2315 
2316  PG_RETURN_DATUM(result);
2317 }
2318 
2319 /*
2320  * Returns 64-bit value by hashing a value to a 64-bit value, with a seed.
2321  * Otherwise, similar to hash_numeric.
2322  */
2323 Datum
2325 {
2326  Numeric key = PG_GETARG_NUMERIC(0);
2327  uint64 seed = PG_GETARG_INT64(1);
2328  Datum digit_hash;
2329  Datum result;
2330  int weight;
2331  int start_offset;
2332  int end_offset;
2333  int i;
2334  int hash_len;
2336 
2337  if (NUMERIC_IS_NAN(key))
2338  PG_RETURN_UINT64(seed);
2339 
2340  weight = NUMERIC_WEIGHT(key);
2341  start_offset = 0;
2342  end_offset = 0;
2343 
2344  digits = NUMERIC_DIGITS(key);
2345  for (i = 0; i < NUMERIC_NDIGITS(key); i++)
2346  {
2347  if (digits[i] != (NumericDigit) 0)
2348  break;
2349 
2350  start_offset++;
2351 
2352  weight--;
2353  }
2354 
2355  if (NUMERIC_NDIGITS(key) == start_offset)
2356  PG_RETURN_UINT64(seed - 1);
2357 
2358  for (i = NUMERIC_NDIGITS(key) - 1; i >= 0; i--)
2359  {
2360  if (digits[i] != (NumericDigit) 0)
2361  break;
2362 
2363  end_offset++;
2364  }
2365 
2366  Assert(start_offset + end_offset < NUMERIC_NDIGITS(key));
2367 
2368  hash_len = NUMERIC_NDIGITS(key) - start_offset - end_offset;
2369  digit_hash = hash_any_extended((unsigned char *) (NUMERIC_DIGITS(key)
2370  + start_offset),
2371  hash_len * sizeof(NumericDigit),
2372  seed);
2373 
2374  result = UInt64GetDatum(DatumGetUInt64(digit_hash) ^ weight);
2375 
2376  PG_RETURN_DATUM(result);
2377 }
2378 
2379 
2380 /* ----------------------------------------------------------------------
2381  *
2382  * Basic arithmetic functions
2383  *
2384  * ----------------------------------------------------------------------
2385  */
2386 
2387 
2388 /*
2389  * numeric_add() -
2390  *
2391  * Add two numerics
2392  */
2393 Datum
2395 {
2396  Numeric num1 = PG_GETARG_NUMERIC(0);
2397  Numeric num2 = PG_GETARG_NUMERIC(1);
2398  NumericVar arg1;
2399  NumericVar arg2;
2400  NumericVar result;
2401  Numeric res;
2402 
2403  /*
2404  * Handle NaN
2405  */
2406  if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2407  PG_RETURN_NUMERIC(make_result(&const_nan));
2408 
2409  /*
2410  * Unpack the values, let add_var() compute the result and return it.
2411  */
2412  init_var_from_num(num1, &arg1);
2413  init_var_from_num(num2, &arg2);
2414 
2415  init_var(&result);
2416  add_var(&arg1, &arg2, &result);
2417 
2418  res = make_result(&result);
2419 
2420  free_var(&result);
2421 
2422  PG_RETURN_NUMERIC(res);
2423 }
2424 
2425 
2426 /*
2427  * numeric_sub() -
2428  *
2429  * Subtract one numeric from another
2430  */
2431 Datum
2433 {
2434  Numeric num1 = PG_GETARG_NUMERIC(0);
2435  Numeric num2 = PG_GETARG_NUMERIC(1);
2436  NumericVar arg1;
2437  NumericVar arg2;
2438  NumericVar result;
2439  Numeric res;
2440 
2441  /*
2442  * Handle NaN
2443  */
2444  if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2445  PG_RETURN_NUMERIC(make_result(&const_nan));
2446 
2447  /*
2448  * Unpack the values, let sub_var() compute the result and return it.
2449  */
2450  init_var_from_num(num1, &arg1);
2451  init_var_from_num(num2, &arg2);
2452 
2453  init_var(&result);
2454  sub_var(&arg1, &arg2, &result);
2455 
2456  res = make_result(&result);
2457 
2458  free_var(&result);
2459 
2460  PG_RETURN_NUMERIC(res);
2461 }
2462 
2463 
2464 /*
2465  * numeric_mul() -
2466  *
2467  * Calculate the product of two numerics
2468  */
2469 Datum
2471 {
2472  Numeric num1 = PG_GETARG_NUMERIC(0);
2473  Numeric num2 = PG_GETARG_NUMERIC(1);
2474  NumericVar arg1;
2475  NumericVar arg2;
2476  NumericVar result;
2477  Numeric res;
2478 
2479  /*
2480  * Handle NaN
2481  */
2482  if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2483  PG_RETURN_NUMERIC(make_result(&const_nan));
2484 
2485  /*
2486  * Unpack the values, let mul_var() compute the result and return it.
2487  * Unlike add_var() and sub_var(), mul_var() will round its result. In the
2488  * case of numeric_mul(), which is invoked for the * operator on numerics,
2489  * we request exact representation for the product (rscale = sum(dscale of
2490  * arg1, dscale of arg2)).
2491  */
2492  init_var_from_num(num1, &arg1);
2493  init_var_from_num(num2, &arg2);
2494 
2495  init_var(&result);
2496  mul_var(&arg1, &arg2, &result, arg1.dscale + arg2.dscale);
2497 
2498  res = make_result(&result);
2499 
2500  free_var(&result);
2501 
2502  PG_RETURN_NUMERIC(res);
2503 }
2504 
2505 
2506 /*
2507  * numeric_div() -
2508  *
2509  * Divide one numeric into another
2510  */
2511 Datum
2513 {
2514  Numeric num1 = PG_GETARG_NUMERIC(0);
2515  Numeric num2 = PG_GETARG_NUMERIC(1);
2516  NumericVar arg1;
2517  NumericVar arg2;
2518  NumericVar result;
2519  Numeric res;
2520  int rscale;
2521 
2522  /*
2523  * Handle NaN
2524  */
2525  if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2526  PG_RETURN_NUMERIC(make_result(&const_nan));
2527 
2528  /*
2529  * Unpack the arguments
2530  */
2531  init_var_from_num(num1, &arg1);
2532  init_var_from_num(num2, &arg2);
2533 
2534  init_var(&result);
2535 
2536  /*
2537  * Select scale for division result
2538  */
2539  rscale = select_div_scale(&arg1, &arg2);
2540 
2541  /*
2542  * Do the divide and return the result
2543  */
2544  div_var(&arg1, &arg2, &result, rscale, true);
2545 
2546  res = make_result(&result);
2547 
2548  free_var(&result);
2549 
2550  PG_RETURN_NUMERIC(res);
2551 }
2552 
2553 
2554 /*
2555  * numeric_div_trunc() -
2556  *
2557  * Divide one numeric into another, truncating the result to an integer
2558  */
2559 Datum
2561 {
2562  Numeric num1 = PG_GETARG_NUMERIC(0);
2563  Numeric num2 = PG_GETARG_NUMERIC(1);
2564  NumericVar arg1;
2565  NumericVar arg2;
2566  NumericVar result;
2567  Numeric res;
2568 
2569  /*
2570  * Handle NaN
2571  */
2572  if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2573  PG_RETURN_NUMERIC(make_result(&const_nan));
2574 
2575  /*
2576  * Unpack the arguments
2577  */
2578  init_var_from_num(num1, &arg1);
2579  init_var_from_num(num2, &arg2);
2580 
2581  init_var(&result);
2582 
2583  /*
2584  * Do the divide and return the result
2585  */
2586  div_var(&arg1, &arg2, &result, 0, false);
2587 
2588  res = make_result(&result);
2589 
2590  free_var(&result);
2591 
2592  PG_RETURN_NUMERIC(res);
2593 }
2594 
2595 
2596 /*
2597  * numeric_mod() -
2598  *
2599  * Calculate the modulo of two numerics
2600  */
2601 Datum
2603 {
2604  Numeric num1 = PG_GETARG_NUMERIC(0);
2605  Numeric num2 = PG_GETARG_NUMERIC(1);
2606  Numeric res;
2607  NumericVar arg1;
2608  NumericVar arg2;
2609  NumericVar result;
2610 
2611  if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2612  PG_RETURN_NUMERIC(make_result(&const_nan));
2613 
2614  init_var_from_num(num1, &arg1);
2615  init_var_from_num(num2, &arg2);
2616 
2617  init_var(&result);
2618 
2619  mod_var(&arg1, &arg2, &result);
2620 
2621  res = make_result(&result);
2622 
2623  free_var(&result);
2624 
2625  PG_RETURN_NUMERIC(res);
2626 }
2627 
2628 
2629 /*
2630  * numeric_inc() -
2631  *
2632  * Increment a number by one
2633  */
2634 Datum
2636 {
2637  Numeric num = PG_GETARG_NUMERIC(0);
2638  NumericVar arg;
2639  Numeric res;
2640 
2641  /*
2642  * Handle NaN
2643  */
2644  if (NUMERIC_IS_NAN(num))
2645  PG_RETURN_NUMERIC(make_result(&const_nan));
2646 
2647  /*
2648  * Compute the result and return it
2649  */
2650  init_var_from_num(num, &arg);
2651 
2652  add_var(&arg, &const_one, &arg);
2653 
2654  res = make_result(&arg);
2655 
2656  free_var(&arg);
2657 
2658  PG_RETURN_NUMERIC(res);
2659 }
2660 
2661 
2662 /*
2663  * numeric_smaller() -
2664  *
2665  * Return the smaller of two numbers
2666  */
2667 Datum
2669 {
2670  Numeric num1 = PG_GETARG_NUMERIC(0);
2671  Numeric num2 = PG_GETARG_NUMERIC(1);
2672 
2673  /*
2674  * Use cmp_numerics so that this will agree with the comparison operators,
2675  * particularly as regards comparisons involving NaN.
2676  */
2677  if (cmp_numerics(num1, num2) < 0)
2678  PG_RETURN_NUMERIC(num1);
2679  else
2680  PG_RETURN_NUMERIC(num2);
2681 }
2682 
2683 
2684 /*
2685  * numeric_larger() -
2686  *
2687  * Return the larger of two numbers
2688  */
2689 Datum
2691 {
2692  Numeric num1 = PG_GETARG_NUMERIC(0);
2693  Numeric num2 = PG_GETARG_NUMERIC(1);
2694 
2695  /*
2696  * Use cmp_numerics so that this will agree with the comparison operators,
2697  * particularly as regards comparisons involving NaN.
2698  */
2699  if (cmp_numerics(num1, num2) > 0)
2700  PG_RETURN_NUMERIC(num1);
2701  else
2702  PG_RETURN_NUMERIC(num2);
2703 }
2704 
2705 
2706 /* ----------------------------------------------------------------------
2707  *
2708  * Advanced math functions
2709  *
2710  * ----------------------------------------------------------------------
2711  */
2712 
2713 /*
2714  * numeric_fac()
2715  *
2716  * Compute factorial
2717  */
2718 Datum
2720 {
2721  int64 num = PG_GETARG_INT64(0);
2722  Numeric res;
2723  NumericVar fact;
2724  NumericVar result;
2725 
2726  if (num <= 1)
2727  {
2728  res = make_result(&const_one);
2729  PG_RETURN_NUMERIC(res);
2730  }
2731  /* Fail immediately if the result would overflow */
2732  if (num > 32177)
2733  ereport(ERROR,
2734  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
2735  errmsg("value overflows numeric format")));
2736 
2737  init_var(&fact);
2738  init_var(&result);
2739 
2740  int64_to_numericvar(num, &result);
2741 
2742  for (num = num - 1; num > 1; num--)
2743  {
2744  /* this loop can take awhile, so allow it to be interrupted */
2746 
2747  int64_to_numericvar(num, &fact);
2748 
2749  mul_var(&result, &fact, &result, 0);
2750  }
2751 
2752  res = make_result(&result);
2753 
2754  free_var(&fact);
2755  free_var(&result);
2756 
2757  PG_RETURN_NUMERIC(res);
2758 }
2759 
2760 
2761 /*
2762  * numeric_sqrt() -
2763  *
2764  * Compute the square root of a numeric.
2765  */
2766 Datum
2768 {
2769  Numeric num = PG_GETARG_NUMERIC(0);
2770  Numeric res;
2771  NumericVar arg;
2772  NumericVar result;
2773  int sweight;
2774  int rscale;
2775 
2776  /*
2777  * Handle NaN
2778  */
2779  if (NUMERIC_IS_NAN(num))
2780  PG_RETURN_NUMERIC(make_result(&const_nan));
2781 
2782  /*
2783  * Unpack the argument and determine the result scale. We choose a scale
2784  * to give at least NUMERIC_MIN_SIG_DIGITS significant digits; but in any
2785  * case not less than the input's dscale.
2786  */
2787  init_var_from_num(num, &arg);
2788 
2789  init_var(&result);
2790 
2791  /* Assume the input was normalized, so arg.weight is accurate */
2792  sweight = (arg.weight + 1) * DEC_DIGITS / 2 - 1;
2793 
2794  rscale = NUMERIC_MIN_SIG_DIGITS - sweight;
2795  rscale = Max(rscale, arg.dscale);
2796  rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
2797  rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
2798 
2799  /*
2800  * Let sqrt_var() do the calculation and return the result.
2801  */
2802  sqrt_var(&arg, &result, rscale);
2803 
2804  res = make_result(&result);
2805 
2806  free_var(&result);
2807 
2808  PG_RETURN_NUMERIC(res);
2809 }
2810 
2811 
2812 /*
2813  * numeric_exp() -
2814  *
2815  * Raise e to the power of x
2816  */
2817 Datum
2819 {
2820  Numeric num = PG_GETARG_NUMERIC(0);
2821  Numeric res;
2822  NumericVar arg;
2823  NumericVar result;
2824  int rscale;
2825  double val;
2826 
2827  /*
2828  * Handle NaN
2829  */
2830  if (NUMERIC_IS_NAN(num))
2831  PG_RETURN_NUMERIC(make_result(&const_nan));
2832 
2833  /*
2834  * Unpack the argument and determine the result scale. We choose a scale
2835  * to give at least NUMERIC_MIN_SIG_DIGITS significant digits; but in any
2836  * case not less than the input's dscale.
2837  */
2838  init_var_from_num(num, &arg);
2839 
2840  init_var(&result);
2841 
2842  /* convert input to float8, ignoring overflow */
2844 
2845  /*
2846  * log10(result) = num * log10(e), so this is approximately the decimal
2847  * weight of the result:
2848  */
2849  val *= 0.434294481903252;
2850 
2851  /* limit to something that won't cause integer overflow */
2852  val = Max(val, -NUMERIC_MAX_RESULT_SCALE);
2853  val = Min(val, NUMERIC_MAX_RESULT_SCALE);
2854 
2855  rscale = NUMERIC_MIN_SIG_DIGITS - (int) val;
2856  rscale = Max(rscale, arg.dscale);
2857  rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
2858  rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
2859 
2860  /*
2861  * Let exp_var() do the calculation and return the result.
2862  */
2863  exp_var(&arg, &result, rscale);
2864 
2865  res = make_result(&result);
2866 
2867  free_var(&result);
2868 
2869  PG_RETURN_NUMERIC(res);
2870 }
2871 
2872 
2873 /*
2874  * numeric_ln() -
2875  *
2876  * Compute the natural logarithm of x
2877  */
2878 Datum
2880 {
2881  Numeric num = PG_GETARG_NUMERIC(0);
2882  Numeric res;
2883  NumericVar arg;
2884  NumericVar result;
2885  int ln_dweight;
2886  int rscale;
2887 
2888  /*
2889  * Handle NaN
2890  */
2891  if (NUMERIC_IS_NAN(num))
2892  PG_RETURN_NUMERIC(make_result(&const_nan));
2893 
2894  init_var_from_num(num, &arg);
2895  init_var(&result);
2896 
2897  /* Estimated dweight of logarithm */
2898  ln_dweight = estimate_ln_dweight(&arg);
2899 
2900  rscale = NUMERIC_MIN_SIG_DIGITS - ln_dweight;
2901  rscale = Max(rscale, arg.dscale);
2902  rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
2903  rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
2904 
2905  ln_var(&arg, &result, rscale);
2906 
2907  res = make_result(&result);
2908 
2909  free_var(&result);
2910 
2911  PG_RETURN_NUMERIC(res);
2912 }
2913 
2914 
2915 /*
2916  * numeric_log() -
2917  *
2918  * Compute the logarithm of x in a given base
2919  */
2920 Datum
2922 {
2923  Numeric num1 = PG_GETARG_NUMERIC(0);
2924  Numeric num2 = PG_GETARG_NUMERIC(1);
2925  Numeric res;
2926  NumericVar arg1;
2927  NumericVar arg2;
2928  NumericVar result;
2929 
2930  /*
2931  * Handle NaN
2932  */
2933  if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2934  PG_RETURN_NUMERIC(make_result(&const_nan));
2935 
2936  /*
2937  * Initialize things
2938  */
2939  init_var_from_num(num1, &arg1);
2940  init_var_from_num(num2, &arg2);
2941  init_var(&result);
2942 
2943  /*
2944  * Call log_var() to compute and return the result; note it handles scale
2945  * selection itself.
2946  */
2947  log_var(&arg1, &arg2, &result);
2948 
2949  res = make_result(&result);
2950 
2951  free_var(&result);
2952 
2953  PG_RETURN_NUMERIC(res);
2954 }
2955 
2956 
2957 /*
2958  * numeric_power() -
2959  *
2960  * Raise b to the power of x
2961  */
2962 Datum
2964 {
2965  Numeric num1 = PG_GETARG_NUMERIC(0);
2966  Numeric num2 = PG_GETARG_NUMERIC(1);
2967  Numeric res;
2968  NumericVar arg1;
2969  NumericVar arg2;
2970  NumericVar arg2_trunc;
2971  NumericVar result;
2972 
2973  /*
2974  * Handle NaN
2975  */
2976  if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2977  PG_RETURN_NUMERIC(make_result(&const_nan));
2978 
2979  /*
2980  * Initialize things
2981  */
2982  init_var(&arg2_trunc);
2983  init_var(&result);
2984  init_var_from_num(num1, &arg1);
2985  init_var_from_num(num2, &arg2);
2986 
2987  set_var_from_var(&arg2, &arg2_trunc);
2988  trunc_var(&arg2_trunc, 0);
2989 
2990  /*
2991  * The SQL spec requires that we emit a particular SQLSTATE error code for
2992  * certain error conditions. Specifically, we don't return a
2993  * divide-by-zero error code for 0 ^ -1.
2994  */
2995  if (cmp_var(&arg1, &const_zero) == 0 &&
2996  cmp_var(&arg2, &const_zero) < 0)
2997  ereport(ERROR,
2998  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
2999  errmsg("zero raised to a negative power is undefined")));
3000 
3001  if (cmp_var(&arg1, &const_zero) < 0 &&
3002  cmp_var(&arg2, &arg2_trunc) != 0)
3003  ereport(ERROR,
3004  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
3005  errmsg("a negative number raised to a non-integer power yields a complex result")));
3006 
3007  /*
3008  * Call power_var() to compute and return the result; note it handles
3009  * scale selection itself.
3010  */
3011  power_var(&arg1, &arg2, &result);
3012 
3013  res = make_result(&result);
3014 
3015  free_var(&result);
3016  free_var(&arg2_trunc);
3017 
3018  PG_RETURN_NUMERIC(res);
3019 }
3020 
3021 /*
3022  * numeric_scale() -
3023  *
3024  * Returns the scale, i.e. the count of decimal digits in the fractional part
3025  */
3026 Datum
3028 {
3029  Numeric num = PG_GETARG_NUMERIC(0);
3030 
3031  if (NUMERIC_IS_NAN(num))
3032  PG_RETURN_NULL();
3033 
3035 }
3036 
3037 
3038 
3039 /* ----------------------------------------------------------------------
3040  *
3041  * Type conversion functions
3042  *
3043  * ----------------------------------------------------------------------
3044  */
3045 
3046 
3047 Datum
3049 {
3050  int32 val = PG_GETARG_INT32(0);
3051  Numeric res;
3052  NumericVar result;
3053 
3054  init_var(&result);
3055 
3056  int64_to_numericvar((int64) val, &result);
3057 
3058  res = make_result(&result);
3059 
3060  free_var(&result);
3061 
3062  PG_RETURN_NUMERIC(res);
3063 }
3064 
3065 
3066 Datum
3068 {
3069  Numeric num = PG_GETARG_NUMERIC(0);
3070  NumericVar x;
3071  int32 result;
3072 
3073  /* XXX would it be better to return NULL? */
3074  if (NUMERIC_IS_NAN(num))
3075  ereport(ERROR,
3076  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3077  errmsg("cannot convert NaN to integer")));
3078 
3079  /* Convert to variable format, then convert to int4 */
3080  init_var_from_num(num, &x);
3081  result = numericvar_to_int32(&x);
3082  PG_RETURN_INT32(result);
3083 }
3084 
3085 /*
3086  * Given a NumericVar, convert it to an int32. If the NumericVar
3087  * exceeds the range of an int32, raise the appropriate error via
3088  * ereport(). The input NumericVar is *not* free'd.
3089  */
3090 static int32
3092 {
3093  int32 result;
3094  int64 val;
3095 
3096  if (!numericvar_to_int64(var, &val))
3097  ereport(ERROR,
3098  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
3099  errmsg("integer out of range")));
3100 
3101  /* Down-convert to int4 */
3102  result = (int32) val;
3103 
3104  /* Test for overflow by reverse-conversion. */
3105  if ((int64) result != val)
3106  ereport(ERROR,
3107  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
3108  errmsg("integer out of range")));
3109 
3110  return result;
3111 }
3112 
3113 Datum
3115 {
3116  int64 val = PG_GETARG_INT64(0);
3117  Numeric res;
3118  NumericVar result;
3119 
3120  init_var(&result);
3121 
3122  int64_to_numericvar(val, &result);
3123 
3124  res = make_result(&result);
3125 
3126  free_var(&result);
3127 
3128  PG_RETURN_NUMERIC(res);
3129 }
3130 
3131 
3132 Datum
3134 {
3135  Numeric num = PG_GETARG_NUMERIC(0);
3136  NumericVar x;
3137  int64 result;
3138 
3139  /* XXX would it be better to return NULL? */
3140  if (NUMERIC_IS_NAN(num))
3141  ereport(ERROR,
3142  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3143  errmsg("cannot convert NaN to bigint")));
3144 
3145  /* Convert to variable format and thence to int8 */
3146  init_var_from_num(num, &x);
3147 
3148  if (!numericvar_to_int64(&x, &result))
3149  ereport(ERROR,
3150  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
3151  errmsg("bigint out of range")));
3152 
3153  PG_RETURN_INT64(result);
3154 }
3155 
3156 
3157 Datum
3159 {
3160  int16 val = PG_GETARG_INT16(0);
3161  Numeric res;
3162  NumericVar result;
3163 
3164  init_var(&result);
3165 
3166  int64_to_numericvar((int64) val, &result);
3167 
3168  res = make_result(&result);
3169 
3170  free_var(&result);
3171 
3172  PG_RETURN_NUMERIC(res);
3173 }
3174 
3175 
3176 Datum
3178 {
3179  Numeric num = PG_GETARG_NUMERIC(0);
3180  NumericVar x;
3181  int64 val;
3182  int16 result;
3183 
3184  /* XXX would it be better to return NULL? */
3185  if (NUMERIC_IS_NAN(num))
3186  ereport(ERROR,
3187  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3188  errmsg("cannot convert NaN to smallint")));
3189 
3190  /* Convert to variable format and thence to int8 */
3191  init_var_from_num(num, &x);
3192 
3193  if (!numericvar_to_int64(&x, &val))
3194  ereport(ERROR,
3195  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
3196  errmsg("smallint out of range")));
3197 
3198  /* Down-convert to int2 */
3199  result = (int16) val;
3200 
3201  /* Test for overflow by reverse-conversion. */
3202  if ((int64) result != val)
3203  ereport(ERROR,
3204  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
3205  errmsg("smallint out of range")));
3206 
3207  PG_RETURN_INT16(result);
3208 }
3209 
3210 
3211 Datum
3213 {
3215  Numeric res;
3216  NumericVar result;
3217  char buf[DBL_DIG + 100];
3218 
3219  if (isnan(val))
3220  PG_RETURN_NUMERIC(make_result(&const_nan));
3221 
3222  if (isinf(val))
3223  ereport(ERROR,
3224  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3225  errmsg("cannot convert infinity to numeric")));
3226 
3227  snprintf(buf, sizeof(buf), "%.*g", DBL_DIG, val);
3228 
3229  init_var(&result);
3230 
3231  /* Assume we need not worry about leading/trailing spaces */
3232  (void) set_var_from_str(buf, buf, &result);
3233 
3234  res = make_result(&result);
3235 
3236  free_var(&result);
3237 
3238  PG_RETURN_NUMERIC(res);
3239 }
3240 
3241 
3242 Datum
3244 {
3245  Numeric num = PG_GETARG_NUMERIC(0);
3246  char *tmp;
3247  Datum result;
3248 
3249  if (NUMERIC_IS_NAN(num))
3251 
3253  NumericGetDatum(num)));
3254 
3256 
3257  pfree(tmp);
3258 
3259  PG_RETURN_DATUM(result);
3260 }
3261 
3262 
3263 /*
3264  * Convert numeric to float8; if out of range, return +/- HUGE_VAL
3265  *
3266  * (internal helper function, not directly callable from SQL)
3267  */
3268 Datum
3270 {
3271  Numeric num = PG_GETARG_NUMERIC(0);
3272  double val;
3273 
3274  if (NUMERIC_IS_NAN(num))
3276 
3277  val = numeric_to_double_no_overflow(num);
3278 
3279  PG_RETURN_FLOAT8(val);
3280 }
3281 
3282 Datum
3284 {
3286  Numeric res;
3287  NumericVar result;
3288  char buf[FLT_DIG + 100];
3289 
3290  if (isnan(val))
3291  PG_RETURN_NUMERIC(make_result(&const_nan));
3292 
3293  if (isinf(val))
3294  ereport(ERROR,
3295  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3296  errmsg("cannot convert infinity to numeric")));
3297 
3298  snprintf(buf, sizeof(buf), "%.*g", FLT_DIG, val);
3299 
3300  init_var(&result);
3301 
3302  /* Assume we need not worry about leading/trailing spaces */
3303  (void) set_var_from_str(buf, buf, &result);
3304 
3305  res = make_result(&result);
3306 
3307  free_var(&result);
3308 
3309  PG_RETURN_NUMERIC(res);
3310 }
3311 
3312 
3313 Datum
3315 {
3316  Numeric num = PG_GETARG_NUMERIC(0);
3317  char *tmp;
3318  Datum result;
3319 
3320  if (NUMERIC_IS_NAN(num))
3322 
3324  NumericGetDatum(num)));
3325 
3327 
3328  pfree(tmp);
3329 
3330  PG_RETURN_DATUM(result);
3331 }
3332 
3333 
3334 /* ----------------------------------------------------------------------
3335  *
3336  * Aggregate functions
3337  *
3338  * The transition datatype for all these aggregates is declared as INTERNAL.
3339  * Actually, it's a pointer to a NumericAggState allocated in the aggregate
3340  * context. The digit buffers for the NumericVars will be there too.
3341  *
3342  * On platforms which support 128-bit integers some aggregates instead use a
3343  * 128-bit integer based transition datatype to speed up calculations.
3344  *
3345  * ----------------------------------------------------------------------
3346  */
3347 
3348 typedef struct NumericAggState
3349 {
3350  bool calcSumX2; /* if true, calculate sumX2 */
3351  MemoryContext agg_context; /* context we're calculating in */
3352  int64 N; /* count of processed numbers */
3353  NumericSumAccum sumX; /* sum of processed numbers */
3354  NumericSumAccum sumX2; /* sum of squares of processed numbers */
3355  int maxScale; /* maximum scale seen so far */
3356  int64 maxScaleCount; /* number of values seen with maximum scale */
3357  int64 NaNcount; /* count of NaN values (not included in N!) */
3358 } NumericAggState;
3359 
3360 /*
3361  * Prepare state data for a numeric aggregate function that needs to compute
3362  * sum, count and optionally sum of squares of the input.
3363  */
3364 static NumericAggState *
3365 makeNumericAggState(FunctionCallInfo fcinfo, bool calcSumX2)
3366 {
3368  MemoryContext agg_context;
3369  MemoryContext old_context;
3370 
3371  if (!AggCheckCallContext(fcinfo, &agg_context))
3372  elog(ERROR, "aggregate function called in non-aggregate context");
3373 
3374  old_context = MemoryContextSwitchTo(agg_context);
3375 
3376  state = (NumericAggState *) palloc0(sizeof(NumericAggState));
3377  state->calcSumX2 = calcSumX2;
3378  state->agg_context = agg_context;
3379 
3380  MemoryContextSwitchTo(old_context);
3381 
3382  return state;
3383 }
3384 
3385 /*
3386  * Like makeNumericAggState(), but allocate the state in the current memory
3387  * context.
3388  */
3389 static NumericAggState *
3391 {
3393 
3394  state = (NumericAggState *) palloc0(sizeof(NumericAggState));
3395  state->calcSumX2 = calcSumX2;
3397 
3398  return state;
3399 }
3400 
3401 /*
3402  * Accumulate a new input value for numeric aggregate functions.
3403  */
3404 static void
3406 {
3407  NumericVar X;
3408  NumericVar X2;
3409  MemoryContext old_context;
3410 
3411  /* Count NaN inputs separately from all else */
3412  if (NUMERIC_IS_NAN(newval))
3413  {
3414  state->NaNcount++;
3415  return;
3416  }
3417 
3418  /* load processed number in short-lived context */
3419  init_var_from_num(newval, &X);
3420 
3421  /*
3422  * Track the highest input dscale that we've seen, to support inverse
3423  * transitions (see do_numeric_discard).
3424  */
3425  if (X.dscale > state->maxScale)
3426  {
3427  state->maxScale = X.dscale;
3428  state->maxScaleCount = 1;
3429  }
3430  else if (X.dscale == state->maxScale)
3431  state->maxScaleCount++;
3432 
3433  /* if we need X^2, calculate that in short-lived context */
3434  if (state->calcSumX2)
3435  {
3436  init_var(&X2);
3437  mul_var(&X, &X, &X2, X.dscale * 2);
3438  }
3439 
3440  /* The rest of this needs to work in the aggregate context */
3441  old_context = MemoryContextSwitchTo(state->agg_context);
3442 
3443  state->N++;
3444 
3445  /* Accumulate sums */
3446  accum_sum_add(&(state->sumX), &X);
3447 
3448  if (state->calcSumX2)
3449  accum_sum_add(&(state->sumX2), &X2);
3450 
3451  MemoryContextSwitchTo(old_context);
3452 }
3453 
3454 /*
3455  * Attempt to remove an input value from the aggregated state.
3456  *
3457  * If the value cannot be removed then the function will return false; the
3458  * possible reasons for failing are described below.
3459  *
3460  * If we aggregate the values 1.01 and 2 then the result will be 3.01.
3461  * If we are then asked to un-aggregate the 1.01 then we must fail as we
3462  * won't be able to tell what the new aggregated value's dscale should be.
3463  * We don't want to return 2.00 (dscale = 2), since the sum's dscale would
3464  * have been zero if we'd really aggregated only 2.
3465  *
3466  * Note: alternatively, we could count the number of inputs with each possible
3467  * dscale (up to some sane limit). Not yet clear if it's worth the trouble.
3468  */
3469 static bool
3471 {
3472  NumericVar X;
3473  NumericVar X2;
3474  MemoryContext old_context;
3475 
3476  /* Count NaN inputs separately from all else */
3477  if (NUMERIC_IS_NAN(newval))
3478  {
3479  state->NaNcount--;
3480  return true;
3481  }
3482 
3483  /* load processed number in short-lived context */
3484  init_var_from_num(newval, &X);
3485 
3486  /*
3487  * state->sumX's dscale is the maximum dscale of any of the inputs.
3488  * Removing the last input with that dscale would require us to recompute
3489  * the maximum dscale of the *remaining* inputs, which we cannot do unless
3490  * no more non-NaN inputs remain at all. So we report a failure instead,
3491  * and force the aggregation to be redone from scratch.
3492  */
3493  if (X.dscale == state->maxScale)
3494  {
3495  if (state->maxScaleCount > 1 || state->maxScale == 0)
3496  {
3497  /*
3498  * Some remaining inputs have same dscale, or dscale hasn't gotten
3499  * above zero anyway
3500  */
3501  state->maxScaleCount--;
3502  }
3503  else if (state->N == 1)
3504  {
3505  /* No remaining non-NaN inputs at all, so reset maxScale */
3506  state->maxScale = 0;
3507  state->maxScaleCount = 0;
3508  }
3509  else
3510  {
3511  /* Correct new maxScale is uncertain, must fail */
3512  return false;
3513  }
3514  }
3515 
3516  /* if we need X^2, calculate that in short-lived context */
3517  if (state->calcSumX2)
3518  {
3519  init_var(&X2);
3520  mul_var(&X, &X, &X2, X.dscale * 2);
3521  }
3522 
3523  /* The rest of this needs to work in the aggregate context */
3524  old_context = MemoryContextSwitchTo(state->agg_context);
3525 
3526  if (state->N-- > 1)
3527  {
3528  /* Negate X, to subtract it from the sum */
3529  X.sign = (X.sign == NUMERIC_POS ? NUMERIC_NEG : NUMERIC_POS);
3530  accum_sum_add(&(state->sumX), &X);
3531 
3532  if (state->calcSumX2)
3533  {
3534  /* Negate X^2. X^2 is always positive */
3535  X2.sign = NUMERIC_NEG;
3536  accum_sum_add(&(state->sumX2), &X2);
3537  }
3538  }
3539  else
3540  {
3541  /* Zero the sums */
3542  Assert(state->N == 0);
3543 
3544  accum_sum_reset(&state->sumX);
3545  if (state->calcSumX2)
3546  accum_sum_reset(&state->sumX2);
3547  }
3548 
3549  MemoryContextSwitchTo(old_context);
3550 
3551  return true;
3552 }
3553 
3554 /*
3555  * Generic transition function for numeric aggregates that require sumX2.
3556  */
3557 Datum
3559 {
3561 
3562  state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
3563 
3564  /* Create the state data on the first call */
3565  if (state == NULL)
3566  state = makeNumericAggState(fcinfo, true);
3567 
3568  if (!PG_ARGISNULL(1))
3570 
3571  PG_RETURN_POINTER(state);
3572 }
3573 
3574 /*
3575  * Generic combine function for numeric aggregates which require sumX2
3576  */
3577 Datum
3579 {
3580  NumericAggState *state1;
3581  NumericAggState *state2;
3582  MemoryContext agg_context;
3583  MemoryContext old_context;
3584 
3585  if (!AggCheckCallContext(fcinfo, &agg_context))
3586  elog(ERROR, "aggregate function called in non-aggregate context");
3587 
3588  state1 = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
3589  state2 = PG_ARGISNULL(1) ? NULL : (NumericAggState *) PG_GETARG_POINTER(1);
3590 
3591  if (state2 == NULL)
3592  PG_RETURN_POINTER(state1);
3593 
3594  /* manually copy all fields from state2 to state1 */
3595  if (state1 == NULL)
3596  {
3597  old_context = MemoryContextSwitchTo(agg_context);
3598 
3599  state1 = makeNumericAggStateCurrentContext(true);
3600  state1->N = state2->N;
3601  state1->NaNcount = state2->NaNcount;
3602  state1->maxScale = state2->maxScale;
3603  state1->maxScaleCount = state2->maxScaleCount;
3604 
3605  accum_sum_copy(&state1->sumX, &state2->sumX);
3606  accum_sum_copy(&state1->sumX2, &state2->sumX2);
3607 
3608  MemoryContextSwitchTo(old_context);
3609 
3610  PG_RETURN_POINTER(state1);
3611  }
3612 
3613  if (state2->N > 0)
3614  {
3615  state1->N += state2->N;
3616  state1->NaNcount += state2->NaNcount;
3617 
3618  /*
3619  * These are currently only needed for moving aggregates, but let's do
3620  * the right thing anyway...
3621  */
3622  if (state2->maxScale > state1->maxScale)
3623  {
3624  state1->maxScale = state2->maxScale;
3625  state1->maxScaleCount = state2->maxScaleCount;
3626  }
3627  else if (state2->maxScale == state1->maxScale)
3628  state1->maxScaleCount += state2->maxScaleCount;
3629 
3630  /* The rest of this needs to work in the aggregate context */
3631  old_context = MemoryContextSwitchTo(agg_context);
3632 
3633  /* Accumulate sums */
3634  accum_sum_combine(&state1->sumX, &state2->sumX);
3635  accum_sum_combine(&state1->sumX2, &state2->sumX2);
3636 
3637  MemoryContextSwitchTo(old_context);
3638  }
3639  PG_RETURN_POINTER(state1);
3640 }
3641 
3642 /*
3643  * Generic transition function for numeric aggregates that don't require sumX2.
3644  */
3645 Datum
3647 {
3649 
3650  state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
3651 
3652  /* Create the state data on the first call */
3653  if (state == NULL)
3654  state = makeNumericAggState(fcinfo, false);
3655 
3656  if (!PG_ARGISNULL(1))
3658 
3659  PG_RETURN_POINTER(state);
3660 }
3661 
3662 /*
3663  * Combine function for numeric aggregates which don't require sumX2
3664  */
3665 Datum
3667 {
3668  NumericAggState *state1;
3669  NumericAggState *state2;
3670  MemoryContext agg_context;
3671  MemoryContext old_context;
3672 
3673  if (!AggCheckCallContext(fcinfo, &agg_context))
3674  elog(ERROR, "aggregate function called in non-aggregate context");
3675 
3676  state1 = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
3677  state2 = PG_ARGISNULL(1) ? NULL : (NumericAggState *) PG_GETARG_POINTER(1);
3678 
3679  if (state2 == NULL)
3680  PG_RETURN_POINTER(state1);
3681 
3682  /* manually copy all fields from state2 to state1 */
3683  if (state1 == NULL)
3684  {
3685  old_context = MemoryContextSwitchTo(agg_context);
3686 
3687  state1 = makeNumericAggStateCurrentContext(false);
3688  state1->N = state2->N;
3689  state1->NaNcount = state2->NaNcount;
3690  state1->maxScale = state2->maxScale;
3691  state1->maxScaleCount = state2->maxScaleCount;
3692 
3693  accum_sum_copy(&state1->sumX, &state2->sumX);
3694 
3695  MemoryContextSwitchTo(old_context);
3696 
3697  PG_RETURN_POINTER(state1);
3698  }
3699 
3700  if (state2->N > 0)
3701  {
3702  state1->N += state2->N;
3703  state1->NaNcount += state2->NaNcount;
3704 
3705  /*
3706  * These are currently only needed for moving aggregates, but let's do
3707  * the right thing anyway...
3708  */
3709  if (state2->maxScale > state1->maxScale)
3710  {
3711  state1->maxScale = state2->maxScale;
3712  state1->maxScaleCount = state2->maxScaleCount;
3713  }
3714  else if (state2->maxScale == state1->maxScale)
3715  state1->maxScaleCount += state2->maxScaleCount;
3716 
3717  /* The rest of this needs to work in the aggregate context */
3718  old_context = MemoryContextSwitchTo(agg_context);
3719 
3720  /* Accumulate sums */
3721  accum_sum_combine(&state1->sumX, &state2->sumX);
3722 
3723  MemoryContextSwitchTo(old_context);
3724  }
3725  PG_RETURN_POINTER(state1);
3726 }
3727 
3728 /*
3729  * numeric_avg_serialize
3730  * Serialize NumericAggState for numeric aggregates that don't require
3731  * sumX2.
3732  */
3733 Datum
3735 {
3738  Datum temp;
3739  bytea *sumX;
3740  bytea *result;
3741  NumericVar tmp_var;
3742 
3743  /* Ensure we disallow calling when not in aggregate context */
3744  if (!AggCheckCallContext(fcinfo, NULL))
3745  elog(ERROR, "aggregate function called in non-aggregate context");
3746 
3747  state = (NumericAggState *) PG_GETARG_POINTER(0);
3748 
3749  /*
3750  * This is a little wasteful since make_result converts the NumericVar
3751  * into a Numeric and numeric_send converts it back again. Is it worth
3752  * splitting the tasks in numeric_send into separate functions to stop
3753  * this? Doing so would also remove the fmgr call overhead.
3754  */
3755  init_var(&tmp_var);
3756  accum_sum_final(&state->sumX, &tmp_var);
3757 
3759  NumericGetDatum(make_result(&tmp_var)));
3760  sumX = DatumGetByteaPP(temp);
3761  free_var(&tmp_var);
3762 
3763  pq_begintypsend(&buf);
3764 
3765  /* N */
3766  pq_sendint64(&buf, state->N);
3767 
3768  /* sumX */
3769  pq_sendbytes(&buf, VARDATA_ANY(sumX), VARSIZE_ANY_EXHDR(sumX));
3770 
3771  /* maxScale */
3772  pq_sendint32(&buf, state->maxScale);
3773 
3774  /* maxScaleCount */
3775  pq_sendint64(&buf, state->maxScaleCount);
3776 
3777  /* NaNcount */
3778  pq_sendint64(&buf, state->NaNcount);
3779 
3780  result = pq_endtypsend(&buf);
3781 
3782  PG_RETURN_BYTEA_P(result);
3783 }
3784 
3785 /*
3786  * numeric_avg_deserialize
3787  * Deserialize bytea into NumericAggState for numeric aggregates that
3788  * don't require sumX2.
3789  */
3790 Datum
3792 {
3793  bytea *sstate;
3794  NumericAggState *result;
3795  Datum temp;
3796  NumericVar tmp_var;
3798 
3799  if (!AggCheckCallContext(fcinfo, NULL))
3800  elog(ERROR, "aggregate function called in non-aggregate context");
3801 
3802  sstate = PG_GETARG_BYTEA_PP(0);
3803 
3804  /*
3805  * Copy the bytea into a StringInfo so that we can "receive" it using the
3806  * standard recv-function infrastructure.
3807  */
3808  initStringInfo(&buf);
3810  VARDATA_ANY(sstate), VARSIZE_ANY_EXHDR(sstate));
3811 
3812  result = makeNumericAggStateCurrentContext(false);
3813 
3814  /* N */
3815  result->N = pq_getmsgint64(&buf);
3816 
3817  /* sumX */
3819  PointerGetDatum(&buf),
3820  InvalidOid,
3821  -1);
3822  init_var_from_num(DatumGetNumeric(temp), &tmp_var);
3823  accum_sum_add(&(result->sumX), &tmp_var);
3824 
3825  /* maxScale */
3826  result->maxScale = pq_getmsgint(&buf, 4);
3827 
3828  /* maxScaleCount */
3829  result->maxScaleCount = pq_getmsgint64(&buf);
3830 
3831  /* NaNcount */
3832  result->NaNcount = pq_getmsgint64(&buf);
3833 
3834  pq_getmsgend(&buf);
3835  pfree(buf.data);
3836 
3837  PG_RETURN_POINTER(result);
3838 }
3839 
3840 /*
3841  * numeric_serialize
3842  * Serialization function for NumericAggState for numeric aggregates that
3843  * require sumX2.
3844  */
3845 Datum
3847 {
3850  Datum temp;
3851  bytea *sumX;
3852  NumericVar tmp_var;
3853  bytea *sumX2;
3854  bytea *result;
3855 
3856  /* Ensure we disallow calling when not in aggregate context */
3857  if (!AggCheckCallContext(fcinfo, NULL))
3858  elog(ERROR, "aggregate function called in non-aggregate context");
3859 
3860  state = (NumericAggState *) PG_GETARG_POINTER(0);
3861 
3862  /*
3863  * This is a little wasteful since make_result converts the NumericVar
3864  * into a Numeric and numeric_send converts it back again. Is it worth
3865  * splitting the tasks in numeric_send into separate functions to stop
3866  * this? Doing so would also remove the fmgr call overhead.
3867  */
3868  init_var(&tmp_var);
3869 
3870  accum_sum_final(&state->sumX, &tmp_var);
3872  NumericGetDatum(make_result(&tmp_var)));
3873  sumX = DatumGetByteaPP(temp);
3874 
3875  accum_sum_final(&state->sumX2, &tmp_var);
3877  NumericGetDatum(make_result(&tmp_var)));
3878  sumX2 = DatumGetByteaPP(temp);
3879 
3880  free_var(&tmp_var);
3881 
3882  pq_begintypsend(&buf);
3883 
3884  /* N */
3885  pq_sendint64(&buf, state->N);
3886 
3887  /* sumX */
3888  pq_sendbytes(&buf, VARDATA_ANY(sumX), VARSIZE_ANY_EXHDR(sumX));
3889 
3890  /* sumX2 */
3891  pq_sendbytes(&buf, VARDATA_ANY(sumX2), VARSIZE_ANY_EXHDR(sumX2));
3892 
3893  /* maxScale */
3894  pq_sendint32(&buf, state->maxScale);
3895 
3896  /* maxScaleCount */
3897  pq_sendint64(&buf, state->maxScaleCount);
3898 
3899  /* NaNcount */
3900  pq_sendint64(&buf, state->NaNcount);
3901 
3902  result = pq_endtypsend(&buf);
3903 
3904  PG_RETURN_BYTEA_P(result);
3905 }
3906 
3907 /*
3908  * numeric_deserialize
3909  * Deserialization function for NumericAggState for numeric aggregates that
3910  * require sumX2.
3911  */
3912 Datum
3914 {
3915  bytea *sstate;
3916  NumericAggState *result;
3917  Datum temp;
3918  NumericVar sumX_var;
3919  NumericVar sumX2_var;
3921 
3922  if (!AggCheckCallContext(fcinfo, NULL))
3923  elog(ERROR, "aggregate function called in non-aggregate context");
3924 
3925  sstate = PG_GETARG_BYTEA_PP(0);
3926 
3927  /*
3928  * Copy the bytea into a StringInfo so that we can "receive" it using the
3929  * standard recv-function infrastructure.
3930  */
3931  initStringInfo(&buf);
3933  VARDATA_ANY(sstate), VARSIZE_ANY_EXHDR(sstate));
3934 
3935  result = makeNumericAggStateCurrentContext(false);
3936 
3937  /* N */
3938  result->N = pq_getmsgint64(&buf);
3939 
3940  /* sumX */
3942  PointerGetDatum(&buf),
3943  InvalidOid,
3944  -1);
3945  init_var_from_num(DatumGetNumeric(temp), &sumX_var);
3946  accum_sum_add(&(result->sumX), &sumX_var);
3947 
3948  /* sumX2 */
3950  PointerGetDatum(&buf),
3951  InvalidOid,
3952  -1);
3953  init_var_from_num(DatumGetNumeric(temp), &sumX2_var);
3954  accum_sum_add(&(result->sumX2), &sumX2_var);
3955 
3956  /* maxScale */
3957  result->maxScale = pq_getmsgint(&buf, 4);
3958 
3959  /* maxScaleCount */
3960  result->maxScaleCount = pq_getmsgint64(&buf);
3961 
3962  /* NaNcount */
3963  result->NaNcount = pq_getmsgint64(&buf);
3964 
3965  pq_getmsgend(&buf);
3966  pfree(buf.data);
3967 
3968  PG_RETURN_POINTER(result);
3969 }
3970 
3971 /*
3972  * Generic inverse transition function for numeric aggregates
3973  * (with or without requirement for X^2).
3974  */
3975 Datum
3977 {
3979 
3980  state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
3981 
3982  /* Should not get here with no state */
3983  if (state == NULL)
3984  elog(ERROR, "numeric_accum_inv called with NULL state");
3985 
3986  if (!PG_ARGISNULL(1))
3987  {
3988  /* If we fail to perform the inverse transition, return NULL */
3989  if (!do_numeric_discard(state, PG_GETARG_NUMERIC(1)))
3990  PG_RETURN_NULL();
3991  }
3992 
3993  PG_RETURN_POINTER(state);
3994 }
3995 
3996 
3997 /*
3998  * Integer data types in general use Numeric accumulators to share code
3999  * and avoid risk of overflow.
4000  *
4001  * However for performance reasons optimized special-purpose accumulator
4002  * routines are used when possible.
4003  *
4004  * On platforms with 128-bit integer support, the 128-bit routines will be
4005  * used when sum(X) or sum(X*X) fit into 128-bit.
4006  *
4007  * For 16 and 32 bit inputs, the N and sum(X) fit into 64-bit so the 64-bit
4008  * accumulators will be used for SUM and AVG of these data types.
4009  */
4010 
4011 #ifdef HAVE_INT128
4012 typedef struct Int128AggState
4013 {
4014  bool calcSumX2; /* if true, calculate sumX2 */
4015  int64 N; /* count of processed numbers */
4016  int128 sumX; /* sum of processed numbers */
4017  int128 sumX2; /* sum of squares of processed numbers */
4018 } Int128AggState;
4019 
4020 /*
4021  * Prepare state data for a 128-bit aggregate function that needs to compute
4022  * sum, count and optionally sum of squares of the input.
4023  */
4024 static Int128AggState *
4025 makeInt128AggState(FunctionCallInfo fcinfo, bool calcSumX2)
4026 {
4027  Int128AggState *state;
4028  MemoryContext agg_context;
4029  MemoryContext old_context;
4030 
4031  if (!AggCheckCallContext(fcinfo, &agg_context))
4032  elog(ERROR, "aggregate function called in non-aggregate context");
4033 
4034  old_context = MemoryContextSwitchTo(agg_context);
4035 
4036  state = (Int128AggState *) palloc0(sizeof(Int128AggState));
4037  state->calcSumX2 = calcSumX2;
4038 
4039  MemoryContextSwitchTo(old_context);
4040 
4041  return state;
4042 }
4043 
4044 /*
4045  * Like makeInt128AggState(), but allocate the state in the current memory
4046  * context.
4047  */
4048 static Int128AggState *
4049 makeInt128AggStateCurrentContext(bool calcSumX2)
4050 {
4051  Int128AggState *state;
4052 
4053  state = (Int128AggState *) palloc0(sizeof(Int128AggState));
4054  state->calcSumX2 = calcSumX2;
4055 
4056  return state;
4057 }
4058 
4059 /*
4060  * Accumulate a new input value for 128-bit aggregate functions.
4061  */
4062 static void
4063 do_int128_accum(Int128AggState *state, int128 newval)
4064 {
4065  if (state->calcSumX2)
4066  state->sumX2 += newval * newval;
4067 
4068  state->sumX += newval;
4069  state->N++;
4070 }
4071 
4072 /*
4073  * Remove an input value from the aggregated state.
4074  */
4075 static void
4076 do_int128_discard(Int128AggState *state, int128 newval)
4077 {
4078  if (state->calcSumX2)
4079  state->sumX2 -= newval * newval;
4080 
4081  state->sumX -= newval;
4082  state->N--;
4083 }
4084 
4085 typedef Int128AggState PolyNumAggState;
4086 #define makePolyNumAggState makeInt128AggState
4087 #define makePolyNumAggStateCurrentContext makeInt128AggStateCurrentContext
4088 #else
4090 #define makePolyNumAggState makeNumericAggState
4091 #define makePolyNumAggStateCurrentContext makeNumericAggStateCurrentContext
4092 #endif
4093 
4094 Datum
4096 {
4097  PolyNumAggState *state;
4098 
4099  state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
4100 
4101  /* Create the state data on the first call */
4102  if (state == NULL)
4103  state = makePolyNumAggState(fcinfo, true);
4104 
4105  if (!PG_ARGISNULL(1))
4106  {
4107 #ifdef HAVE_INT128
4108  do_int128_accum(state, (int128) PG_GETARG_INT16(1));
4109 #else
4110  Numeric newval;
4111 
4113  PG_GETARG_DATUM(1)));
4114  do_numeric_accum(state, newval);
4115 #endif
4116  }
4117 
4118  PG_RETURN_POINTER(state);
4119 }
4120 
4121 Datum
4123 {
4124  PolyNumAggState *state;
4125 
4126  state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
4127 
4128  /* Create the state data on the first call */
4129  if (state == NULL)
4130  state = makePolyNumAggState(fcinfo, true);
4131 
4132  if (!PG_ARGISNULL(1))
4133  {
4134 #ifdef HAVE_INT128
4135  do_int128_accum(state, (int128) PG_GETARG_INT32(1));
4136 #else
4137  Numeric newval;
4138 
4140  PG_GETARG_DATUM(1)));
4141  do_numeric_accum(state, newval);
4142 #endif
4143  }
4144 
4145  PG_RETURN_POINTER(state);
4146 }
4147 
4148 Datum
4150 {
4151  NumericAggState *state;
4152 
4153  state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
4154 
4155  /* Create the state data on the first call */
4156  if (state == NULL)
4157  state = makeNumericAggState(fcinfo, true);
4158 
4159  if (!PG_ARGISNULL(1))
4160  {
4161  Numeric newval;
4162 
4164  PG_GETARG_DATUM(1)));
4165  do_numeric_accum(state, newval);
4166  }
4167 
4168  PG_RETURN_POINTER(state);
4169 }
4170 
4171 /*
4172  * Combine function for numeric aggregates which require sumX2
4173  */
4174 Datum
4176 {
4177  PolyNumAggState *state1;
4178  PolyNumAggState *state2;
4179  MemoryContext agg_context;
4180  MemoryContext old_context;
4181 
4182  if (!AggCheckCallContext(fcinfo, &agg_context))
4183  elog(ERROR, "aggregate function called in non-aggregate context");
4184 
4185  state1 = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
4186  state2 = PG_ARGISNULL(1) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(1);
4187 
4188  if (state2 == NULL)
4189  PG_RETURN_POINTER(state1);
4190 
4191  /* manually copy all fields from state2 to state1 */
4192  if (state1 == NULL)
4193  {
4194  old_context = MemoryContextSwitchTo(agg_context);
4195 
4196  state1 = makePolyNumAggState(fcinfo, true);
4197  state1->N = state2->N;
4198 
4199 #ifdef HAVE_INT128
4200  state1->sumX = state2->sumX;
4201  state1->sumX2 = state2->sumX2;
4202 #else
4203  accum_sum_copy(&state2->sumX, &state1->sumX);
4204  accum_sum_copy(&state2->sumX2, &state1->sumX2);
4205 #endif
4206 
4207  MemoryContextSwitchTo(old_context);
4208 
4209  PG_RETURN_POINTER(state1);
4210  }
4211 
4212  if (state2->N > 0)
4213  {
4214  state1->N += state2->N;
4215 
4216 #ifdef HAVE_INT128
4217  state1->sumX += state2->sumX;
4218  state1->sumX2 += state2->sumX2;
4219 #else
4220  /* The rest of this needs to work in the aggregate context */
4221  old_context = MemoryContextSwitchTo(agg_context);
4222 
4223  /* Accumulate sums */
4224  accum_sum_combine(&state1->sumX, &state2->sumX);
4225  accum_sum_combine(&state1->sumX2, &state2->sumX2);
4226 
4227  MemoryContextSwitchTo(old_context);
4228 #endif
4229 
4230  }
4231  PG_RETURN_POINTER(state1);
4232 }
4233 
4234 /*
4235  * numeric_poly_serialize
4236  * Serialize PolyNumAggState into bytea for aggregate functions which
4237  * require sumX2.
4238  */
4239 Datum
4241 {
4242  PolyNumAggState *state;
4244  bytea *sumX;
4245  bytea *sumX2;
4246  bytea *result;
4247 
4248  /* Ensure we disallow calling when not in aggregate context */
4249  if (!AggCheckCallContext(fcinfo, NULL))
4250  elog(ERROR, "aggregate function called in non-aggregate context");
4251 
4252  state = (PolyNumAggState *) PG_GETARG_POINTER(0);
4253 
4254  /*
4255  * If the platform supports int128 then sumX and sumX2 will be a 128 bit
4256  * integer type. Here we'll convert that into a numeric type so that the
4257  * combine state is in the same format for both int128 enabled machines
4258  * and machines which don't support that type. The logic here is that one
4259  * day we might like to send these over to another server for further
4260  * processing and we want a standard format to work with.
4261  */
4262  {
4263  Datum temp;
4264  NumericVar num;
4265 
4266  init_var(&num);
4267 
4268 #ifdef HAVE_INT128
4269  int128_to_numericvar(state->sumX, &num);
4270 #else
4271  accum_sum_final(&state->sumX, &num);
4272 #endif
4274  NumericGetDatum(make_result(&num)));
4275  sumX = DatumGetByteaPP(temp);
4276 
4277 #ifdef HAVE_INT128
4278  int128_to_numericvar(state->sumX2, &num);
4279 #else
4280  accum_sum_final(&state->sumX2, &num);
4281 #endif
4283  NumericGetDatum(make_result(&num)));
4284  sumX2 = DatumGetByteaPP(temp);
4285 
4286  free_var(&num);
4287  }
4288 
4289  pq_begintypsend(&buf);
4290 
4291  /* N */
4292  pq_sendint64(&buf, state->N);
4293 
4294  /* sumX */
4295  pq_sendbytes(&buf, VARDATA_ANY(sumX), VARSIZE_ANY_EXHDR(sumX));
4296 
4297  /* sumX2 */
4298  pq_sendbytes(&buf, VARDATA_ANY(sumX2), VARSIZE_ANY_EXHDR(sumX2));
4299 
4300  result = pq_endtypsend(&buf);
4301 
4302  PG_RETURN_BYTEA_P(result);
4303 }
4304 
4305 /*
4306  * numeric_poly_deserialize
4307  * Deserialize PolyNumAggState from bytea for aggregate functions which
4308  * require sumX2.
4309  */
4310 Datum
4312 {
4313  bytea *sstate;
4314  PolyNumAggState *result;
4315  Datum sumX;
4316  NumericVar sumX_var;
4317  Datum sumX2;
4318  NumericVar sumX2_var;
4320 
4321  if (!AggCheckCallContext(fcinfo, NULL))
4322  elog(ERROR, "aggregate function called in non-aggregate context");
4323 
4324  sstate = PG_GETARG_BYTEA_PP(0);
4325 
4326  /*
4327  * Copy the bytea into a StringInfo so that we can "receive" it using the
4328  * standard recv-function infrastructure.
4329  */
4330  initStringInfo(&buf);
4332  VARDATA_ANY(sstate), VARSIZE_ANY_EXHDR(sstate));
4333 
4334  result = makePolyNumAggStateCurrentContext(false);
4335 
4336  /* N */
4337  result->N = pq_getmsgint64(&buf);
4338 
4339  /* sumX */
4341  PointerGetDatum(&buf),
4342  InvalidOid,
4343  -1);
4344 
4345  /* sumX2 */
4347  PointerGetDatum(&buf),
4348  InvalidOid,
4349  -1);
4350 
4351  init_var_from_num(DatumGetNumeric(sumX), &sumX_var);
4352 #ifdef HAVE_INT128
4353  numericvar_to_int128(&sumX_var, &result->sumX);
4354 #else
4355  accum_sum_add(&result->sumX, &sumX_var);
4356 #endif
4357 
4358  init_var_from_num(DatumGetNumeric(sumX2), &sumX2_var);
4359 #ifdef HAVE_INT128
4360  numericvar_to_int128(&sumX2_var, &result->sumX2);
4361 #else
4362  accum_sum_add(&result->sumX2, &sumX2_var);
4363 #endif
4364 
4365  pq_getmsgend(&buf);
4366  pfree(buf.data);
4367 
4368  PG_RETURN_POINTER(result);
4369 }
4370 
4371 /*
4372  * Transition function for int8 input when we don't need sumX2.
4373  */
4374 Datum
4376 {
4377  PolyNumAggState *state;
4378 
4379  state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
4380 
4381  /* Create the state data on the first call */
4382  if (state == NULL)
4383  state = makePolyNumAggState(fcinfo, false);
4384 
4385  if (!PG_ARGISNULL(1))
4386  {
4387 #ifdef HAVE_INT128
4388  do_int128_accum(state, (int128) PG_GETARG_INT64(1));
4389 #else
4390  Numeric newval;
4391 
4393  PG_GETARG_DATUM(1)));
4394  do_numeric_accum(state, newval);
4395 #endif
4396  }
4397 
4398  PG_RETURN_POINTER(state);
4399 }
4400 
4401 /*
4402  * Combine function for PolyNumAggState for aggregates which don't require
4403  * sumX2
4404  */
4405 Datum
4407 {
4408  PolyNumAggState *state1;
4409  PolyNumAggState *state2;
4410  MemoryContext agg_context;
4411  MemoryContext old_context;
4412 
4413  if (!AggCheckCallContext(fcinfo, &agg_context))
4414  elog(ERROR, "aggregate function called in non-aggregate context");
4415 
4416  state1 = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
4417  state2 = PG_ARGISNULL(1) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(1);
4418 
4419  if (state2 == NULL)
4420  PG_RETURN_POINTER(state1);
4421 
4422  /* manually copy all fields from state2 to state1 */
4423  if (state1 == NULL)
4424  {
4425  old_context = MemoryContextSwitchTo(agg_context);
4426 
4427  state1 = makePolyNumAggState(fcinfo, false);
4428  state1->N = state2->N;
4429 
4430 #ifdef HAVE_INT128
4431  state1->sumX = state2->sumX;
4432 #else
4433  accum_sum_copy(&state1->sumX, &state2->sumX);
4434 #endif
4435  MemoryContextSwitchTo(old_context);
4436 
4437  PG_RETURN_POINTER(state1);
4438  }
4439 
4440  if (state2->N > 0)
4441  {
4442  state1->N += state2->N;
4443 
4444 #ifdef HAVE_INT128
4445  state1->sumX += state2->sumX;
4446 #else
4447  /* The rest of this needs to work in the aggregate context */
4448  old_context = MemoryContextSwitchTo(agg_context);
4449 
4450  /* Accumulate sums */
4451  accum_sum_combine(&state1->sumX, &state2->sumX);
4452 
4453  MemoryContextSwitchTo(old_context);
4454 #endif
4455 
4456  }
4457  PG_RETURN_POINTER(state1);
4458 }
4459 
4460 /*
4461  * int8_avg_serialize
4462  * Serialize PolyNumAggState into bytea using the standard
4463  * recv-function infrastructure.
4464  */
4465 Datum
4467 {
4468  PolyNumAggState *state;
4470  bytea *sumX;
4471  bytea *result;
4472 
4473  /* Ensure we disallow calling when not in aggregate context */
4474  if (!AggCheckCallContext(fcinfo, NULL))
4475  elog(ERROR, "aggregate function called in non-aggregate context");
4476 
4477  state = (PolyNumAggState *) PG_GETARG_POINTER(0);
4478 
4479  /*
4480  * If the platform supports int128 then sumX will be a 128 integer type.
4481  * Here we'll convert that into a numeric type so that the combine state
4482  * is in the same format for both int128 enabled machines and machines
4483  * which don't support that type. The logic here is that one day we might
4484  * like to send these over to another server for further processing and we
4485  * want a standard format to work with.
4486  */
4487  {
4488  Datum temp;
4489  NumericVar num;
4490 
4491  init_var(&num);
4492 
4493 #ifdef HAVE_INT128
4494  int128_to_numericvar(state->sumX, &num);
4495 #else
4496  accum_sum_final(&state->sumX, &num);
4497 #endif
4499  NumericGetDatum(make_result(&num)));
4500  sumX = DatumGetByteaPP(temp);
4501 
4502  free_var(&num);
4503  }
4504 
4505  pq_begintypsend(&buf);
4506 
4507  /* N */
4508  pq_sendint64(&buf, state->N);
4509 
4510  /* sumX */
4511  pq_sendbytes(&buf, VARDATA_ANY(sumX), VARSIZE_ANY_EXHDR(sumX));
4512 
4513  result = pq_endtypsend(&buf);
4514 
4515  PG_RETURN_BYTEA_P(result);
4516 }
4517 
4518 /*
4519  * int8_avg_deserialize
4520  * Deserialize bytea back into PolyNumAggState.
4521  */
4522 Datum
4524 {
4525  bytea *sstate;
4526  PolyNumAggState *result;
4528  Datum temp;
4529  NumericVar num;
4530 
4531  if (!AggCheckCallContext(fcinfo, NULL))
4532  elog(ERROR, "aggregate function called in non-aggregate context");
4533 
4534  sstate = PG_GETARG_BYTEA_PP(0);
4535 
4536  /*
4537  * Copy the bytea into a StringInfo so that we can "receive" it using the
4538  * standard recv-function infrastructure.
4539  */
4540  initStringInfo(&buf);
4542  VARDATA_ANY(sstate), VARSIZE_ANY_EXHDR(sstate));
4543 
4544  result = makePolyNumAggStateCurrentContext(false);
4545 
4546  /* N */
4547  result->N = pq_getmsgint64(&buf);
4548 
4549  /* sumX */
4551  PointerGetDatum(&buf),
4552  InvalidOid,
4553  -1);
4554  init_var_from_num(DatumGetNumeric(temp), &num);
4555 #ifdef HAVE_INT128
4556  numericvar_to_int128(&num, &result->sumX);
4557 #else
4558  accum_sum_add(&result->sumX, &num);
4559 #endif
4560 
4561  pq_getmsgend(&buf);
4562  pfree(buf.data);
4563 
4564  PG_RETURN_POINTER(result);
4565 }
4566 
4567 /*
4568  * Inverse transition functions to go with the above.
4569  */
4570 
4571 Datum
4573 {
4574  PolyNumAggState *state;
4575 
4576  state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
4577 
4578  /* Should not get here with no state */
4579  if (state == NULL)
4580  elog(ERROR, "int2_accum_inv called with NULL state");
4581 
4582  if (!PG_ARGISNULL(1))
4583  {
4584 #ifdef HAVE_INT128
4585  do_int128_discard(state, (int128) PG_GETARG_INT16(1));
4586 #else
4587  Numeric newval;
4588 
4590  PG_GETARG_DATUM(1)));
4591 
4592  /* Should never fail, all inputs have dscale 0 */
4593  if (!do_numeric_discard(state, newval))
4594  elog(ERROR, "do_numeric_discard failed unexpectedly");
4595 #endif
4596  }
4597 
4598  PG_RETURN_POINTER(state);
4599 }
4600 
4601 Datum
4603 {
4604  PolyNumAggState *state;
4605 
4606  state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
4607 
4608  /* Should not get here with no state */
4609  if (state == NULL)
4610  elog(ERROR, "int4_accum_inv called with NULL state");
4611 
4612  if (!PG_ARGISNULL(1))
4613  {
4614 #ifdef HAVE_INT128
4615  do_int128_discard(state, (int128) PG_GETARG_INT32(1));
4616 #else
4617  Numeric newval;
4618 
4620  PG_GETARG_DATUM(1)));
4621 
4622  /* Should never fail, all inputs have dscale 0 */
4623  if (!do_numeric_discard(state, newval))
4624  elog(ERROR, "do_numeric_discard failed unexpectedly");
4625 #endif
4626  }
4627 
4628  PG_RETURN_POINTER(state);
4629 }
4630 
4631 Datum
4633 {
4634  NumericAggState *state;
4635 
4636  state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
4637 
4638  /* Should not get here with no state */
4639  if (state == NULL)
4640  elog(ERROR, "int8_accum_inv called with NULL state");
4641 
4642  if (!PG_ARGISNULL(1))
4643  {
4644  Numeric newval;
4645 
4647  PG_GETARG_DATUM(1)));
4648 
4649  /* Should never fail, all inputs have dscale 0 */
4650  if (!do_numeric_discard(state, newval))
4651  elog(ERROR, "do_numeric_discard failed unexpectedly");
4652  }
4653 
4654  PG_RETURN_POINTER(state);
4655 }
4656 
4657 Datum
4659 {
4660  PolyNumAggState *state;
4661 
4662  state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
4663 
4664  /* Should not get here with no state */
4665  if (state == NULL)
4666  elog(ERROR, "int8_avg_accum_inv called with NULL state");
4667 
4668  if (!PG_ARGISNULL(1))
4669  {
4670 #ifdef HAVE_INT128
4671  do_int128_discard(state, (int128) PG_GETARG_INT64(1));
4672 #else
4673  Numeric newval;
4674 
4676  PG_GETARG_DATUM(1)));
4677 
4678  /* Should never fail, all inputs have dscale 0 */
4679  if (!do_numeric_discard(state, newval))
4680  elog(ERROR, "do_numeric_discard failed unexpectedly");
4681 #endif
4682  }
4683 
4684  PG_RETURN_POINTER(state);
4685 }
4686 
4687 Datum
4689 {
4690 #ifdef HAVE_INT128
4691  PolyNumAggState *state;
4692  Numeric res;
4693  NumericVar result;
4694 
4695  state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
4696 
4697  /* If there were no non-null inputs, return NULL */
4698  if (state == NULL || state->N == 0)
4699  PG_RETURN_NULL();
4700 
4701  init_var(&result);
4702 
4703  int128_to_numericvar(state->sumX, &result);
4704 
4705  res = make_result(&result);
4706 
4707  free_var(&result);
4708 
4709  PG_RETURN_NUMERIC(res);
4710 #else
4711  return numeric_sum(fcinfo);
4712 #endif
4713 }
4714 
4715 Datum
4717 {
4718 #ifdef HAVE_INT128
4719  PolyNumAggState *state;
4720  NumericVar result;
4721  Datum countd,
4722  sumd;
4723 
4724  state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
4725 
4726  /* If there were no non-null inputs, return NULL */
4727  if (state == NULL || state->N == 0)
4728  PG_RETURN_NULL();
4729 
4730  init_var(&result);
4731 
4732  int128_to_numericvar(state->sumX, &result);
4733 
4735  Int64GetDatumFast(state->N));
4736  sumd = NumericGetDatum(make_result(&result));
4737 
4738  free_var(&result);
4739 
4741 #else
4742  return numeric_avg(fcinfo);
4743 #endif
4744 }
4745 
4746 Datum
4748 {
4749  NumericAggState *state;
4750  Datum N_datum;
4751  Datum sumX_datum;
4752  NumericVar sumX_var;
4753 
4754  state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
4755 
4756  /* If there were no non-null inputs, return NULL */
4757  if (state == NULL || (state->N + state->NaNcount) == 0)
4758  PG_RETURN_NULL();
4759 
4760  if (state->NaNcount > 0) /* there was at least one NaN input */
4761  PG_RETURN_NUMERIC(make_result(&const_nan));
4762 
4763  N_datum = DirectFunctionCall1(int8_numeric, Int64GetDatum(state->N));
4764 
4765  init_var(&sumX_var);
4766  accum_sum_final(&state->sumX, &sumX_var);
4767  sumX_datum = NumericGetDatum(make_result(&sumX_var));
4768  free_var(&sumX_var);
4769 
4770  PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumX_datum, N_datum));
4771 }
4772 
4773 Datum
4775 {
4776  NumericAggState *state;
4777  NumericVar sumX_var;
4778  Numeric result;
4779 
4780  state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
4781 
4782  /* If there were no non-null inputs, return NULL */
4783  if (state == NULL || (state->N + state->NaNcount) == 0)
4784  PG_RETURN_NULL();
4785 
4786  if (state->NaNcount > 0) /* there was at least one NaN input */
4787  PG_RETURN_NUMERIC(make_result(&const_nan));
4788 
4789  init_var(&sumX_var);
4790  accum_sum_final(&state->sumX, &sumX_var);
4791  result = make_result(&sumX_var);
4792  free_var(&sumX_var);
4793 
4794  PG_RETURN_NUMERIC(result);
4795 }
4796 
4797 /*
4798  * Workhorse routine for the standard deviance and variance
4799  * aggregates. 'state' is aggregate's transition state.
4800  * 'variance' specifies whether we should calculate the
4801  * variance or the standard deviation. 'sample' indicates whether the
4802  * caller is interested in the sample or the population
4803  * variance/stddev.
4804  *
4805  * If appropriate variance statistic is undefined for the input,
4806  * *is_null is set to true and NULL is returned.
4807  */
4808 static Numeric
4810  bool variance, bool sample,
4811  bool *is_null)
4812 {
4813  Numeric res;
4814  NumericVar vN,
4815  vsumX,
4816  vsumX2,
4817  vNminus1;
4818  const NumericVar *comp;
4819  int rscale;
4820 
4821  /* Deal with empty input and NaN-input cases */
4822  if (state == NULL || (state->N + state->NaNcount) == 0)
4823  {
4824  *is_null = true;
4825  return NULL;
4826  }
4827 
4828  *is_null = false;
4829 
4830  if (state->NaNcount > 0)
4831  return make_result(&const_nan);
4832 
4833  init_var(&vN);
4834  init_var(&vsumX);
4835  init_var(&vsumX2);
4836 
4837  int64_to_numericvar(state->N, &vN);
4838  accum_sum_final(&(state->sumX), &vsumX);
4839  accum_sum_final(&(state->sumX2), &vsumX2);
4840 
4841  /*
4842  * Sample stddev and variance are undefined when N <= 1; population stddev
4843  * is undefined when N == 0. Return NULL in either case.
4844  */
4845  if (sample)
4846  comp = &const_one;
4847  else
4848  comp = &const_zero;
4849 
4850  if (cmp_var(&vN, comp) <= 0)
4851  {
4852  *is_null = true;
4853  return NULL;
4854  }
4855 
4856  init_var(&vNminus1);
4857  sub_var(&vN, &const_one, &vNminus1);
4858 
4859  /* compute rscale for mul_var calls */
4860  rscale = vsumX.dscale * 2;
4861 
4862  mul_var(&vsumX, &vsumX, &vsumX, rscale); /* vsumX = sumX * sumX */
4863  mul_var(&vN, &vsumX2, &vsumX2, rscale); /* vsumX2 = N * sumX2 */
4864  sub_var(&vsumX2, &vsumX, &vsumX2); /* N * sumX2 - sumX * sumX */
4865 
4866  if (cmp_var(&vsumX2, &const_zero) <= 0)
4867  {
4868  /* Watch out for roundoff error producing a negative numerator */
4869  res = make_result(&const_zero);
4870  }
4871  else
4872  {
4873  if (sample)
4874  mul_var(&vN, &vNminus1, &vNminus1, 0); /* N * (N - 1) */
4875  else
4876  mul_var(&vN, &vN, &vNminus1, 0); /* N * N */
4877  rscale = select_div_scale(&vsumX2, &vNminus1);
4878  div_var(&vsumX2, &vNminus1, &vsumX, rscale, true); /* variance */
4879  if (!variance)
4880  sqrt_var(&vsumX, &vsumX, rscale); /* stddev */
4881 
4882  res = make_result(&vsumX);
4883  }
4884 
4885  free_var(&vNminus1);
4886  free_var(&vsumX);
4887  free_var(&vsumX2);
4888 
4889  return res;
4890 }
4891 
4892 Datum
4894 {
4895  NumericAggState *state;
4896  Numeric res;
4897  bool is_null;
4898 
4899  state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
4900 
4901  res = numeric_stddev_internal(state, true, true, &is_null);
4902 
4903  if (is_null)
4904  PG_RETURN_NULL();
4905  else
4906  PG_RETURN_NUMERIC(res);
4907 }
4908 
4909 Datum
4911 {
4912  NumericAggState *state;
4913  Numeric res;
4914  bool is_null;
4915 
4916  state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
4917 
4918  res = numeric_stddev_internal(state, false, true, &is_null);
4919 
4920  if (is_null)
4921  PG_RETURN_NULL();
4922  else
4923  PG_RETURN_NUMERIC(res);
4924 }
4925 
4926 Datum
4928 {
4929  NumericAggState *state;
4930  Numeric res;
4931  bool is_null;
4932 
4933  state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
4934 
4935  res = numeric_stddev_internal(state, true, false, &is_null);
4936 
4937  if (is_null)
4938  PG_RETURN_NULL();
4939  else
4940  PG_RETURN_NUMERIC(res);
4941 }
4942 
4943 Datum
4945 {
4946  NumericAggState *state;
4947  Numeric res;
4948  bool is_null;
4949 
4950  state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
4951 
4952  res = numeric_stddev_internal(state, false, false, &is_null);
4953 
4954  if (is_null)
4955  PG_RETURN_NULL();
4956  else
4957  PG_RETURN_NUMERIC(res);
4958 }
4959 
4960 #ifdef HAVE_INT128
4961 static Numeric
4962 numeric_poly_stddev_internal(Int128AggState *state,
4963  bool variance, bool sample,
4964  bool *is_null)
4965 {
4966  NumericAggState numstate;
4967  Numeric res;
4968 
4969  /* Initialize an empty agg state */
4970  memset(&numstate, 0, sizeof(NumericAggState));
4971 
4972  if (state)
4973  {
4974  NumericVar tmp_var;
4975 
4976  numstate.N = state->N;
4977 
4978  init_var(&tmp_var);
4979 
4980  int128_to_numericvar(state->sumX, &tmp_var);
4981  accum_sum_add(&numstate.sumX, &tmp_var);
4982 
4983  int128_to_numericvar(state->sumX2, &tmp_var);
4984  accum_sum_add(&numstate.sumX2, &tmp_var);
4985 
4986  free_var(&tmp_var);
4987  }
4988 
4989  res = numeric_stddev_internal(&numstate, variance, sample, is_null);
4990 
4991  if (numstate.sumX.ndigits > 0)
4992  {
4993  pfree(numstate.sumX.pos_digits);
4994  pfree(numstate.sumX.neg_digits);
4995  }
4996  if (numstate.sumX2.ndigits > 0)
4997  {
4998  pfree(numstate.sumX2.pos_digits);
4999  pfree(numstate.sumX2.neg_digits);
5000  }
5001 
5002  return res;
5003 }
5004 #endif
5005 
5006 Datum
5008 {
5009 #ifdef HAVE_INT128
5010  PolyNumAggState *state;
5011  Numeric res;
5012  bool is_null;
5013 
5014  state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
5015 
5016  res = numeric_poly_stddev_internal(state, true, true, &is_null);
5017 
5018  if (is_null)
5019  PG_RETURN_NULL();
5020  else
5021  PG_RETURN_NUMERIC(res);
5022 #else
5023  return numeric_var_samp(fcinfo);
5024 #endif
5025 }
5026 
5027 Datum
5029 {
5030 #ifdef HAVE_INT128
5031  PolyNumAggState *state;
5032  Numeric res;
5033  bool is_null;
5034 
5035  state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
5036 
5037  res = numeric_poly_stddev_internal(state, false, true, &is_null);
5038 
5039  if (is_null)
5040  PG_RETURN_NULL();
5041  else
5042  PG_RETURN_NUMERIC(res);
5043 #else
5044  return numeric_stddev_samp(fcinfo);
5045 #endif
5046 }
5047 
5048 Datum
5050 {
5051 #ifdef HAVE_INT128
5052  PolyNumAggState *state;
5053  Numeric res;
5054  bool is_null;
5055 
5056  state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
5057 
5058  res = numeric_poly_stddev_internal(state, true, false, &is_null);
5059 
5060  if (is_null)
5061  PG_RETURN_NULL();
5062  else
5063  PG_RETURN_NUMERIC(res);
5064 #else
5065  return numeric_var_pop(fcinfo);
5066 #endif
5067 }
5068 
5069 Datum
5071 {
5072 #ifdef HAVE_INT128
5073  PolyNumAggState *state;
5074  Numeric res;
5075  bool is_null;
5076 
5077  state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
5078 
5079  res = numeric_poly_stddev_internal(state, false, false, &is_null);
5080 
5081  if (is_null)
5082  PG_RETURN_NULL();
5083  else
5084  PG_RETURN_NUMERIC(res);
5085 #else
5086  return numeric_stddev_pop(fcinfo);
5087 #endif
5088 }
5089 
5090 /*
5091  * SUM transition functions for integer datatypes.
5092  *
5093  * To avoid overflow, we use accumulators wider than the input datatype.
5094  * A Numeric accumulator is needed for int8 input; for int4 and int2
5095  * inputs, we use int8 accumulators which should be sufficient for practical
5096  * purposes. (The latter two therefore don't really belong in this file,
5097  * but we keep them here anyway.)
5098  *
5099  * Because SQL defines the SUM() of no values to be NULL, not zero,
5100  * the initial condition of the transition data value needs to be NULL. This
5101  * means we can't rely on ExecAgg to automatically insert the first non-null
5102  * data value into the transition data: it doesn't know how to do the type
5103  * conversion. The upshot is that these routines have to be marked non-strict
5104  * and handle substitution of the first non-null input themselves.
5105  *
5106  * Note: these functions are used only in plain aggregation mode.
5107  * In moving-aggregate mode, we use intX_avg_accum and intX_avg_accum_inv.
5108  */
5109 
5110 Datum
5112 {
5113  int64 newval;
5114 
5115  if (PG_ARGISNULL(0))
5116  {
5117  /* No non-null input seen so far... */
5118  if (PG_ARGISNULL(1))
5119  PG_RETURN_NULL(); /* still no non-null */
5120  /* This is the first non-null input. */
5121  newval = (int64) PG_GETARG_INT16(1);
5122  PG_RETURN_INT64(newval);
5123  }
5124 
5125  /*
5126  * If we're invoked as an aggregate, we can cheat and modify our first
5127  * parameter in-place to avoid palloc overhead. If not, we need to return
5128  * the new value of the transition variable. (If int8 is pass-by-value,
5129  * then of course this is useless as well as incorrect, so just ifdef it
5130  * out.)
5131  */
5132 #ifndef USE_FLOAT8_BYVAL /* controls int8 too */
5133  if (AggCheckCallContext(fcinfo, NULL))
5134  {
5135  int64 *oldsum = (int64 *) PG_GETARG_POINTER(0);
5136 
5137  /* Leave the running sum unchanged in the new input is null */
5138  if (!PG_ARGISNULL(1))
5139  *oldsum = *oldsum + (int64) PG_GETARG_INT16(1);
5140 
5141  PG_RETURN_POINTER(oldsum);
5142  }
5143  else
5144 #endif
5145  {
5146  int64 oldsum = PG_GETARG_INT64(0);
5147 
5148  /* Leave sum unchanged if new input is null. */
5149  if (PG_ARGISNULL(1))
5150  PG_RETURN_INT64(oldsum);
5151 
5152  /* OK to do the addition. */
5153  newval = oldsum + (int64) PG_GETARG_INT16(1);
5154 
5155  PG_RETURN_INT64(newval);
5156  }
5157 }
5158 
5159 Datum
5161 {
5162  int64 newval;
5163 
5164  if (PG_ARGISNULL(0))
5165  {
5166  /* No non-null input seen so far... */
5167  if (PG_ARGISNULL(1))
5168  PG_RETURN_NULL(); /* still no non-null */
5169  /* This is the first non-null input. */
5170  newval = (int64) PG_GETARG_INT32(1);
5171  PG_RETURN_INT64(newval);
5172  }
5173 
5174  /*
5175  * If we're invoked as an aggregate, we can cheat and modify our first
5176  * parameter in-place to avoid palloc overhead. If not, we need to return
5177  * the new value of the transition variable. (If int8 is pass-by-value,
5178  * then of course this is useless as well as incorrect, so just ifdef it
5179  * out.)
5180  */
5181 #ifndef USE_FLOAT8_BYVAL /* controls int8 too */
5182  if (AggCheckCallContext(fcinfo, NULL))
5183  {
5184  int64 *oldsum = (int64 *) PG_GETARG_POINTER(0);
5185 
5186  /* Leave the running sum unchanged in the new input is null */
5187  if (!PG_ARGISNULL(1))
5188  *oldsum = *oldsum + (int64) PG_GETARG_INT32(1);
5189 
5190  PG_RETURN_POINTER(oldsum);
5191  }
5192  else
5193 #endif
5194  {
5195  int64 oldsum = PG_GETARG_INT64(0);
5196 
5197  /* Leave sum unchanged if new input is null. */
5198  if (PG_ARGISNULL(1))
5199  PG_RETURN_INT64(oldsum);
5200 
5201  /* OK to do the addition. */
5202  newval = oldsum + (int64) PG_GETARG_INT32(1);
5203 
5204  PG_RETURN_INT64(newval);
5205  }
5206 }
5207 
5208 /*
5209  * Note: this function is obsolete, it's no longer used for SUM(int8).
5210  */
5211 Datum
5213 {
5214  Numeric oldsum;
5215  Datum newval;
5216 
5217  if (PG_ARGISNULL(0))
5218  {
5219  /* No non-null input seen so far... */
5220  if (PG_ARGISNULL(1))
5221  PG_RETURN_NULL(); /* still no non-null */
5222  /* This is the first non-null input. */
5224  PG_RETURN_DATUM(newval);
5225  }
5226 
5227  /*
5228  * Note that we cannot special-case the aggregate case here, as we do for
5229  * int2_sum and int4_sum: numeric is of variable size, so we cannot modify
5230  * our first parameter in-place.
5231  */
5232 
5233  oldsum = PG_GETARG_NUMERIC(0);
5234 
5235  /* Leave sum unchanged if new input is null. */
5236  if (PG_ARGISNULL(1))
5237  PG_RETURN_NUMERIC(oldsum);
5238 
5239  /* OK to do the addition. */
5241 
5243  NumericGetDatum(oldsum), newval));
5244 }
5245 
5246 
5247 /*
5248  * Routines for avg(int2) and avg(int4). The transition datatype
5249  * is a two-element int8 array, holding count and sum.
5250  *
5251  * These functions are also used for sum(int2) and sum(int4) when
5252  * operating in moving-aggregate mode, since for correct inverse transitions
5253  * we need to count the inputs.
5254  */
5255 
5256 typedef struct Int8TransTypeData
5257 {
5258  int64 count;
5259  int64 sum;
5261 
5262 Datum
5264 {
5265  ArrayType *transarray;
5267  Int8TransTypeData *transdata;
5268 
5269  /*
5270  * If we're invoked as an aggregate, we can cheat and modify our first
5271  * parameter in-place to reduce palloc overhead. Otherwise we need to make
5272  * a copy of it before scribbling on it.
5273  */
5274  if (AggCheckCallContext(fcinfo, NULL))
5275  transarray = PG_GETARG_ARRAYTYPE_P(0);
5276  else
5277  transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
5278 
5279  if (ARR_HASNULL(transarray) ||
5280  ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
5281  elog(ERROR, "expected 2-element int8 array");
5282 
5283  transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
5284  transdata->count++;
5285  transdata->sum += newval;
5286 
5287  PG_RETURN_ARRAYTYPE_P(transarray);
5288 }
5289 
5290 Datum
5292 {
5293  ArrayType *transarray;
5295  Int8TransTypeData *transdata;
5296 
5297  /*
5298  * If we're invoked as an aggregate, we can cheat and modify our first
5299  * parameter in-place to reduce palloc overhead. Otherwise we need to make
5300  * a copy of it before scribbling on it.
5301  */
5302  if (AggCheckCallContext(fcinfo, NULL))
5303  transarray = PG_GETARG_ARRAYTYPE_P(0);
5304  else
5305  transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
5306 
5307  if (ARR_HASNULL(transarray) ||
5308  ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
5309  elog(ERROR, "expected 2-element int8 array");
5310 
5311  transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
5312  transdata->count++;
5313  transdata->sum += newval;
5314 
5315  PG_RETURN_ARRAYTYPE_P(transarray);
5316 }
5317 
5318 Datum
5320 {
5321  ArrayType *transarray1;
5322  ArrayType *transarray2;
5323  Int8TransTypeData *state1;
5324  Int8TransTypeData *state2;
5325 
5326  if (!AggCheckCallContext(fcinfo, NULL))
5327  elog(ERROR, "aggregate function called in non-aggregate context");
5328 
5329  transarray1 = PG_GETARG_ARRAYTYPE_P(0);
5330  transarray2 = PG_GETARG_ARRAYTYPE_P(1);
5331 
5332  if (ARR_HASNULL(transarray1) ||
5333  ARR_SIZE(transarray1) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
5334  elog(ERROR, "expected 2-element int8 array");
5335 
5336  if (ARR_HASNULL(transarray2) ||
5337  ARR_SIZE(transarray2) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
5338  elog(ERROR, "expected 2-element int8 array");
5339 
5340  state1 = (Int8TransTypeData *) ARR_DATA_PTR(transarray1);
5341  state2 = (Int8TransTypeData *) ARR_DATA_PTR(transarray2);
5342 
5343  state1->count += state2->count;
5344  state1->sum += state2->sum;
5345 
5346  PG_RETURN_ARRAYTYPE_P(transarray1);
5347 }
5348 
5349 Datum
5351 {
5352  ArrayType *transarray;
5354  Int8TransTypeData *transdata;
5355 
5356  /*
5357  * If we're invoked as an aggregate, we can cheat and modify our first
5358  * parameter in-place to reduce palloc overhead. Otherwise we need to make
5359  * a copy of it before scribbling on it.
5360  */
5361  if (AggCheckCallContext(fcinfo, NULL))
5362  transarray = PG_GETARG_ARRAYTYPE_P(0);
5363  else
5364  transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
5365 
5366  if (ARR_HASNULL(transarray) ||
5367  ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
5368  elog(ERROR, "expected 2-element int8 array");
5369 
5370  transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
5371  transdata->count--;
5372  transdata->sum -= newval;
5373 
5374  PG_RETURN_ARRAYTYPE_P(transarray);
5375 }
5376 
5377 Datum
5379 {
5380  ArrayType *transarray;
5382  Int8TransTypeData *transdata;
5383 
5384  /*
5385  * If we're invoked as an aggregate, we can cheat and modify our first
5386  * parameter in-place to reduce palloc overhead. Otherwise we need to make
5387  * a copy of it before scribbling on it.
5388  */
5389  if (AggCheckCallContext(fcinfo, NULL))
5390  transarray = PG_GETARG_ARRAYTYPE_P(0);
5391  else
5392  transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
5393 
5394  if (ARR_HASNULL(transarray) ||
5395  ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
5396  elog(ERROR, "expected 2-element int8 array");
5397 
5398  transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
5399  transdata->count--;
5400  transdata->sum -= newval;
5401 
5402  PG_RETURN_ARRAYTYPE_P(transarray);
5403 }
5404 
5405 Datum
5407 {
5408  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
5409  Int8TransTypeData *transdata;
5410  Datum countd,
5411  sumd;
5412 
5413  if (ARR_HASNULL(transarray) ||
5414  ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
5415  elog(ERROR, "expected 2-element int8 array");
5416  transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
5417 
5418  /* SQL defines AVG of no values to be NULL */
5419  if (transdata->count == 0)
5420  PG_RETURN_NULL();
5421 
5423  Int64GetDatumFast(transdata->count));
5425  Int64GetDatumFast(transdata->sum));
5426 
5428 }
5429 
5430 /*
5431  * SUM(int2) and SUM(int4) both return int8, so we can use this
5432  * final function for both.
5433  */
5434 Datum
5436 {
5437  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
5438  Int8TransTypeData *transdata;
5439 
5440  if (ARR_HASNULL(transarray) ||
5441  ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
5442  elog(ERROR, "expected 2-element int8 array");
5443  transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
5444 
5445  /* SQL defines SUM of no values to be NULL */
5446  if (transdata->count == 0)
5447  PG_RETURN_NULL();
5448 
5449  PG_RETURN_DATUM(Int64GetDatumFast(transdata->sum));
5450 }
5451 
5452 
5453 /* ----------------------------------------------------------------------
5454  *
5455  * Debug support
5456  *
5457  * ----------------------------------------------------------------------
5458  */
5459 
5460 #ifdef NUMERIC_DEBUG
5461 
5462 /*
5463  * dump_numeric() - Dump a value in the db storage format for debugging
5464  */
5465 static void
5466 dump_numeric(const char *str, Numeric num)
5467 {
5469  int ndigits;
5470  int i;
5471 
5472  ndigits = NUMERIC_NDIGITS(num);
5473 
5474  printf("%s: NUMERIC w=%d d=%d ", str,
5475  NUMERIC_WEIGHT(num), NUMERIC_DSCALE(num));
5476  switch (NUMERIC_SIGN(num))
5477  {
5478  case NUMERIC_POS:
5479  printf("POS");
5480  break;
5481  case NUMERIC_NEG:
5482  printf("NEG");
5483  break;
5484  case NUMERIC_NAN:
5485  printf("NaN");
5486  break;
5487  default:
5488  printf("SIGN=0x%x", NUMERIC_SIGN(num));
5489  break;
5490  }
5491 
5492  for (i = 0; i < ndigits; i++)
5493  printf(" %0*d", DEC_DIGITS, digits[i]);
5494  printf("\n");
5495 }
5496 
5497 
5498 /*
5499  * dump_var() - Dump a value in the variable format for debugging
5500  */
5501 static void
5502 dump_var(const char *str, NumericVar *var)
5503 {
5504  int i;
5505 
5506  printf("%s: VAR w=%d d=%d ", str, var->weight, var->dscale);
5507  switch (var->sign)
5508  {
5509  case NUMERIC_POS:
5510  printf("POS");
5511  break;
5512  case NUMERIC_NEG:
5513  printf("NEG");
5514  break;
5515  case NUMERIC_NAN:
5516  printf("NaN");
5517  break;
5518  default:
5519  printf("SIGN=0x%x", var->sign);
5520  break;
5521  }
5522 
5523  for (i = 0; i < var->ndigits; i++)
5524  printf(" %0*d", DEC_DIGITS, var->digits[i]);
5525 
5526  printf("\n");
5527 }
5528 #endif /* NUMERIC_DEBUG */
5529 
5530 
5531 /* ----------------------------------------------------------------------
5532  *
5533  * Local functions follow
5534  *
5535  * In general, these do not support NaNs --- callers must eliminate
5536  * the possibility of NaN first. (make_result() is an exception.)
5537  *
5538  * ----------------------------------------------------------------------
5539  */
5540 
5541 
5542 /*
5543  * alloc_var() -
5544  *
5545  * Allocate a digit buffer of ndigits digits (plus a spare digit for rounding)
5546  */
5547 static void
5548 alloc_var(NumericVar *var, int ndigits)
5549 {
5550  digitbuf_free(var->buf);
5551  var->buf = digitbuf_alloc(ndigits + 1);
5552  var->buf[0] = 0; /* spare digit for rounding */
5553  var->digits = var->buf + 1;
5554  var->ndigits = ndigits;
5555 }
5556 
5557 
5558 /*
5559  * free_var() -
5560  *
5561  * Return the digit buffer of a variable to the free pool
5562  */
5563 static void
5565 {
5566  digitbuf_free(var->buf);
5567  var->buf = NULL;
5568  var->digits = NULL;
5569  var->sign = NUMERIC_NAN;
5570 }
5571 
5572 
5573 /*
5574  * zero_var() -
5575  *
5576  * Set a variable to ZERO.
5577  * Note: its dscale is not touched.
5578  */
5579 static void
5581 {
5582  digitbuf_free(var->buf);
5583  var->buf = NULL;
5584  var->digits = NULL;
5585  var->ndigits = 0;
5586  var->weight = 0; /* by convention; doesn't really matter */
5587  var->sign = NUMERIC_POS; /* anything but NAN... */
5588 }
5589 
5590 
5591 /*
5592  * set_var_from_str()
5593  *
5594  * Parse a string and put the number into a variable
5595  *
5596  * This function does not handle leading or trailing spaces, and it doesn't
5597  * accept "NaN" either. It returns the end+1 position so that caller can
5598  * check for trailing spaces/garbage if deemed necessary.
5599  *
5600  * cp is the place to actually start parsing; str is what to use in error
5601  * reports. (Typically cp would be the same except advanced over spaces.)
5602  */
5603 static const char *
5604 set_var_from_str(const char *str, const char *cp, NumericVar *dest)
5605 {
5606  bool have_dp = false;
5607  int i;
5608  unsigned char *decdigits;
5609  int sign = NUMERIC_POS;
5610  int dweight = -1;
5611  int ddigits;
5612  int dscale = 0;
5613  int weight;
5614  int ndigits;
5615  int offset;
5617 
5618  /*
5619  * We first parse the string to extract decimal digits and determine the
5620  * correct decimal weight. Then convert to NBASE representation.
5621  */
5622  switch (*cp)
5623  {
5624  case '+':
5625  sign = NUMERIC_POS;
5626  cp++;
5627  break;
5628 
5629  case '-':
5630  sign = NUMERIC_NEG;
5631  cp++;
5632  break;
5633  }
5634 
5635  if (*cp == '.')
5636  {
5637  have_dp = true;
5638  cp++;
5639  }
5640 
5641  if (!isdigit((unsigned char) *cp))
5642  ereport(ERROR,
5643  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
5644  errmsg("invalid input syntax for type %s: \"%s\"",
5645  "numeric", str)));
5646 
5647  decdigits = (unsigned char *) palloc(strlen(cp) + DEC_DIGITS * 2);
5648 
5649  /* leading padding for digit alignment later */
5650  memset(decdigits, 0, DEC_DIGITS);
5651  i = DEC_DIGITS;
5652 
5653  while (*cp)
5654  {
5655  if (isdigit((unsigned char) *cp))
5656  {
5657  decdigits[i++] = *cp++ - '0';
5658  if (!have_dp)
5659  dweight++;
5660  else
5661  dscale++;
5662  }
5663  else if (*cp == '.')
5664  {
5665  if (have_dp)
5666  ereport(ERROR,
5667  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
5668  errmsg("invalid input syntax for type %s: \"%s\"",
5669  "numeric", str)));
5670  have_dp = true;
5671  cp++;
5672  }
5673  else
5674  break;
5675  }
5676 
5677  ddigits = i - DEC_DIGITS;
5678  /* trailing padding for digit alignment later */
5679  memset(decdigits + i, 0, DEC_DIGITS - 1);
5680 
5681  /* Handle exponent, if any */
5682  if (*cp == 'e' || *cp == 'E')
5683  {
5684  long exponent;
5685  char *endptr;
5686 
5687  cp++;
5688  exponent = strtol(cp, &endptr, 10);
5689  if (endptr == cp)
5690  ereport(ERROR,
5691  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
5692  errmsg("invalid input syntax for type %s: \"%s\"",
5693  "numeric", str)));
5694  cp = endptr;
5695 
5696  /*
5697  * At this point, dweight and dscale can't be more than about
5698  * INT_MAX/2 due to the MaxAllocSize limit on string length, so
5699  * constraining the exponent similarly should be enough to prevent
5700  * integer overflow in this function. If the value is too large to
5701  * fit in storage format, make_result() will complain about it later;
5702  * for consistency use the same ereport errcode/text as make_result().
5703  */
5704  if (exponent >= INT_MAX / 2 || exponent <= -(INT_MAX / 2))
5705  ereport(ERROR,
5706  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
5707  errmsg("value overflows numeric format")));
5708  dweight += (int) exponent;
5709  dscale -= (int) exponent;
5710  if (dscale < 0)
5711  dscale = 0;
5712  }
5713 
5714  /*
5715  * Okay, convert pure-decimal representation to base NBASE. First we need
5716  * to determine the converted weight and ndigits. offset is the number of
5717  * decimal zeroes to insert before the first given digit to have a
5718  * correctly aligned first NBASE digit.
5719  */
5720  if (dweight >= 0)
5721  weight = (dweight + 1 + DEC_DIGITS - 1) / DEC_DIGITS - 1;
5722  else
5723  weight = -((-dweight - 1) / DEC_DIGITS + 1);
5724  offset = (weight + 1) * DEC_DIGITS - (dweight + 1);
5725  ndigits = (ddigits + offset + DEC_DIGITS - 1) / DEC_DIGITS;
5726 
5727  alloc_var(dest, ndigits);
5728  dest->sign = sign;
5729  dest->weight = weight;
5730  dest->dscale = dscale;
5731 
5732  i = DEC_DIGITS - offset;
5733  digits = dest->digits;
5734 
5735  while (ndigits-- > 0)
5736  {
5737 #if DEC_DIGITS == 4
5738  *digits++ = ((decdigits[i] * 10 + decdigits[i + 1]) * 10 +
5739  decdigits[i + 2]) * 10 + decdigits[i + 3];
5740 #elif DEC_DIGITS == 2
5741  *digits++ = decdigits[i] * 10 + decdigits[i + 1];
5742 #elif DEC_DIGITS == 1
5743  *digits++ = decdigits[i];
5744 #else
5745 #error unsupported NBASE
5746 #endif
5747  i += DEC_DIGITS;
5748  }
5749 
5750  pfree(decdigits);
5751 
5752  /* Strip any leading/trailing zeroes, and normalize weight if zero */
5753  strip_var(dest);
5754 
5755  /* Return end+1 position for caller */
5756  return cp;
5757 }
5758 
5759 
5760 /*
5761  * set_var_from_num() -
5762  *
5763  * Convert the packed db format into a variable
5764  */
5765 static void
5767 {
5768  int ndigits;
5769 
5770  ndigits = NUMERIC_NDIGITS(num);
5771 
5772  alloc_var(dest, ndigits);
5773 
5774  dest->weight = NUMERIC_WEIGHT(num);
5775  dest->sign = NUMERIC_SIGN(num);
5776  dest->dscale = NUMERIC_DSCALE(num);
5777 
5778  memcpy(dest->digits, NUMERIC_DIGITS(num), ndigits * sizeof(NumericDigit));
5779 }
5780 
5781 
5782 /*
5783  * init_var_from_num() -
5784  *
5785  * Initialize a variable from packed db format. The digits array is not
5786  * copied, which saves some cycles when the resulting var is not modified.
5787  * Also, there's no need to call free_var(), as long as you don't assign any
5788  * other value to it (with set_var_* functions, or by using the var as the
5789  * destination of a function like add_var())
5790  *
5791  * CAUTION: Do not modify the digits buffer of a var initialized with this
5792  * function, e.g by calling round_var() or trunc_var(), as the changes will
5793  * propagate to the original Numeric! It's OK to use it as the destination
5794  * argument of one of the calculational functions, though.
5795  */
5796 static void
5798 {
5799  dest->ndigits = NUMERIC_NDIGITS(num);
5800  dest->weight = NUMERIC_WEIGHT(num);
5801  dest->sign = NUMERIC_SIGN(num);
5802  dest->dscale = NUMERIC_DSCALE(num);
5803  dest->digits = NUMERIC_DIGITS(num);
5804  dest->buf = NULL; /* digits array is not palloc'd */
5805 }
5806 
5807 
5808 /*
5809  * set_var_from_var() -
5810  *
5811  * Copy one variable into another
5812  */
5813 static void
5815 {
5816  NumericDigit *newbuf;
5817 
5818  newbuf = digitbuf_alloc(value->ndigits + 1);
5819  newbuf[0] = 0; /* spare digit for rounding */
5820  if (value->ndigits > 0) /* else value->digits might be null */
5821  memcpy(newbuf + 1, value->digits,
5822  value->ndigits * sizeof(NumericDigit));
5823 
5824  digitbuf_free(dest->buf);
5825 
5826  memmove(dest, value, sizeof(NumericVar));
5827  dest->buf = newbuf;
5828  dest->digits = newbuf + 1;
5829 }
5830 
5831 
5832 /*
5833  * get_str_from_var() -
5834  *
5835  * Convert a var to text representation (guts of numeric_out).
5836  * The var is displayed to the number of digits indicated by its dscale.
5837  * Returns a palloc'd string.
5838  */
5839 static char *
5841 {
5842  int dscale;
5843  char *str;
5844  char *cp;
5845  char *endcp;
5846  int i;
5847  int d;
5848  NumericDigit dig;
5849 
5850 #if DEC_DIGITS > 1
5851  NumericDigit d1;
5852 #endif
5853 
5854  dscale = var->dscale;
5855 
5856  /*
5857  * Allocate space for the result.
5858  *
5859  * i is set to the # of decimal digits before decimal point. dscale is the
5860  * # of decimal digits we will print after decimal point. We may generate
5861  * as many as DEC_DIGITS-1 excess digits at the end, and in addition we
5862  * need room for sign, decimal point, null terminator.
5863  */
5864  i = (var->weight + 1) * DEC_DIGITS;
5865  if (i <= 0)
5866  i = 1;
5867 
5868  str = palloc(i + dscale + DEC_DIGITS + 2);
5869  cp = str;
5870 
5871  /*
5872  * Output a dash for negative values
5873  */
5874  if (var->sign == NUMERIC_NEG)
5875  *cp++ = '-';
5876 
5877  /*
5878  * Output all digits before the decimal point
5879  */
5880  if (var->weight < 0)
5881  {
5882  d = var->weight + 1;
5883  *cp++ = '0';
5884  }
5885  else
5886  {
5887  for (d = 0; d <= var->weight; d++)
5888  {
5889  dig = (d < var->ndigits) ? var->digits[d] : 0;
5890  /* In the first digit, suppress extra leading decimal zeroes */
5891 #if DEC_DIGITS == 4
5892  {
5893  bool putit = (d > 0);
5894 
5895  d1 = dig / 1000;
5896  dig -= d1 * 1000;
5897  putit |= (d1 > 0);
5898  if (putit)
5899  *cp++ = d1 + '0';
5900  d1 = dig / 100;
5901  dig -= d1 * 100;
5902  putit |= (d1 > 0);
5903  if (putit)
5904  *cp++ = d1 + '0';
5905  d1 = dig / 10;
5906  dig -= d1 * 10;
5907  putit |= (d1 > 0);
5908  if (putit)
5909  *cp++ = d1 + '0';
5910  *cp++ = dig + '0';
5911  }
5912 #elif DEC_DIGITS == 2
5913  d1 = dig / 10;
5914  dig -= d1 * 10;
5915  if (d1 > 0 || d > 0)
5916  *cp++ = d1 + '0';
5917  *cp++ = dig + '0';
5918 #elif DEC_DIGITS == 1
5919  *cp++ = dig + '0';
5920 #else
5921 #error unsupported NBASE
5922 #endif
5923  }
5924  }
5925 
5926  /*
5927  * If requested, output a decimal point and all the digits that follow it.
5928  * We initially put out a multiple of DEC_DIGITS digits, then truncate if
5929  * needed.
5930  */
5931  if (dscale > 0)
5932  {
5933  *cp++ = '.';
5934  endcp = cp + dscale;
5935  for (i = 0; i < dscale; d++, i += DEC_DIGITS)
5936  {
5937  dig = (d >= 0 && d < var->ndigits) ? var->digits[d] : 0;
5938 #if DEC_DIGITS == 4
5939  d1 = dig / 1000;
5940  dig -= d1 * 1000;
5941  *cp++ = d1 + '0';
5942  d1 = dig / 100;
5943  dig -= d1 * 100;
5944  *cp++ = d1 + '0';
5945  d1 = dig / 10;
5946  dig -= d1 * 10;
5947  *cp++ = d1 + '0';
5948  *cp++ = dig + '0';
5949 #elif DEC_DIGITS == 2
5950  d1 = dig / 10;
5951  dig -= d1 * 10;
5952  *cp++ = d1 + '0';
5953  *cp++ = dig + '0';
5954 #elif DEC_DIGITS == 1
5955  *cp++ = dig + '0';
5956 #else
5957 #error unsupported NBASE
5958 #endif
5959  }
5960  cp = endcp;
5961  }
5962 
5963  /*
5964  * terminate the string and return it
5965  */
5966  *cp = '\0';
5967  return str;