Coverage Report

Created: 2026-10-16 06:48

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