Age Owner TLA Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * numeric.c
4 : * An exact numeric data type for the Postgres database system
5 : *
6 : * Original coding 1998, Jan Wieck. Heavily revised 2003, Tom Lane.
7 : *
8 : * Many of the algorithmic ideas are borrowed from David M. Smith's "FM"
9 : * multiple-precision math library, most recently published as Algorithm
10 : * 786: Multiple-Precision Complex Arithmetic and Functions, ACM
11 : * Transactions on Mathematical Software, Vol. 24, No. 4, December 1998,
12 : * pages 359-367.
13 : *
14 : * Copyright (c) 1998-2023, PostgreSQL Global Development Group
15 : *
16 : * IDENTIFICATION
17 : * src/backend/utils/adt/numeric.c
18 : *
19 : *-------------------------------------------------------------------------
20 : */
21 :
22 : #include "postgres.h"
23 :
24 : #include <ctype.h>
25 : #include <float.h>
26 : #include <limits.h>
27 : #include <math.h>
28 :
29 : #include "catalog/pg_type.h"
30 : #include "common/hashfn.h"
31 : #include "common/int.h"
32 : #include "funcapi.h"
33 : #include "lib/hyperloglog.h"
34 : #include "libpq/pqformat.h"
35 : #include "miscadmin.h"
36 : #include "nodes/nodeFuncs.h"
37 : #include "nodes/supportnodes.h"
38 : #include "utils/array.h"
39 : #include "utils/builtins.h"
40 : #include "utils/float.h"
41 : #include "utils/guc.h"
42 : #include "utils/numeric.h"
43 : #include "utils/pg_lsn.h"
44 : #include "utils/sortsupport.h"
45 :
46 : /* ----------
47 : * Uncomment the following to enable compilation of dump_numeric()
48 : * and dump_var() and to get a dump of any result produced by make_result().
49 : * ----------
50 : #define NUMERIC_DEBUG
51 : */
52 :
53 :
54 : /* ----------
55 : * Local data types
56 : *
57 : * Numeric values are represented in a base-NBASE floating point format.
58 : * Each "digit" ranges from 0 to NBASE-1. The type NumericDigit is signed
59 : * and wide enough to store a digit. We assume that NBASE*NBASE can fit in
60 : * an int. Although the purely calculational routines could handle any even
61 : * NBASE that's less than sqrt(INT_MAX), in practice we are only interested
62 : * in NBASE a power of ten, so that I/O conversions and decimal rounding
63 : * are easy. Also, it's actually more efficient if NBASE is rather less than
64 : * sqrt(INT_MAX), so that there is "headroom" for mul_var and div_var_fast to
65 : * postpone processing carries.
66 : *
67 : * Values of NBASE other than 10000 are considered of historical interest only
68 : * and are no longer supported in any sense; no mechanism exists for the client
69 : * to discover the base, so every client supporting binary mode expects the
70 : * base-10000 format. If you plan to change this, also note the numeric
71 : * abbreviation code, which assumes NBASE=10000.
72 : * ----------
73 : */
74 :
75 : #if 0
76 : #define NBASE 10
77 : #define HALF_NBASE 5
78 : #define DEC_DIGITS 1 /* decimal digits per NBASE digit */
79 : #define MUL_GUARD_DIGITS 4 /* these are measured in NBASE digits */
80 : #define DIV_GUARD_DIGITS 8
81 :
82 : typedef signed char NumericDigit;
83 : #endif
84 :
85 : #if 0
86 : #define NBASE 100
87 : #define HALF_NBASE 50
88 : #define DEC_DIGITS 2 /* decimal digits per NBASE digit */
89 : #define MUL_GUARD_DIGITS 3 /* these are measured in NBASE digits */
90 : #define DIV_GUARD_DIGITS 6
91 :
92 : typedef signed char NumericDigit;
93 : #endif
94 :
95 : #if 1
96 : #define NBASE 10000
97 : #define HALF_NBASE 5000
98 : #define DEC_DIGITS 4 /* decimal digits per NBASE digit */
99 : #define MUL_GUARD_DIGITS 2 /* these are measured in NBASE digits */
100 : #define DIV_GUARD_DIGITS 4
101 :
102 : typedef int16 NumericDigit;
103 : #endif
104 :
105 : /*
106 : * The Numeric type as stored on disk.
107 : *
108 : * If the high bits of the first word of a NumericChoice (n_header, or
109 : * n_short.n_header, or n_long.n_sign_dscale) are NUMERIC_SHORT, then the
110 : * numeric follows the NumericShort format; if they are NUMERIC_POS or
111 : * NUMERIC_NEG, it follows the NumericLong format. If they are NUMERIC_SPECIAL,
112 : * the value is a NaN or Infinity. We currently always store SPECIAL values
113 : * using just two bytes (i.e. only n_header), but previous releases used only
114 : * the NumericLong format, so we might find 4-byte NaNs (though not infinities)
115 : * on disk if a database has been migrated using pg_upgrade. In either case,
116 : * the low-order bits of a special value's header are reserved and currently
117 : * should always be set to zero.
118 : *
119 : * In the NumericShort format, the remaining 14 bits of the header word
120 : * (n_short.n_header) are allocated as follows: 1 for sign (positive or
121 : * negative), 6 for dynamic scale, and 7 for weight. In practice, most
122 : * commonly-encountered values can be represented this way.
123 : *
124 : * In the NumericLong format, the remaining 14 bits of the header word
125 : * (n_long.n_sign_dscale) represent the display scale; and the weight is
126 : * stored separately in n_weight.
127 : *
128 : * NOTE: by convention, values in the packed form have been stripped of
129 : * all leading and trailing zero digits (where a "digit" is of base NBASE).
130 : * In particular, if the value is zero, there will be no digits at all!
131 : * The weight is arbitrary in that case, but we normally set it to zero.
132 : */
133 :
134 : struct NumericShort
135 : {
136 : uint16 n_header; /* Sign + display scale + weight */
137 : NumericDigit n_data[FLEXIBLE_ARRAY_MEMBER]; /* Digits */
138 : };
139 :
140 : struct NumericLong
141 : {
142 : uint16 n_sign_dscale; /* Sign + display scale */
143 : int16 n_weight; /* Weight of 1st digit */
144 : NumericDigit n_data[FLEXIBLE_ARRAY_MEMBER]; /* Digits */
145 : };
146 :
147 : union NumericChoice
148 : {
149 : uint16 n_header; /* Header word */
150 : struct NumericLong n_long; /* Long form (4-byte header) */
151 : struct NumericShort n_short; /* Short form (2-byte header) */
152 : };
153 :
154 : struct NumericData
155 : {
156 : int32 vl_len_; /* varlena header (do not touch directly!) */
157 : union NumericChoice choice; /* choice of format */
158 : };
159 :
160 :
161 : /*
162 : * Interpretation of high bits.
163 : */
164 :
165 : #define NUMERIC_SIGN_MASK 0xC000
166 : #define NUMERIC_POS 0x0000
167 : #define NUMERIC_NEG 0x4000
168 : #define NUMERIC_SHORT 0x8000
169 : #define NUMERIC_SPECIAL 0xC000
170 :
171 : #define NUMERIC_FLAGBITS(n) ((n)->choice.n_header & NUMERIC_SIGN_MASK)
172 : #define NUMERIC_IS_SHORT(n) (NUMERIC_FLAGBITS(n) == NUMERIC_SHORT)
173 : #define NUMERIC_IS_SPECIAL(n) (NUMERIC_FLAGBITS(n) == NUMERIC_SPECIAL)
174 :
175 : #define NUMERIC_HDRSZ (VARHDRSZ + sizeof(uint16) + sizeof(int16))
176 : #define NUMERIC_HDRSZ_SHORT (VARHDRSZ + sizeof(uint16))
177 :
178 : /*
179 : * If the flag bits are NUMERIC_SHORT or NUMERIC_SPECIAL, we want the short
180 : * header; otherwise, we want the long one. Instead of testing against each
181 : * value, we can just look at the high bit, for a slight efficiency gain.
182 : */
183 : #define NUMERIC_HEADER_IS_SHORT(n) (((n)->choice.n_header & 0x8000) != 0)
184 : #define NUMERIC_HEADER_SIZE(n) \
185 : (VARHDRSZ + sizeof(uint16) + \
186 : (NUMERIC_HEADER_IS_SHORT(n) ? 0 : sizeof(int16)))
187 :
188 : /*
189 : * Definitions for special values (NaN, positive infinity, negative infinity).
190 : *
191 : * The two bits after the NUMERIC_SPECIAL bits are 00 for NaN, 01 for positive
192 : * infinity, 11 for negative infinity. (This makes the sign bit match where
193 : * it is in a short-format value, though we make no use of that at present.)
194 : * We could mask off the remaining bits before testing the active bits, but
195 : * currently those bits must be zeroes, so masking would just add cycles.
196 : */
197 : #define NUMERIC_EXT_SIGN_MASK 0xF000 /* high bits plus NaN/Inf flag bits */
198 : #define NUMERIC_NAN 0xC000
199 : #define NUMERIC_PINF 0xD000
200 : #define NUMERIC_NINF 0xF000
201 : #define NUMERIC_INF_SIGN_MASK 0x2000
202 :
203 : #define NUMERIC_EXT_FLAGBITS(n) ((n)->choice.n_header & NUMERIC_EXT_SIGN_MASK)
204 : #define NUMERIC_IS_NAN(n) ((n)->choice.n_header == NUMERIC_NAN)
205 : #define NUMERIC_IS_PINF(n) ((n)->choice.n_header == NUMERIC_PINF)
206 : #define NUMERIC_IS_NINF(n) ((n)->choice.n_header == NUMERIC_NINF)
207 : #define NUMERIC_IS_INF(n) \
208 : (((n)->choice.n_header & ~NUMERIC_INF_SIGN_MASK) == NUMERIC_PINF)
209 :
210 : /*
211 : * Short format definitions.
212 : */
213 :
214 : #define NUMERIC_SHORT_SIGN_MASK 0x2000
215 : #define NUMERIC_SHORT_DSCALE_MASK 0x1F80
216 : #define NUMERIC_SHORT_DSCALE_SHIFT 7
217 : #define NUMERIC_SHORT_DSCALE_MAX \
218 : (NUMERIC_SHORT_DSCALE_MASK >> NUMERIC_SHORT_DSCALE_SHIFT)
219 : #define NUMERIC_SHORT_WEIGHT_SIGN_MASK 0x0040
220 : #define NUMERIC_SHORT_WEIGHT_MASK 0x003F
221 : #define NUMERIC_SHORT_WEIGHT_MAX NUMERIC_SHORT_WEIGHT_MASK
222 : #define NUMERIC_SHORT_WEIGHT_MIN (-(NUMERIC_SHORT_WEIGHT_MASK+1))
223 :
224 : /*
225 : * Extract sign, display scale, weight. These macros extract field values
226 : * suitable for the NumericVar format from the Numeric (on-disk) format.
227 : *
228 : * Note that we don't trouble to ensure that dscale and weight read as zero
229 : * for an infinity; however, that doesn't matter since we never convert
230 : * "special" numerics to NumericVar form. Only the constants defined below
231 : * (const_nan, etc) ever represent a non-finite value as a NumericVar.
232 : */
233 :
234 : #define NUMERIC_DSCALE_MASK 0x3FFF
235 : #define NUMERIC_DSCALE_MAX NUMERIC_DSCALE_MASK
236 :
237 : #define NUMERIC_SIGN(n) \
238 : (NUMERIC_IS_SHORT(n) ? \
239 : (((n)->choice.n_short.n_header & NUMERIC_SHORT_SIGN_MASK) ? \
240 : NUMERIC_NEG : NUMERIC_POS) : \
241 : (NUMERIC_IS_SPECIAL(n) ? \
242 : NUMERIC_EXT_FLAGBITS(n) : NUMERIC_FLAGBITS(n)))
243 : #define NUMERIC_DSCALE(n) (NUMERIC_HEADER_IS_SHORT((n)) ? \
244 : ((n)->choice.n_short.n_header & NUMERIC_SHORT_DSCALE_MASK) \
245 : >> NUMERIC_SHORT_DSCALE_SHIFT \
246 : : ((n)->choice.n_long.n_sign_dscale & NUMERIC_DSCALE_MASK))
247 : #define NUMERIC_WEIGHT(n) (NUMERIC_HEADER_IS_SHORT((n)) ? \
248 : (((n)->choice.n_short.n_header & NUMERIC_SHORT_WEIGHT_SIGN_MASK ? \
249 : ~NUMERIC_SHORT_WEIGHT_MASK : 0) \
250 : | ((n)->choice.n_short.n_header & NUMERIC_SHORT_WEIGHT_MASK)) \
251 : : ((n)->choice.n_long.n_weight))
252 :
253 : /* ----------
254 : * NumericVar is the format we use for arithmetic. The digit-array part
255 : * is the same as the NumericData storage format, but the header is more
256 : * complex.
257 : *
258 : * The value represented by a NumericVar is determined by the sign, weight,
259 : * ndigits, and digits[] array. If it is a "special" value (NaN or Inf)
260 : * then only the sign field matters; ndigits should be zero, and the weight
261 : * and dscale fields are ignored.
262 : *
263 : * Note: the first digit of a NumericVar's value is assumed to be multiplied
264 : * by NBASE ** weight. Another way to say it is that there are weight+1
265 : * digits before the decimal point. It is possible to have weight < 0.
266 : *
267 : * buf points at the physical start of the palloc'd digit buffer for the
268 : * NumericVar. digits points at the first digit in actual use (the one
269 : * with the specified weight). We normally leave an unused digit or two
270 : * (preset to zeroes) between buf and digits, so that there is room to store
271 : * a carry out of the top digit without reallocating space. We just need to
272 : * decrement digits (and increment weight) to make room for the carry digit.
273 : * (There is no such extra space in a numeric value stored in the database,
274 : * only in a NumericVar in memory.)
275 : *
276 : * If buf is NULL then the digit buffer isn't actually palloc'd and should
277 : * not be freed --- see the constants below for an example.
278 : *
279 : * dscale, or display scale, is the nominal precision expressed as number
280 : * of digits after the decimal point (it must always be >= 0 at present).
281 : * dscale may be more than the number of physically stored fractional digits,
282 : * implying that we have suppressed storage of significant trailing zeroes.
283 : * It should never be less than the number of stored digits, since that would
284 : * imply hiding digits that are present. NOTE that dscale is always expressed
285 : * in *decimal* digits, and so it may correspond to a fractional number of
286 : * base-NBASE digits --- divide by DEC_DIGITS to convert to NBASE digits.
287 : *
288 : * rscale, or result scale, is the target precision for a computation.
289 : * Like dscale it is expressed as number of *decimal* digits after the decimal
290 : * point, and is always >= 0 at present.
291 : * Note that rscale is not stored in variables --- it's figured on-the-fly
292 : * from the dscales of the inputs.
293 : *
294 : * While we consistently use "weight" to refer to the base-NBASE weight of
295 : * a numeric value, it is convenient in some scale-related calculations to
296 : * make use of the base-10 weight (ie, the approximate log10 of the value).
297 : * To avoid confusion, such a decimal-units weight is called a "dweight".
298 : *
299 : * NB: All the variable-level functions are written in a style that makes it
300 : * possible to give one and the same variable as argument and destination.
301 : * This is feasible because the digit buffer is separate from the variable.
302 : * ----------
303 : */
304 : typedef struct NumericVar
305 : {
306 : int ndigits; /* # of digits in digits[] - can be 0! */
307 : int weight; /* weight of first digit */
308 : int sign; /* NUMERIC_POS, _NEG, _NAN, _PINF, or _NINF */
309 : int dscale; /* display scale */
310 : NumericDigit *buf; /* start of palloc'd space for digits[] */
311 : NumericDigit *digits; /* base-NBASE digits */
312 : } NumericVar;
313 :
314 :
315 : /* ----------
316 : * Data for generate_series
317 : * ----------
318 : */
319 : typedef struct
320 : {
321 : NumericVar current;
322 : NumericVar stop;
323 : NumericVar step;
324 : } generate_series_numeric_fctx;
325 :
326 :
327 : /* ----------
328 : * Sort support.
329 : * ----------
330 : */
331 : typedef struct
332 : {
333 : void *buf; /* buffer for short varlenas */
334 : int64 input_count; /* number of non-null values seen */
335 : bool estimating; /* true if estimating cardinality */
336 :
337 : hyperLogLogState abbr_card; /* cardinality estimator */
338 : } NumericSortSupport;
339 :
340 :
341 : /* ----------
342 : * Fast sum accumulator.
343 : *
344 : * NumericSumAccum is used to implement SUM(), and other standard aggregates
345 : * that track the sum of input values. It uses 32-bit integers to store the
346 : * digits, instead of the normal 16-bit integers (with NBASE=10000). This
347 : * way, we can safely accumulate up to NBASE - 1 values without propagating
348 : * carry, before risking overflow of any of the digits. 'num_uncarried'
349 : * tracks how many values have been accumulated without propagating carry.
350 : *
351 : * Positive and negative values are accumulated separately, in 'pos_digits'
352 : * and 'neg_digits'. This is simpler and faster than deciding whether to add
353 : * or subtract from the current value, for each new value (see sub_var() for
354 : * the logic we avoid by doing this). Both buffers are of same size, and
355 : * have the same weight and scale. In accum_sum_final(), the positive and
356 : * negative sums are added together to produce the final result.
357 : *
358 : * When a new value has a larger ndigits or weight than the accumulator
359 : * currently does, the accumulator is enlarged to accommodate the new value.
360 : * We normally have one zero digit reserved for carry propagation, and that
361 : * is indicated by the 'have_carry_space' flag. When accum_sum_carry() uses
362 : * up the reserved digit, it clears the 'have_carry_space' flag. The next
363 : * call to accum_sum_add() will enlarge the buffer, to make room for the
364 : * extra digit, and set the flag again.
365 : *
366 : * To initialize a new accumulator, simply reset all fields to zeros.
367 : *
368 : * The accumulator does not handle NaNs.
369 : * ----------
370 : */
371 : typedef struct NumericSumAccum
372 : {
373 : int ndigits;
374 : int weight;
375 : int dscale;
376 : int num_uncarried;
377 : bool have_carry_space;
378 : int32 *pos_digits;
379 : int32 *neg_digits;
380 : } NumericSumAccum;
381 :
382 :
383 : /*
384 : * We define our own macros for packing and unpacking abbreviated-key
385 : * representations for numeric values in order to avoid depending on
386 : * USE_FLOAT8_BYVAL. The type of abbreviation we use is based only on
387 : * the size of a datum, not the argument-passing convention for float8.
388 : *
389 : * The range of abbreviations for finite values is from +PG_INT64/32_MAX
390 : * to -PG_INT64/32_MAX. NaN has the abbreviation PG_INT64/32_MIN, and we
391 : * define the sort ordering to make that work out properly (see further
392 : * comments below). PINF and NINF share the abbreviations of the largest
393 : * and smallest finite abbreviation classes.
394 : */
395 : #define NUMERIC_ABBREV_BITS (SIZEOF_DATUM * BITS_PER_BYTE)
396 : #if SIZEOF_DATUM == 8
397 : #define NumericAbbrevGetDatum(X) ((Datum) (X))
398 : #define DatumGetNumericAbbrev(X) ((int64) (X))
399 : #define NUMERIC_ABBREV_NAN NumericAbbrevGetDatum(PG_INT64_MIN)
400 : #define NUMERIC_ABBREV_PINF NumericAbbrevGetDatum(-PG_INT64_MAX)
401 : #define NUMERIC_ABBREV_NINF NumericAbbrevGetDatum(PG_INT64_MAX)
402 : #else
403 : #define NumericAbbrevGetDatum(X) ((Datum) (X))
404 : #define DatumGetNumericAbbrev(X) ((int32) (X))
405 : #define NUMERIC_ABBREV_NAN NumericAbbrevGetDatum(PG_INT32_MIN)
406 : #define NUMERIC_ABBREV_PINF NumericAbbrevGetDatum(-PG_INT32_MAX)
407 : #define NUMERIC_ABBREV_NINF NumericAbbrevGetDatum(PG_INT32_MAX)
408 : #endif
409 :
410 :
411 : /* ----------
412 : * Some preinitialized constants
413 : * ----------
414 : */
415 : static const NumericDigit const_zero_data[1] = {0};
416 : static const NumericVar const_zero =
417 : {0, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_zero_data};
418 :
419 : static const NumericDigit const_one_data[1] = {1};
420 : static const NumericVar const_one =
421 : {1, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_one_data};
422 :
423 : static const NumericVar const_minus_one =
424 : {1, 0, NUMERIC_NEG, 0, NULL, (NumericDigit *) const_one_data};
425 :
426 : static const NumericDigit const_two_data[1] = {2};
427 : static const NumericVar const_two =
428 : {1, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_two_data};
429 :
430 : #if DEC_DIGITS == 4
431 : static const NumericDigit const_zero_point_nine_data[1] = {9000};
432 : #elif DEC_DIGITS == 2
433 : static const NumericDigit const_zero_point_nine_data[1] = {90};
434 : #elif DEC_DIGITS == 1
435 : static const NumericDigit const_zero_point_nine_data[1] = {9};
436 : #endif
437 : static const NumericVar const_zero_point_nine =
438 : {1, -1, NUMERIC_POS, 1, NULL, (NumericDigit *) const_zero_point_nine_data};
439 :
440 : #if DEC_DIGITS == 4
441 : static const NumericDigit const_one_point_one_data[2] = {1, 1000};
442 : #elif DEC_DIGITS == 2
443 : static const NumericDigit const_one_point_one_data[2] = {1, 10};
444 : #elif DEC_DIGITS == 1
445 : static const NumericDigit const_one_point_one_data[2] = {1, 1};
446 : #endif
447 : static const NumericVar const_one_point_one =
448 : {2, 0, NUMERIC_POS, 1, NULL, (NumericDigit *) const_one_point_one_data};
449 :
450 : static const NumericVar const_nan =
451 : {0, 0, NUMERIC_NAN, 0, NULL, NULL};
452 :
453 : static const NumericVar const_pinf =
454 : {0, 0, NUMERIC_PINF, 0, NULL, NULL};
455 :
456 : static const NumericVar const_ninf =
457 : {0, 0, NUMERIC_NINF, 0, NULL, NULL};
458 :
459 : #if DEC_DIGITS == 4
460 : static const int round_powers[4] = {0, 1000, 100, 10};
461 : #endif
462 :
463 :
464 : /* ----------
465 : * Local functions
466 : * ----------
467 : */
468 :
469 : #ifdef NUMERIC_DEBUG
470 : static void dump_numeric(const char *str, Numeric num);
471 : static void dump_var(const char *str, NumericVar *var);
472 : #else
473 : #define dump_numeric(s,n)
474 : #define dump_var(s,v)
475 : #endif
476 :
477 : #define digitbuf_alloc(ndigits) \
478 : ((NumericDigit *) palloc((ndigits) * sizeof(NumericDigit)))
479 : #define digitbuf_free(buf) \
480 : do { \
481 : if ((buf) != NULL) \
482 : pfree(buf); \
483 : } while (0)
484 :
485 : #define init_var(v) memset(v, 0, sizeof(NumericVar))
486 :
487 : #define NUMERIC_DIGITS(num) (NUMERIC_HEADER_IS_SHORT(num) ? \
488 : (num)->choice.n_short.n_data : (num)->choice.n_long.n_data)
489 : #define NUMERIC_NDIGITS(num) \
490 : ((VARSIZE(num) - NUMERIC_HEADER_SIZE(num)) / sizeof(NumericDigit))
491 : #define NUMERIC_CAN_BE_SHORT(scale,weight) \
492 : ((scale) <= NUMERIC_SHORT_DSCALE_MAX && \
493 : (weight) <= NUMERIC_SHORT_WEIGHT_MAX && \
494 : (weight) >= NUMERIC_SHORT_WEIGHT_MIN)
495 :
496 : static void alloc_var(NumericVar *var, int ndigits);
497 : static void free_var(NumericVar *var);
498 : static void zero_var(NumericVar *var);
499 :
500 : static bool set_var_from_str(const char *str, const char *cp,
501 : NumericVar *dest, const char **endptr,
502 : Node *escontext);
503 : static bool set_var_from_non_decimal_integer_str(const char *str,
504 : const char *cp, int sign,
505 : int base, NumericVar *dest,
506 : const char **endptr,
507 : Node *escontext);
508 : static void set_var_from_num(Numeric num, NumericVar *dest);
509 : static void init_var_from_num(Numeric num, NumericVar *dest);
510 : static void set_var_from_var(const NumericVar *value, NumericVar *dest);
511 : static char *get_str_from_var(const NumericVar *var);
512 : static char *get_str_from_var_sci(const NumericVar *var, int rscale);
513 :
514 : static void numericvar_serialize(StringInfo buf, const NumericVar *var);
515 : static void numericvar_deserialize(StringInfo buf, NumericVar *var);
516 :
517 : static Numeric duplicate_numeric(Numeric num);
518 : static Numeric make_result(const NumericVar *var);
519 : static Numeric make_result_opt_error(const NumericVar *var, bool *have_error);
520 :
521 : static bool apply_typmod(NumericVar *var, int32 typmod, Node *escontext);
522 : static bool apply_typmod_special(Numeric num, int32 typmod, Node *escontext);
523 :
524 : static bool numericvar_to_int32(const NumericVar *var, int32 *result);
525 : static bool numericvar_to_int64(const NumericVar *var, int64 *result);
526 : static void int64_to_numericvar(int64 val, NumericVar *var);
527 : static bool numericvar_to_uint64(const NumericVar *var, uint64 *result);
528 : #ifdef HAVE_INT128
529 : static bool numericvar_to_int128(const NumericVar *var, int128 *result);
530 : static void int128_to_numericvar(int128 val, NumericVar *var);
531 : #endif
532 : static double numericvar_to_double_no_overflow(const NumericVar *var);
533 :
534 : static Datum numeric_abbrev_convert(Datum original_datum, SortSupport ssup);
535 : static bool numeric_abbrev_abort(int memtupcount, SortSupport ssup);
536 : static int numeric_fast_cmp(Datum x, Datum y, SortSupport ssup);
537 : static int numeric_cmp_abbrev(Datum x, Datum y, SortSupport ssup);
538 :
539 : static Datum numeric_abbrev_convert_var(const NumericVar *var,
540 : NumericSortSupport *nss);
541 :
542 : static int cmp_numerics(Numeric num1, Numeric num2);
543 : static int cmp_var(const NumericVar *var1, const NumericVar *var2);
544 : static int cmp_var_common(const NumericDigit *var1digits, int var1ndigits,
545 : int var1weight, int var1sign,
546 : const NumericDigit *var2digits, int var2ndigits,
547 : int var2weight, int var2sign);
548 : static void add_var(const NumericVar *var1, const NumericVar *var2,
549 : NumericVar *result);
550 : static void sub_var(const NumericVar *var1, const NumericVar *var2,
551 : NumericVar *result);
552 : static void mul_var(const NumericVar *var1, const NumericVar *var2,
553 : NumericVar *result,
554 : int rscale);
555 : static void div_var(const NumericVar *var1, const NumericVar *var2,
556 : NumericVar *result,
557 : int rscale, bool round);
558 : static void div_var_fast(const NumericVar *var1, const NumericVar *var2,
559 : NumericVar *result, int rscale, bool round);
560 : static void div_var_int(const NumericVar *var, int ival, int ival_weight,
561 : NumericVar *result, int rscale, bool round);
562 : #ifdef HAVE_INT128
563 : static void div_var_int64(const NumericVar *var, int64 ival, int ival_weight,
564 : NumericVar *result, int rscale, bool round);
565 : #endif
566 : static int select_div_scale(const NumericVar *var1, const NumericVar *var2);
567 : static void mod_var(const NumericVar *var1, const NumericVar *var2,
568 : NumericVar *result);
569 : static void div_mod_var(const NumericVar *var1, const NumericVar *var2,
570 : NumericVar *quot, NumericVar *rem);
571 : static void ceil_var(const NumericVar *var, NumericVar *result);
572 : static void floor_var(const NumericVar *var, NumericVar *result);
573 :
574 : static void gcd_var(const NumericVar *var1, const NumericVar *var2,
575 : NumericVar *result);
576 : static void sqrt_var(const NumericVar *arg, NumericVar *result, int rscale);
577 : static void exp_var(const NumericVar *arg, NumericVar *result, int rscale);
578 : static int estimate_ln_dweight(const NumericVar *var);
579 : static void ln_var(const NumericVar *arg, NumericVar *result, int rscale);
580 : static void log_var(const NumericVar *base, const NumericVar *num,
581 : NumericVar *result);
582 : static void power_var(const NumericVar *base, const NumericVar *exp,
583 : NumericVar *result);
584 : static void power_var_int(const NumericVar *base, int exp, int exp_dscale,
585 : NumericVar *result);
586 : static void power_ten_int(int exp, NumericVar *result);
587 :
588 : static int cmp_abs(const NumericVar *var1, const NumericVar *var2);
589 : static int cmp_abs_common(const NumericDigit *var1digits, int var1ndigits,
590 : int var1weight,
591 : const NumericDigit *var2digits, int var2ndigits,
592 : int var2weight);
593 : static void add_abs(const NumericVar *var1, const NumericVar *var2,
594 : NumericVar *result);
595 : static void sub_abs(const NumericVar *var1, const NumericVar *var2,
596 : NumericVar *result);
597 : static void round_var(NumericVar *var, int rscale);
598 : static void trunc_var(NumericVar *var, int rscale);
599 : static void strip_var(NumericVar *var);
600 : static void compute_bucket(Numeric operand, Numeric bound1, Numeric bound2,
601 : const NumericVar *count_var, bool reversed_bounds,
602 : NumericVar *result_var);
603 :
604 : static void accum_sum_add(NumericSumAccum *accum, const NumericVar *val);
605 : static void accum_sum_rescale(NumericSumAccum *accum, const NumericVar *val);
606 : static void accum_sum_carry(NumericSumAccum *accum);
607 : static void accum_sum_reset(NumericSumAccum *accum);
608 : static void accum_sum_final(NumericSumAccum *accum, NumericVar *result);
609 : static void accum_sum_copy(NumericSumAccum *dst, NumericSumAccum *src);
610 : static void accum_sum_combine(NumericSumAccum *accum, NumericSumAccum *accum2);
611 :
612 :
613 : /* ----------------------------------------------------------------------
614 : *
615 : * Input-, output- and rounding-functions
616 : *
617 : * ----------------------------------------------------------------------
618 : */
619 :
620 :
621 : /*
622 : * numeric_in() -
623 : *
624 : * Input function for numeric data type
625 : */
626 : Datum
8335 tgl 627 GIC 47288 : numeric_in(PG_FUNCTION_ARGS)
628 : {
629 47288 : char *str = PG_GETARG_CSTRING(0);
630 : #ifdef NOT_USED
631 : Oid typelem = PG_GETARG_OID(1);
632 : #endif
633 47288 : int32 typmod = PG_GETARG_INT32(2);
121 tgl 634 GNC 47288 : Node *escontext = fcinfo->context;
635 : Numeric res;
636 : const char *cp;
637 : const char *numstart;
638 : int sign;
5114 tgl 639 ECB :
640 : /* Skip leading spaces */
5114 tgl 641 CBC 47288 : cp = str;
5114 tgl 642 GIC 47480 : while (*cp)
643 : {
644 47474 : if (!isspace((unsigned char) *cp))
5114 tgl 645 CBC 47282 : break;
646 192 : cp++;
647 : }
648 :
649 : /*
650 : * Process the number's sign. This duplicates logic in set_var_from_str(),
651 : * but it's worth doing here, since it simplifies the handling of
652 : * infinities and non-decimal integers.
653 : */
76 dean.a.rasheed 654 GNC 47288 : numstart = cp;
655 47288 : sign = NUMERIC_POS;
656 :
657 47288 : if (*cp == '+')
658 18 : cp++;
659 47270 : else if (*cp == '-')
660 : {
661 1727 : sign = NUMERIC_NEG;
662 1727 : cp++;
663 : }
664 :
665 : /*
666 : * Check for NaN and infinities. We recognize the same strings allowed by
667 : * float8in().
668 : *
669 : * Since all other legal inputs have a digit or a decimal point after the
670 : * sign, we need only check for NaN/infinity if that's not the case.
671 : */
672 47288 : if (!isdigit((unsigned char) *cp) && *cp != '.')
673 : {
76 dean.a.rasheed 674 ECB : /*
675 : * The number must be NaN or infinity; anything else can only be a
676 : * syntax error. Note that NaN mustn't have a sign.
677 : */
76 dean.a.rasheed 678 GNC 722 : if (pg_strncasecmp(numstart, "NaN", 3) == 0)
679 : {
680 271 : res = make_result(&const_nan);
681 271 : cp = numstart + 3;
682 : }
683 451 : else if (pg_strncasecmp(cp, "Infinity", 8) == 0)
684 : {
685 156 : res = make_result(sign == NUMERIC_POS ? &const_pinf : &const_ninf);
686 156 : cp += 8;
687 : }
688 295 : else if (pg_strncasecmp(cp, "inf", 3) == 0)
689 : {
690 264 : res = make_result(sign == NUMERIC_POS ? &const_pinf : &const_ninf);
691 264 : cp += 3;
692 : }
693 : else
694 31 : goto invalid_syntax;
76 dean.a.rasheed 695 ECB :
696 : /*
697 : * Check for trailing junk; there should be nothing left but spaces.
698 : *
699 : * We intentionally do this check before applying the typmod because
700 : * we would like to throw any trailing-junk syntax error before any
701 : * semantic error resulting from apply_typmod_special().
702 : */
76 dean.a.rasheed 703 GIC 712 : while (*cp)
76 dean.a.rasheed 704 ECB : {
76 dean.a.rasheed 705 GIC 21 : if (!isspace((unsigned char) *cp))
76 dean.a.rasheed 706 UNC 0 : goto invalid_syntax;
76 dean.a.rasheed 707 GIC 21 : cp++;
708 : }
709 :
76 dean.a.rasheed 710 GNC 691 : if (!apply_typmod_special(res, typmod, escontext))
76 dean.a.rasheed 711 UNC 0 : PG_RETURN_NULL();
712 : }
713 : else
714 : {
715 : /*
716 : * We have a normal numeric value, which may be a non-decimal integer
717 : * or a regular decimal number.
718 : */
719 : NumericVar value;
720 : int base;
721 : bool have_error;
722 :
5114 tgl 723 GNC 46566 : init_var(&value);
724 :
725 : /*
726 : * Determine the number's base by looking for a non-decimal prefix
727 : * indicator ("0x", "0o", or "0b").
728 : */
76 dean.a.rasheed 729 46566 : if (cp[0] == '0')
730 : {
731 12837 : switch (cp[1])
732 : {
733 36 : case 'x':
734 : case 'X':
735 36 : base = 16;
736 36 : break;
737 21 : case 'o':
738 : case 'O':
739 21 : base = 8;
740 21 : break;
741 21 : case 'b':
742 : case 'B':
743 21 : base = 2;
744 21 : break;
745 12759 : default:
746 12759 : base = 10;
747 : }
748 : }
749 : else
750 33729 : base = 10;
751 :
752 : /* Parse the rest of the number and apply the sign */
753 46566 : if (base == 10)
754 : {
755 46488 : if (!set_var_from_str(str, cp, &value, &cp, escontext))
756 15 : PG_RETURN_NULL();
757 46464 : value.sign = sign;
758 : }
759 : else
760 : {
761 78 : if (!set_var_from_non_decimal_integer_str(str, cp + 2, sign, base,
762 : &value, &cp, escontext))
76 dean.a.rasheed 763 UNC 0 : PG_RETURN_NULL();
764 : }
765 :
766 : /*
767 : * Should be nothing left but spaces. As above, throw any typmod error
768 : * after finishing syntax check.
769 : */
5114 tgl 770 GNC 46572 : while (*cp)
771 : {
772 69 : if (!isspace((unsigned char) *cp))
76 dean.a.rasheed 773 30 : goto invalid_syntax;
5114 tgl 774 39 : cp++;
775 : }
776 :
121 777 46503 : if (!apply_typmod(&value, typmod, escontext))
778 6 : PG_RETURN_NULL();
779 :
780 46497 : res = make_result_opt_error(&value, &have_error);
781 :
782 46497 : if (have_error)
783 9 : ereturn(escontext, (Datum) 0,
784 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
785 : errmsg("value overflows numeric format")));
786 :
5114 787 46488 : free_var(&value);
788 : }
789 :
8335 tgl 790 GIC 47179 : PG_RETURN_NUMERIC(res);
791 :
76 dean.a.rasheed 792 GNC 61 : invalid_syntax:
793 61 : ereturn(escontext, (Datum) 0,
794 : (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
795 : errmsg("invalid input syntax for type %s: \"%s\"",
796 : "numeric", str)));
797 : }
798 :
799 :
7324 tgl 800 ECB : /*
801 : * numeric_out() -
8866 JanWieck 802 : *
803 : * Output function for numeric data type
804 : */
805 : Datum
8335 tgl 806 CBC 389247 : numeric_out(PG_FUNCTION_ARGS)
8866 JanWieck 807 ECB : {
8335 tgl 808 CBC 389247 : Numeric num = PG_GETARG_NUMERIC(0);
809 : NumericVar x;
8482 tgl 810 ECB : char *str;
8866 JanWieck 811 :
8053 bruce 812 : /*
813 : * Handle NaN and infinities
8866 JanWieck 814 : */
991 tgl 815 CBC 389247 : if (NUMERIC_IS_SPECIAL(num))
991 tgl 816 ECB : {
991 tgl 817 CBC 1698 : if (NUMERIC_IS_PINF(num))
991 tgl 818 GIC 478 : PG_RETURN_CSTRING(pstrdup("Infinity"));
819 1220 : else if (NUMERIC_IS_NINF(num))
820 287 : PG_RETURN_CSTRING(pstrdup("-Infinity"));
991 tgl 821 ECB : else
991 tgl 822 GIC 933 : PG_RETURN_CSTRING(pstrdup("NaN"));
823 : }
8866 JanWieck 824 ECB :
825 : /*
8485 tgl 826 : * Get the number in the variable format.
8866 JanWieck 827 : */
3791 heikki.linnakangas 828 CBC 387549 : init_var_from_num(num, &x);
829 :
3791 heikki.linnakangas 830 GIC 387549 : str = get_str_from_var(&x);
831 :
8335 tgl 832 CBC 387549 : PG_RETURN_CSTRING(str);
833 : }
8866 JanWieck 834 EUB :
835 : /*
836 : * numeric_is_nan() -
837 : *
838 : * Is Numeric value a NaN?
839 : */
840 : bool
4636 rhaas 841 CBC 6547 : numeric_is_nan(Numeric num)
842 : {
843 6547 : return NUMERIC_IS_NAN(num);
4636 rhaas 844 ECB : }
845 :
846 : /*
847 : * numeric_is_inf() -
991 tgl 848 : *
849 : * Is Numeric value an infinity?
850 : */
851 : bool
991 tgl 852 GIC 15 : numeric_is_inf(Numeric num)
991 tgl 853 ECB : {
991 tgl 854 CBC 15 : return NUMERIC_IS_INF(num);
855 : }
856 :
857 : /*
991 tgl 858 ECB : * numeric_is_integral() -
859 : *
860 : * Is Numeric value integral?
861 : */
862 : static bool
991 tgl 863 CBC 33 : numeric_is_integral(Numeric num)
991 tgl 864 ECB : {
865 : NumericVar arg;
866 :
867 : /* Reject NaN, but infinities are considered integral */
991 tgl 868 GIC 33 : if (NUMERIC_IS_SPECIAL(num))
869 : {
870 15 : if (NUMERIC_IS_NAN(num))
991 tgl 871 UIC 0 : return false;
991 tgl 872 GIC 15 : return true;
873 : }
874 :
875 : /* Integral if there are no digits to the right of the decimal point */
876 18 : init_var_from_num(num, &arg);
991 tgl 877 ECB :
991 tgl 878 GIC 18 : return (arg.ndigits == 0 || arg.ndigits <= arg.weight + 1);
991 tgl 879 ECB : }
880 :
881 : /*
882 : * make_numeric_typmod() -
883 : *
884 : * Pack numeric precision and scale values into a typmod. The upper 16 bits
885 : * are used for the precision (though actually not all these bits are needed,
622 dean.a.rasheed 886 : * since the maximum allowed precision is 1000). The lower 16 bits are for
887 : * the scale, but since the scale is constrained to the range [-1000, 1000],
888 : * we use just the lower 11 of those 16 bits, and leave the remaining 5 bits
889 : * unset, for possible future use.
890 : *
891 : * For purely historical reasons VARHDRSZ is then added to the result, thus
892 : * the unused space in the upper 16 bits is not all as freely available as it
893 : * might seem. (We can't let the result overflow to a negative int32, as
894 : * other parts of the system would interpret that as not-a-valid-typmod.)
895 : */
896 : static inline int32
622 dean.a.rasheed 897 GIC 905 : make_numeric_typmod(int precision, int scale)
898 : {
622 dean.a.rasheed 899 CBC 905 : return ((precision << 16) | (scale & 0x7ff)) + VARHDRSZ;
900 : }
622 dean.a.rasheed 901 ECB :
902 : /*
903 : * Because of the offset, valid numeric typmods are at least VARHDRSZ
904 : */
905 : static inline bool
622 dean.a.rasheed 906 GIC 59150 : is_valid_numeric_typmod(int32 typmod)
907 : {
908 59150 : return typmod >= (int32) VARHDRSZ;
909 : }
910 :
911 : /*
622 dean.a.rasheed 912 ECB : * numeric_typmod_precision() -
913 : *
914 : * Extract the precision from a numeric typmod --- see make_numeric_typmod().
915 : */
916 : static inline int
622 dean.a.rasheed 917 GIC 12269 : numeric_typmod_precision(int32 typmod)
918 : {
919 12269 : return ((typmod - VARHDRSZ) >> 16) & 0xffff;
920 : }
921 :
922 : /*
622 dean.a.rasheed 923 ECB : * numeric_typmod_scale() -
924 : *
925 : * Extract the scale from a numeric typmod --- see make_numeric_typmod().
926 : *
927 : * Note that the scale may be negative, so we must do sign extension when
928 : * unpacking it. We do this using the bit hack (x^1024)-1024, which sign
929 : * extends an 11-bit two's complement number x.
930 : */
931 : static inline int
622 dean.a.rasheed 932 GIC 8503 : numeric_typmod_scale(int32 typmod)
933 : {
622 dean.a.rasheed 934 CBC 8503 : return (((typmod - VARHDRSZ) & 0x7ff) ^ 1024) - 1024;
935 : }
936 :
937 : /*
938 : * numeric_maximum_size() -
4636 rhaas 939 ECB : *
940 : * Maximum size of a numeric with given typmod, or -1 if unlimited/unknown.
941 : */
4636 rhaas 942 EUB : int32
4631 rhaas 943 CBC 3766 : numeric_maximum_size(int32 typmod)
944 : {
945 : int precision;
946 : int numeric_digits;
4636 rhaas 947 ECB :
622 dean.a.rasheed 948 GIC 3766 : if (!is_valid_numeric_typmod(typmod))
4636 rhaas 949 LBC 0 : return -1;
950 :
951 : /* precision (ie, max # of digits) is in upper bits of typmod */
622 dean.a.rasheed 952 GIC 3766 : precision = numeric_typmod_precision(typmod);
953 :
954 : /*
955 : * This formula computes the maximum number of NumericDigits we could need
956 : * in order to store the specified number of decimal digits. Because the
957 : * weight is stored as a number of NumericDigits rather than a number of
958 : * decimal digits, it's possible that the first NumericDigit will contain
959 : * only a single decimal digit. Thus, the first two decimal digits can
960 : * require two NumericDigits to store, but it isn't until we reach
961 : * DEC_DIGITS + 2 decimal digits that we potentially need a third
962 : * NumericDigit.
963 : */
4631 rhaas 964 3766 : numeric_digits = (precision + 2 * (DEC_DIGITS - 1)) / DEC_DIGITS;
965 :
966 : /*
967 : * In most cases, the size of a numeric will be smaller than the value
4631 rhaas 968 ECB : * computed below, because the varlena header will typically get toasted
969 : * down to a single byte before being stored on disk, and it may also be
3260 bruce 970 : * possible to use a short numeric header. But our job here is to compute
971 : * the worst case.
972 : */
4631 rhaas 973 GIC 3766 : return NUMERIC_HDRSZ + (numeric_digits * sizeof(NumericDigit));
974 : }
975 :
976 : /*
4990 tgl 977 ECB : * numeric_out_sci() -
978 : *
979 : * Output function for numeric data type in scientific notation.
980 : */
981 : char *
4990 tgl 982 GIC 117 : numeric_out_sci(Numeric num, int scale)
983 : {
984 : NumericVar x;
985 : char *str;
986 :
987 : /*
991 tgl 988 ECB : * Handle NaN and infinities
989 : */
991 tgl 990 CBC 117 : if (NUMERIC_IS_SPECIAL(num))
991 : {
991 tgl 992 GIC 9 : if (NUMERIC_IS_PINF(num))
993 3 : return pstrdup("Infinity");
994 6 : else if (NUMERIC_IS_NINF(num))
995 3 : return pstrdup("-Infinity");
996 : else
997 3 : return pstrdup("NaN");
998 : }
999 :
3791 heikki.linnakangas 1000 108 : init_var_from_num(num, &x);
1001 :
4990 tgl 1002 108 : str = get_str_from_var_sci(&x, scale);
4990 tgl 1003 ECB :
4990 tgl 1004 GIC 108 : return str;
4990 tgl 1005 ECB : }
1006 :
1007 : /*
1008 : * numeric_normalize() -
1009 : *
1010 : * Output function for numeric data type, suppressing insignificant trailing
1011 : * zeroes and then any trailing decimal point. The intent of this is to
1012 : * produce strings that are equal if and only if the input numeric values
1013 : * compare equal.
3304 andrew 1014 : */
1015 : char *
3304 andrew 1016 GIC 4983 : numeric_normalize(Numeric num)
1017 : {
1018 : NumericVar x;
3304 andrew 1019 ECB : char *str;
3076 tgl 1020 EUB : int last;
1021 :
1022 : /*
991 tgl 1023 ECB : * Handle NaN and infinities
1024 : */
991 tgl 1025 GIC 4983 : if (NUMERIC_IS_SPECIAL(num))
1026 : {
991 tgl 1027 UIC 0 : if (NUMERIC_IS_PINF(num))
1028 0 : return pstrdup("Infinity");
1029 0 : else if (NUMERIC_IS_NINF(num))
1030 0 : return pstrdup("-Infinity");
1031 : else
1032 0 : return pstrdup("NaN");
1033 : }
1034 :
3304 andrew 1035 CBC 4983 : init_var_from_num(num, &x);
1036 :
3304 andrew 1037 GIC 4983 : str = get_str_from_var(&x);
1038 :
1039 : /* If there's no decimal point, there's certainly nothing to remove. */
3076 tgl 1040 4983 : if (strchr(str, '.') != NULL)
1041 : {
1042 : /*
1043 : * Back up over trailing fractional zeroes. Since there is a decimal
3076 tgl 1044 ECB : * point, this loop will terminate safely.
1045 : */
3076 tgl 1046 GIC 21 : last = strlen(str) - 1;
1047 42 : while (str[last] == '0')
1048 21 : last--;
1049 :
1050 : /* We want to get rid of the decimal point too, if it's now last. */
1051 21 : if (str[last] == '.')
1052 21 : last--;
3304 andrew 1053 ECB :
1054 : /* Delete whatever we backed up over. */
3076 tgl 1055 GIC 21 : str[last + 1] = '\0';
1056 : }
1057 :
3304 andrew 1058 4983 : return str;
1059 : }
1060 :
7272 tgl 1061 ECB : /*
1062 : * numeric_recv - converts external binary format to numeric
1063 : *
1064 : * External format is a sequence of int16's:
1065 : * ndigits, weight, sign, dscale, NumericDigits.
1066 : */
1067 : Datum
7272 tgl 1068 CBC 51 : numeric_recv(PG_FUNCTION_ARGS)
1069 : {
7272 tgl 1070 GIC 51 : StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
6385 bruce 1071 ECB :
1072 : #ifdef NOT_USED
6482 tgl 1073 : Oid typelem = PG_GETARG_OID(1);
1074 : #endif
6482 tgl 1075 CBC 51 : int32 typmod = PG_GETARG_INT32(2);
1076 : NumericVar value;
1077 : Numeric res;
1078 : int len,
1079 : i;
1080 :
7272 tgl 1081 GIC 51 : init_var(&value);
1082 :
1083 51 : len = (uint16) pq_getmsgint(buf, sizeof(uint16));
1084 :
1085 51 : alloc_var(&value, len);
1086 :
7272 tgl 1087 CBC 51 : value.weight = (int16) pq_getmsgint(buf, sizeof(int16));
1088 : /* we allow any int16 for weight --- OK? */
1089 :
7272 tgl 1090 GIC 51 : value.sign = (uint16) pq_getmsgint(buf, sizeof(uint16));
1091 51 : if (!(value.sign == NUMERIC_POS ||
7272 tgl 1092 UIC 0 : value.sign == NUMERIC_NEG ||
991 1093 0 : value.sign == NUMERIC_NAN ||
1094 0 : value.sign == NUMERIC_PINF ||
1095 0 : value.sign == NUMERIC_NINF))
7196 tgl 1096 LBC 0 : ereport(ERROR,
1097 : (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
7132 peter_e 1098 EUB : errmsg("invalid sign in external \"numeric\" value")));
7196 tgl 1099 :
7272 tgl 1100 GBC 51 : value.dscale = (uint16) pq_getmsgint(buf, sizeof(uint16));
3051 1101 51 : if ((value.dscale & NUMERIC_DSCALE_MASK) != value.dscale)
3051 tgl 1102 UIC 0 : ereport(ERROR,
3051 tgl 1103 EUB : (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1104 : errmsg("invalid scale in external \"numeric\" value")));
1105 :
7272 tgl 1106 CBC 137 : for (i = 0; i < len; i++)
1107 : {
7188 bruce 1108 86 : NumericDigit d = pq_getmsgint(buf, sizeof(NumericDigit));
1109 :
7272 tgl 1110 GIC 86 : if (d < 0 || d >= NBASE)
7196 tgl 1111 LBC 0 : ereport(ERROR,
1112 : (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1113 : errmsg("invalid digit in external \"numeric\" value")));
7272 tgl 1114 GIC 86 : value.digits[i] = d;
1115 : }
1116 :
3051 tgl 1117 ECB : /*
1118 : * If the given dscale would hide any digits, truncate those digits away.
1119 : * We could alternatively throw an error, but that would take a bunch of
1120 : * extra code (about as much as trunc_var involves), and it might cause
1121 : * client compatibility issues. Be careful not to apply trunc_var to
991 1122 : * special values, as it could do the wrong thing; we don't need it
1123 : * anyway, since make_result will ignore all but the sign field.
1124 : *
1125 : * After doing that, be sure to check the typmod restriction.
3051 1126 : */
991 tgl 1127 GIC 51 : if (value.sign == NUMERIC_POS ||
991 tgl 1128 UIC 0 : value.sign == NUMERIC_NEG)
991 tgl 1129 ECB : {
991 tgl 1130 GIC 51 : trunc_var(&value, value.dscale);
1131 :
121 tgl 1132 GNC 51 : (void) apply_typmod(&value, typmod, NULL);
1133 :
991 tgl 1134 GIC 51 : res = make_result(&value);
1135 : }
1136 : else
1137 : {
1138 : /* apply_typmod_special wants us to make the Numeric first */
991 tgl 1139 LBC 0 : res = make_result(&value);
1140 :
121 tgl 1141 UNC 0 : (void) apply_typmod_special(res, typmod, NULL);
1142 : }
1143 :
7272 tgl 1144 GIC 51 : free_var(&value);
1145 :
7272 tgl 1146 CBC 51 : PG_RETURN_NUMERIC(res);
1147 : }
1148 :
1149 : /*
1150 : * numeric_send - converts numeric to binary format
1151 : */
7272 tgl 1152 ECB : Datum
7272 tgl 1153 GIC 35 : numeric_send(PG_FUNCTION_ARGS)
7272 tgl 1154 ECB : {
7272 tgl 1155 GIC 35 : Numeric num = PG_GETARG_NUMERIC(0);
7272 tgl 1156 ECB : NumericVar x;
1157 : StringInfoData buf;
1158 : int i;
1159 :
3791 heikki.linnakangas 1160 GIC 35 : init_var_from_num(num, &x);
7272 tgl 1161 ECB :
7272 tgl 1162 CBC 35 : pq_begintypsend(&buf);
7272 tgl 1163 EUB :
2006 andres 1164 GBC 35 : pq_sendint16(&buf, x.ndigits);
1165 35 : pq_sendint16(&buf, x.weight);
1166 35 : pq_sendint16(&buf, x.sign);
1167 35 : pq_sendint16(&buf, x.dscale);
7272 tgl 1168 GIC 97 : for (i = 0; i < x.ndigits; i++)
2006 andres 1169 62 : pq_sendint16(&buf, x.digits[i]);
1170 :
7272 tgl 1171 CBC 35 : PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
7272 tgl 1172 ECB : }
7272 tgl 1173 EUB :
1174 :
1175 : /*
1176 : * numeric_support()
4079 rhaas 1177 ECB : *
1178 : * Planner support function for the numeric() length coercion function.
1520 tgl 1179 : *
1180 : * Flatten calls that solely represent increases in allowable precision.
1181 : * Scale changes mutate every datum, so they are unoptimizable. Some values,
1520 tgl 1182 EUB : * e.g. 1E-1001, can only fit into an unconstrained numeric, so a change from
1183 : * an unconstrained numeric to any constrained numeric is also unoptimizable.
1184 : */
4079 rhaas 1185 ECB : Datum
1520 tgl 1186 GIC 258 : numeric_support(PG_FUNCTION_ARGS)
1187 : {
1188 258 : Node *rawreq = (Node *) PG_GETARG_POINTER(0);
4079 rhaas 1189 258 : Node *ret = NULL;
1190 :
1520 tgl 1191 258 : if (IsA(rawreq, SupportRequestSimplify))
1192 : {
1193 114 : SupportRequestSimplify *req = (SupportRequestSimplify *) rawreq;
1194 114 : FuncExpr *expr = req->fcall;
1195 : Node *typmod;
1196 :
1197 114 : Assert(list_length(expr->args) >= 2);
4079 rhaas 1198 ECB :
1520 tgl 1199 GBC 114 : typmod = (Node *) lsecond(expr->args);
1200 :
1058 tgl 1201 CBC 114 : if (IsA(typmod, Const) && !((Const *) typmod)->constisnull)
1202 : {
1520 1203 114 : Node *source = (Node *) linitial(expr->args);
1520 tgl 1204 GIC 114 : int32 old_typmod = exprTypmod(source);
1520 tgl 1205 CBC 114 : int32 new_typmod = DatumGetInt32(((Const *) typmod)->constvalue);
622 dean.a.rasheed 1206 GIC 114 : int32 old_scale = numeric_typmod_scale(old_typmod);
1207 114 : int32 new_scale = numeric_typmod_scale(new_typmod);
1208 114 : int32 old_precision = numeric_typmod_precision(old_typmod);
1209 114 : int32 new_precision = numeric_typmod_precision(new_typmod);
1520 tgl 1210 EUB :
1211 : /*
622 dean.a.rasheed 1212 : * If new_typmod is invalid, the destination is unconstrained;
1213 : * that's always OK. If old_typmod is valid, the source is
1214 : * constrained, and we're OK if the scale is unchanged and the
1520 tgl 1215 ECB : * precision is not decreasing. See further notes in function
1216 : * header comment.
1217 : */
622 dean.a.rasheed 1218 GIC 228 : if (!is_valid_numeric_typmod(new_typmod) ||
1219 120 : (is_valid_numeric_typmod(old_typmod) &&
1520 tgl 1220 3 : new_scale == old_scale && new_precision >= old_precision))
1221 3 : ret = relabel_to_typmod(source, new_typmod);
1222 : }
1223 : }
4079 rhaas 1224 ECB :
4079 rhaas 1225 GIC 258 : PG_RETURN_POINTER(ret);
4079 rhaas 1226 ECB : }
1227 :
1228 : /*
1229 : * numeric() -
1230 : *
8866 JanWieck 1231 : * This is a special function called by the Postgres database system
1232 : * before a value is stored in a tuple's attribute. The precision and
8720 bruce 1233 : * scale of the attribute have to be applied on the value.
1234 : */
8335 tgl 1235 : Datum
5624 bruce 1236 CBC 5880 : numeric (PG_FUNCTION_ARGS)
8866 JanWieck 1237 ECB : {
8335 tgl 1238 CBC 5880 : Numeric num = PG_GETARG_NUMERIC(0);
1239 5880 : int32 typmod = PG_GETARG_INT32(1);
8866 JanWieck 1240 ECB : Numeric new;
1241 : int precision;
1242 : int scale;
1243 : int ddigits;
1244 : int maxdigits;
1245 : int dscale;
1246 : NumericVar var;
1247 :
1248 : /*
1249 : * Handle NaN and infinities: if apply_typmod_special doesn't complain,
1250 : * just return a copy of the input.
1251 : */
991 tgl 1252 GIC 5880 : if (NUMERIC_IS_SPECIAL(num))
1253 : {
121 tgl 1254 GNC 105 : (void) apply_typmod_special(num, typmod, NULL);
991 tgl 1255 GIC 96 : PG_RETURN_NUMERIC(duplicate_numeric(num));
1256 : }
8866 JanWieck 1257 ECB :
1258 : /*
6385 bruce 1259 : * If the value isn't a valid type modifier, simply return a copy of the
1260 : * input value
1261 : */
622 dean.a.rasheed 1262 CBC 5775 : if (!is_valid_numeric_typmod(typmod))
991 tgl 1263 UIC 0 : PG_RETURN_NUMERIC(duplicate_numeric(num));
8866 JanWieck 1264 ECB :
8053 bruce 1265 : /*
1266 : * Get the precision and scale out of the typmod value
1267 : */
622 dean.a.rasheed 1268 CBC 5775 : precision = numeric_typmod_precision(typmod);
622 dean.a.rasheed 1269 GIC 5775 : scale = numeric_typmod_scale(typmod);
7324 tgl 1270 CBC 5775 : maxdigits = precision - scale;
1271 :
622 dean.a.rasheed 1272 ECB : /* The target display scale is non-negative */
622 dean.a.rasheed 1273 GIC 5775 : dscale = Max(scale, 0);
622 dean.a.rasheed 1274 ECB :
8053 bruce 1275 : /*
7324 tgl 1276 : * If the number is certainly in bounds and due to the target scale no
6385 bruce 1277 : * rounding could be necessary, just make a copy of the input and modify
4632 rhaas 1278 : * its scale fields, unless the larger scale forces us to abandon the
4382 bruce 1279 : * short representation. (Note we assume the existing dscale is
1280 : * honest...)
1281 : */
4632 rhaas 1282 GIC 5775 : ddigits = (NUMERIC_WEIGHT(num) + 1) * DEC_DIGITS;
1283 5775 : if (ddigits <= maxdigits && scale >= NUMERIC_DSCALE(num)
622 dean.a.rasheed 1284 3565 : && (NUMERIC_CAN_BE_SHORT(dscale, NUMERIC_WEIGHT(num))
4382 bruce 1285 UIC 0 : || !NUMERIC_IS_SHORT(num)))
1286 : {
991 tgl 1287 GIC 3565 : new = duplicate_numeric(num);
4632 rhaas 1288 3565 : if (NUMERIC_IS_SHORT(num))
4632 rhaas 1289 CBC 3565 : new->choice.n_short.n_header =
1290 3565 : (num->choice.n_short.n_header & ~NUMERIC_SHORT_DSCALE_MASK)
622 dean.a.rasheed 1291 3565 : | (dscale << NUMERIC_SHORT_DSCALE_SHIFT);
4632 rhaas 1292 ECB : else
4632 rhaas 1293 UIC 0 : new->choice.n_long.n_sign_dscale = NUMERIC_SIGN(new) |
622 dean.a.rasheed 1294 0 : ((uint16) dscale & NUMERIC_DSCALE_MASK);
8335 tgl 1295 GIC 3565 : PG_RETURN_NUMERIC(new);
8866 JanWieck 1296 ECB : }
1297 :
1298 : /*
1299 : * We really need to fiddle with things - unpack the number into a
1300 : * variable and let apply_typmod() do it.
1301 : */
8866 JanWieck 1302 GIC 2210 : init_var(&var);
1303 :
1304 2210 : set_var_from_num(num, &var);
121 tgl 1305 GNC 2210 : (void) apply_typmod(&var, typmod, NULL);
8866 JanWieck 1306 GIC 2180 : new = make_result(&var);
8866 JanWieck 1307 ECB :
8866 JanWieck 1308 GIC 2180 : free_var(&var);
8866 JanWieck 1309 ECB :
8335 tgl 1310 CBC 2180 : PG_RETURN_NUMERIC(new);
1311 : }
1312 :
1313 : Datum
5944 tgl 1314 GIC 911 : numerictypmodin(PG_FUNCTION_ARGS)
1315 : {
5624 bruce 1316 911 : ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
1317 : int32 *tl;
1318 : int n;
1319 : int32 typmod;
1320 :
5777 tgl 1321 911 : tl = ArrayGetIntegerTypmods(ta, &n);
1322 :
5944 tgl 1323 CBC 911 : if (n == 2)
1324 : {
1325 903 : if (tl[0] < 1 || tl[0] > NUMERIC_MAX_PRECISION)
5944 tgl 1326 LBC 0 : ereport(ERROR,
1327 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1328 : errmsg("NUMERIC precision %d must be between 1 and %d",
1329 : tl[0], NUMERIC_MAX_PRECISION)));
622 dean.a.rasheed 1330 GIC 903 : if (tl[1] < NUMERIC_MIN_SCALE || tl[1] > NUMERIC_MAX_SCALE)
5944 tgl 1331 UIC 0 : ereport(ERROR,
1332 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
622 dean.a.rasheed 1333 ECB : errmsg("NUMERIC scale %d must be between %d and %d",
622 dean.a.rasheed 1334 EUB : tl[1], NUMERIC_MIN_SCALE, NUMERIC_MAX_SCALE)));
622 dean.a.rasheed 1335 GIC 903 : typmod = make_numeric_typmod(tl[0], tl[1]);
1336 : }
5944 tgl 1337 8 : else if (n == 1)
1338 : {
5944 tgl 1339 CBC 2 : if (tl[0] < 1 || tl[0] > NUMERIC_MAX_PRECISION)
5944 tgl 1340 LBC 0 : ereport(ERROR,
5944 tgl 1341 ECB : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1342 : errmsg("NUMERIC precision %d must be between 1 and %d",
1343 : tl[0], NUMERIC_MAX_PRECISION)));
1344 : /* scale defaults to zero */
622 dean.a.rasheed 1345 GIC 2 : typmod = make_numeric_typmod(tl[0], 0);
1346 : }
1347 : else
1348 : {
5944 tgl 1349 6 : ereport(ERROR,
1350 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1351 : errmsg("invalid NUMERIC type modifier")));
1352 : typmod = 0; /* keep compiler quiet */
5944 tgl 1353 ECB : }
1354 :
5944 tgl 1355 CBC 905 : PG_RETURN_INT32(typmod);
5944 tgl 1356 EUB : }
1357 :
5944 tgl 1358 ECB : Datum
5944 tgl 1359 CBC 188 : numerictypmodout(PG_FUNCTION_ARGS)
5944 tgl 1360 ECB : {
5624 bruce 1361 CBC 188 : int32 typmod = PG_GETARG_INT32(0);
1362 188 : char *res = (char *) palloc(64);
1363 :
622 dean.a.rasheed 1364 GBC 188 : if (is_valid_numeric_typmod(typmod))
5944 tgl 1365 188 : snprintf(res, 64, "(%d,%d)",
622 dean.a.rasheed 1366 ECB : numeric_typmod_precision(typmod),
1367 : numeric_typmod_scale(typmod));
1368 : else
5944 tgl 1369 UIC 0 : *res = '\0';
1370 :
5944 tgl 1371 GIC 188 : PG_RETURN_CSTRING(res);
1372 : }
5944 tgl 1373 ECB :
1374 :
8866 JanWieck 1375 : /* ----------------------------------------------------------------------
1376 : *
8445 tgl 1377 : * Sign manipulation, rounding and the like
1378 : *
8866 JanWieck 1379 : * ----------------------------------------------------------------------
1380 : */
1381 :
1382 : Datum
8289 tgl 1383 GIC 630 : numeric_abs(PG_FUNCTION_ARGS)
1384 : {
8289 tgl 1385 CBC 630 : Numeric num = PG_GETARG_NUMERIC(0);
1386 : Numeric res;
8866 JanWieck 1387 ECB :
1388 : /*
1389 : * Do it the easy way directly on the packed format
1390 : */
991 tgl 1391 GIC 630 : res = duplicate_numeric(num);
8866 JanWieck 1392 ECB :
4632 rhaas 1393 GIC 630 : if (NUMERIC_IS_SHORT(num))
4632 rhaas 1394 CBC 597 : res->choice.n_short.n_header =
4632 rhaas 1395 GIC 597 : num->choice.n_short.n_header & ~NUMERIC_SHORT_SIGN_MASK;
991 tgl 1396 CBC 33 : else if (NUMERIC_IS_SPECIAL(num))
991 tgl 1397 EUB : {
1398 : /* This changes -Inf to Inf, and doesn't affect NaN */
991 tgl 1399 GIC 9 : res->choice.n_short.n_header =
1400 9 : num->choice.n_short.n_header & ~NUMERIC_INF_SIGN_MASK;
991 tgl 1401 ECB : }
4632 rhaas 1402 EUB : else
4632 rhaas 1403 GIC 24 : res->choice.n_long.n_sign_dscale = NUMERIC_POS | NUMERIC_DSCALE(num);
1404 :
8289 tgl 1405 630 : PG_RETURN_NUMERIC(res);
8866 JanWieck 1406 ECB : }
1407 :
1408 :
1409 : Datum
8289 tgl 1410 CBC 427 : numeric_uminus(PG_FUNCTION_ARGS)
8445 tgl 1411 EUB : {
8289 tgl 1412 GIC 427 : Numeric num = PG_GETARG_NUMERIC(0);
1413 : Numeric res;
1414 :
1415 : /*
8445 tgl 1416 ECB : * Do it the easy way directly on the packed format
1417 : */
991 tgl 1418 GIC 427 : res = duplicate_numeric(num);
1419 :
991 tgl 1420 CBC 427 : if (NUMERIC_IS_SPECIAL(num))
1421 : {
1422 : /* Flip the sign, if it's Inf or -Inf */
991 tgl 1423 GIC 63 : if (!NUMERIC_IS_NAN(num))
1424 42 : res->choice.n_short.n_header =
1425 42 : num->choice.n_short.n_header ^ NUMERIC_INF_SIGN_MASK;
991 tgl 1426 ECB : }
1427 :
1428 : /*
1429 : * The packed format is known to be totally zero digit trimmed always. So
1430 : * once we've eliminated specials, we can identify a zero by the fact that
1431 : * there are no digits at all. Do nothing to a zero.
8445 1432 : */
991 tgl 1433 CBC 364 : else if (NUMERIC_NDIGITS(num) != 0)
1434 : {
8445 tgl 1435 ECB : /* Else, flip the sign */
4632 rhaas 1436 CBC 307 : if (NUMERIC_IS_SHORT(num))
4632 rhaas 1437 GIC 307 : res->choice.n_short.n_header =
1438 307 : num->choice.n_short.n_header ^ NUMERIC_SHORT_SIGN_MASK;
4632 rhaas 1439 UIC 0 : else if (NUMERIC_SIGN(num) == NUMERIC_POS)
4632 rhaas 1440 UBC 0 : res->choice.n_long.n_sign_dscale =
4632 rhaas 1441 UIC 0 : NUMERIC_NEG | NUMERIC_DSCALE(num);
8445 tgl 1442 ECB : else
4632 rhaas 1443 UIC 0 : res->choice.n_long.n_sign_dscale =
1444 0 : NUMERIC_POS | NUMERIC_DSCALE(num);
1445 : }
1446 :
8289 tgl 1447 GIC 427 : PG_RETURN_NUMERIC(res);
1448 : }
1449 :
1450 :
1451 : Datum
7976 bruce 1452 243 : numeric_uplus(PG_FUNCTION_ARGS)
1453 : {
7976 bruce 1454 CBC 243 : Numeric num = PG_GETARG_NUMERIC(0);
1455 :
991 tgl 1456 243 : PG_RETURN_NUMERIC(duplicate_numeric(num));
1457 : }
1458 :
1459 :
1460 : /*
1461 : * numeric_sign_internal() -
991 tgl 1462 ECB : *
1463 : * Returns -1 if the argument is less than 0, 0 if the argument is equal
1464 : * to 0, and 1 if the argument is greater than zero. Caller must have
1465 : * taken care of the NaN case, but we can handle infinities here.
1466 : */
1467 : static int
991 tgl 1468 GIC 1527 : numeric_sign_internal(Numeric num)
1469 : {
991 tgl 1470 CBC 1527 : if (NUMERIC_IS_SPECIAL(num))
991 tgl 1471 ECB : {
991 tgl 1472 GIC 156 : Assert(!NUMERIC_IS_NAN(num));
1473 : /* Must be Inf or -Inf */
991 tgl 1474 CBC 156 : if (NUMERIC_IS_PINF(num))
991 tgl 1475 GIC 93 : return 1;
991 tgl 1476 ECB : else
991 tgl 1477 GIC 63 : return -1;
1478 : }
1479 :
1480 : /*
991 tgl 1481 ECB : * The packed format is known to be totally zero digit trimmed always. So
1482 : * once we've eliminated specials, we can identify a zero by the fact that
1483 : * there are no digits at all.
1484 : */
991 tgl 1485 GIC 1371 : else if (NUMERIC_NDIGITS(num) == 0)
1486 111 : return 0;
1487 1260 : else if (NUMERIC_SIGN(num) == NUMERIC_NEG)
1488 303 : return -1;
991 tgl 1489 ECB : else
991 tgl 1490 GIC 957 : return 1;
7976 bruce 1491 ECB : }
1492 :
1493 : /*
7477 1494 : * numeric_sign() -
1495 : *
1496 : * returns -1 if the argument is less than 0, 0 if the argument is equal
1497 : * to 0, and 1 if the argument is greater than zero.
1498 : */
1499 : Datum
8289 tgl 1500 GIC 24 : numeric_sign(PG_FUNCTION_ARGS)
1501 : {
1502 24 : Numeric num = PG_GETARG_NUMERIC(0);
1503 :
8053 bruce 1504 ECB : /*
1505 : * Handle NaN (infinities can be handled normally)
1506 : */
8866 JanWieck 1507 CBC 24 : if (NUMERIC_IS_NAN(num))
8289 tgl 1508 3 : PG_RETURN_NUMERIC(make_result(&const_nan));
8866 JanWieck 1509 ECB :
991 tgl 1510 GBC 21 : switch (numeric_sign_internal(num))
8866 JanWieck 1511 EUB : {
991 tgl 1512 GBC 3 : case 0:
991 tgl 1513 GIC 3 : PG_RETURN_NUMERIC(make_result(&const_zero));
991 tgl 1514 GBC 9 : case 1:
1515 9 : PG_RETURN_NUMERIC(make_result(&const_one));
991 tgl 1516 GIC 9 : case -1:
1517 9 : PG_RETURN_NUMERIC(make_result(&const_minus_one));
8866 JanWieck 1518 ECB : }
1519 :
991 tgl 1520 UIC 0 : Assert(false);
1521 : return (Datum) 0;
1522 : }
8866 JanWieck 1523 ECB :
1524 :
7324 tgl 1525 : /*
1526 : * numeric_round() -
8866 JanWieck 1527 : *
1528 : * Round a value to have 'scale' digits after the decimal point.
1529 : * We allow negative 'scale', implying rounding before the decimal
1530 : * point --- Oracle interprets rounding that way.
1531 : */
1532 : Datum
8335 tgl 1533 GIC 3751 : numeric_round(PG_FUNCTION_ARGS)
1534 : {
1535 3751 : Numeric num = PG_GETARG_NUMERIC(0);
1536 3751 : int32 scale = PG_GETARG_INT32(1);
1537 : Numeric res;
1538 : NumericVar arg;
8866 JanWieck 1539 ECB :
1540 : /*
991 tgl 1541 : * Handle NaN and infinities
1542 : */
991 tgl 1543 CBC 3751 : if (NUMERIC_IS_SPECIAL(num))
991 tgl 1544 GIC 48 : PG_RETURN_NUMERIC(duplicate_numeric(num));
8866 JanWieck 1545 ECB :
8053 bruce 1546 : /*
1547 : * Limit the scale value to avoid possible overflow in calculations
8427 tgl 1548 : */
7494 tgl 1549 GIC 3703 : scale = Max(scale, -NUMERIC_MAX_RESULT_SCALE);
1550 3703 : scale = Min(scale, NUMERIC_MAX_RESULT_SCALE);
1551 :
1552 : /*
1553 : * Unpack the argument and round it at the proper digit position
1554 : */
8427 1555 3703 : init_var(&arg);
8427 tgl 1556 CBC 3703 : set_var_from_num(num, &arg);
8427 tgl 1557 ECB :
7324 tgl 1558 CBC 3703 : round_var(&arg, scale);
8427 tgl 1559 ECB :
1560 : /* We don't allow negative output dscale */
7324 tgl 1561 CBC 3703 : if (scale < 0)
7324 tgl 1562 GIC 90 : arg.dscale = 0;
1563 :
1564 : /*
1565 : * Return the rounded result
1566 : */
8427 1567 3703 : res = make_result(&arg);
1568 :
1569 3703 : free_var(&arg);
8335 1570 3703 : PG_RETURN_NUMERIC(res);
8866 JanWieck 1571 ECB : }
1572 :
1573 :
1574 : /*
1575 : * numeric_trunc() -
1576 : *
1577 : * Truncate a value to have 'scale' digits after the decimal point.
8427 tgl 1578 : * We allow negative 'scale', implying a truncation before the decimal
1579 : * point --- Oracle interprets truncation that way.
1580 : */
8335 1581 : Datum
8335 tgl 1582 GIC 193 : numeric_trunc(PG_FUNCTION_ARGS)
8866 JanWieck 1583 ECB : {
8335 tgl 1584 CBC 193 : Numeric num = PG_GETARG_NUMERIC(0);
1585 193 : int32 scale = PG_GETARG_INT32(1);
8720 bruce 1586 ECB : Numeric res;
1587 : NumericVar arg;
8866 JanWieck 1588 :
1589 : /*
1590 : * Handle NaN and infinities
8866 JanWieck 1591 EUB : */
991 tgl 1592 GIC 193 : if (NUMERIC_IS_SPECIAL(num))
1593 18 : PG_RETURN_NUMERIC(duplicate_numeric(num));
1594 :
1595 : /*
1596 : * Limit the scale value to avoid possible overflow in calculations
1597 : */
7494 1598 175 : scale = Max(scale, -NUMERIC_MAX_RESULT_SCALE);
1599 175 : scale = Min(scale, NUMERIC_MAX_RESULT_SCALE);
1600 :
1601 : /*
1602 : * Unpack the argument and truncate it at the proper digit position
1603 : */
8866 JanWieck 1604 CBC 175 : init_var(&arg);
8866 JanWieck 1605 GIC 175 : set_var_from_num(num, &arg);
8866 JanWieck 1606 ECB :
7324 tgl 1607 CBC 175 : trunc_var(&arg, scale);
1608 :
1609 : /* We don't allow negative output dscale */
7324 tgl 1610 GIC 175 : if (scale < 0)
7324 tgl 1611 UIC 0 : arg.dscale = 0;
1612 :
1613 : /*
8866 JanWieck 1614 ECB : * Return the truncated result
1615 : */
8866 JanWieck 1616 GIC 175 : res = make_result(&arg);
1617 :
1618 175 : free_var(&arg);
8335 tgl 1619 175 : PG_RETURN_NUMERIC(res);
8866 JanWieck 1620 ECB : }
1621 :
1622 :
1623 : /*
1624 : * numeric_ceil() -
1625 : *
1626 : * Return the smallest integer greater than or equal to the argument
1627 : */
1628 : Datum
8289 tgl 1629 CBC 111 : numeric_ceil(PG_FUNCTION_ARGS)
1630 : {
8289 tgl 1631 GIC 111 : Numeric num = PG_GETARG_NUMERIC(0);
8866 JanWieck 1632 ECB : Numeric res;
1633 : NumericVar result;
1634 :
1635 : /*
1636 : * Handle NaN and infinities
1637 : */
991 tgl 1638 CBC 111 : if (NUMERIC_IS_SPECIAL(num))
991 tgl 1639 GIC 9 : PG_RETURN_NUMERIC(duplicate_numeric(num));
8866 JanWieck 1640 ECB :
3791 heikki.linnakangas 1641 CBC 102 : init_var_from_num(num, &result);
8866 JanWieck 1642 GIC 102 : ceil_var(&result, &result);
1643 :
1644 102 : res = make_result(&result);
1645 102 : free_var(&result);
1646 :
8289 tgl 1647 102 : PG_RETURN_NUMERIC(res);
1648 : }
1649 :
1650 :
1651 : /*
1652 : * numeric_floor() -
8866 JanWieck 1653 ECB : *
1654 : * Return the largest integer equal to or less than the argument
1655 : */
8289 tgl 1656 : Datum
8289 tgl 1657 GIC 63 : numeric_floor(PG_FUNCTION_ARGS)
1658 : {
1659 63 : Numeric num = PG_GETARG_NUMERIC(0);
1660 : Numeric res;
1661 : NumericVar result;
1662 :
991 tgl 1663 ECB : /*
1664 : * Handle NaN and infinities
1665 : */
991 tgl 1666 GIC 63 : if (NUMERIC_IS_SPECIAL(num))
1667 9 : PG_RETURN_NUMERIC(duplicate_numeric(num));
1668 :
3791 heikki.linnakangas 1669 CBC 54 : init_var_from_num(num, &result);
8866 JanWieck 1670 54 : floor_var(&result, &result);
1671 :
8866 JanWieck 1672 GIC 54 : res = make_result(&result);
1673 54 : free_var(&result);
1674 :
8289 tgl 1675 CBC 54 : PG_RETURN_NUMERIC(res);
8866 JanWieck 1676 ECB : }
1677 :
3071 fujii 1678 :
1679 : /*
1680 : * generate_series_numeric() -
1681 : *
2969 tgl 1682 EUB : * Generate series of numeric.
1683 : */
1684 : Datum
3071 fujii 1685 GIC 108 : generate_series_numeric(PG_FUNCTION_ARGS)
1686 : {
3071 fujii 1687 CBC 108 : return generate_series_step_numeric(fcinfo);
1688 : }
3071 fujii 1689 ECB :
1690 : Datum
3071 fujii 1691 GIC 210 : generate_series_step_numeric(PG_FUNCTION_ARGS)
1692 : {
1693 : generate_series_numeric_fctx *fctx;
1694 : FuncCallContext *funcctx;
1695 : MemoryContext oldcontext;
1696 :
1697 210 : if (SRF_IS_FIRSTCALL())
1698 : {
1699 69 : Numeric start_num = PG_GETARG_NUMERIC(0);
3071 fujii 1700 CBC 69 : Numeric stop_num = PG_GETARG_NUMERIC(1);
3071 fujii 1701 GIC 69 : NumericVar steploc = const_one;
3071 fujii 1702 ECB :
1703 : /* Reject NaN and infinities in start and stop values */
991 tgl 1704 GIC 69 : if (NUMERIC_IS_SPECIAL(start_num))
1705 : {
1706 6 : if (NUMERIC_IS_NAN(start_num))
1707 3 : ereport(ERROR,
1708 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
991 tgl 1709 ECB : errmsg("start value cannot be NaN")));
1710 : else
991 tgl 1711 GIC 3 : ereport(ERROR,
991 tgl 1712 ECB : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1713 : errmsg("start value cannot be infinity")));
1714 : }
991 tgl 1715 CBC 63 : if (NUMERIC_IS_SPECIAL(stop_num))
991 tgl 1716 ECB : {
991 tgl 1717 GIC 6 : if (NUMERIC_IS_NAN(stop_num))
991 tgl 1718 CBC 3 : ereport(ERROR,
1719 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1720 : errmsg("stop value cannot be NaN")));
1721 : else
991 tgl 1722 GIC 3 : ereport(ERROR,
1723 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1724 : errmsg("stop value cannot be infinity")));
1725 : }
1726 :
1727 : /* see if we were given an explicit step size */
3071 fujii 1728 CBC 57 : if (PG_NARGS() == 3)
1729 : {
2969 tgl 1730 27 : Numeric step_num = PG_GETARG_NUMERIC(2);
1731 :
991 tgl 1732 GIC 27 : if (NUMERIC_IS_SPECIAL(step_num))
1733 : {
1734 6 : if (NUMERIC_IS_NAN(step_num))
1735 3 : ereport(ERROR,
1736 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
991 tgl 1737 ECB : errmsg("step size cannot be NaN")));
1738 : else
991 tgl 1739 GIC 3 : ereport(ERROR,
991 tgl 1740 ECB : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1741 : errmsg("step size cannot be infinity")));
1742 : }
3071 fujii 1743 :
3071 fujii 1744 CBC 21 : init_var_from_num(step_num, &steploc);
1745 :
1746 21 : if (cmp_var(&steploc, &const_zero) == 0)
3071 fujii 1747 GIC 3 : ereport(ERROR,
1748 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1749 : errmsg("step size cannot equal zero")));
1750 : }
1751 :
1752 : /* create a function context for cross-call persistence */
1753 48 : funcctx = SRF_FIRSTCALL_INIT();
1754 :
1755 : /*
3071 fujii 1756 ECB : * Switch to memory context appropriate for multiple function calls.
1757 : */
3071 fujii 1758 CBC 48 : oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
1759 :
1760 : /* allocate memory for user context */
1761 : fctx = (generate_series_numeric_fctx *)
1762 48 : palloc(sizeof(generate_series_numeric_fctx));
1763 :
1764 : /*
1765 : * Use fctx to keep state from call to call. Seed current with the
1766 : * original start value. We must copy the start_num and stop_num
1767 : * values rather than pointing to them, since we may have detoasted
3034 fujii 1768 ECB : * them in the per-call context.
1769 : */
3034 fujii 1770 CBC 48 : init_var(&fctx->current);
1771 48 : init_var(&fctx->stop);
3071 1772 48 : init_var(&fctx->step);
1773 :
3034 fujii 1774 GIC 48 : set_var_from_num(start_num, &fctx->current);
3034 fujii 1775 CBC 48 : set_var_from_num(stop_num, &fctx->stop);
3071 fujii 1776 GIC 48 : set_var_from_var(&steploc, &fctx->step);
3071 fujii 1777 ECB :
3071 fujii 1778 CBC 48 : funcctx->user_fctx = fctx;
3071 fujii 1779 GIC 48 : MemoryContextSwitchTo(oldcontext);
1780 : }
1781 :
3071 fujii 1782 ECB : /* stuff done on every call of the function */
3071 fujii 1783 GIC 189 : funcctx = SRF_PERCALL_SETUP();
1784 :
1785 : /*
3071 fujii 1786 ECB : * Get the saved state and use current state as the result of this
1787 : * iteration.
1788 : */
3071 fujii 1789 CBC 189 : fctx = funcctx->user_fctx;
1790 :
3071 fujii 1791 GIC 366 : if ((fctx->step.sign == NUMERIC_POS &&
1792 177 : cmp_var(&fctx->current, &fctx->stop) <= 0) ||
3071 fujii 1793 CBC 69 : (fctx->step.sign == NUMERIC_NEG &&
3071 fujii 1794 GIC 12 : cmp_var(&fctx->current, &fctx->stop) >= 0))
1795 : {
2969 tgl 1796 141 : Numeric result = make_result(&fctx->current);
1797 :
1798 : /* switch to memory context appropriate for iteration calculation */
3071 fujii 1799 CBC 141 : oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
1800 :
3071 fujii 1801 ECB : /* increment current in preparation for next iteration */
3071 fujii 1802 GIC 141 : add_var(&fctx->current, &fctx->step, &fctx->current);
3071 fujii 1803 CBC 141 : MemoryContextSwitchTo(oldcontext);
1804 :
3071 fujii 1805 ECB : /* do when there is more left to send */
3071 fujii 1806 CBC 141 : SRF_RETURN_NEXT(funcctx, NumericGetDatum(result));
1807 : }
1808 : else
1809 : /* do when there is no more left */
1810 48 : SRF_RETURN_DONE(funcctx);
1811 : }
1812 :
1813 :
1814 : /*
5927 neilc 1815 ECB : * Implements the numeric version of the width_bucket() function
1816 : * defined by SQL2003. See also width_bucket_float8().
6904 1817 : *
1818 : * 'bound1' and 'bound2' are the lower and upper bounds of the
1819 : * histogram's range, respectively. 'count' is the number of buckets
1820 : * in the histogram. width_bucket() returns an integer indicating the
1821 : * bucket number that 'operand' belongs to in an equiwidth histogram
1822 : * with the specified characteristics. An operand smaller than the
1823 : * lower bound is assigned to bucket 0. An operand greater than the
1824 : * upper bound is assigned to an additional bucket (with number
1825 : * count+1). We don't allow "NaN" for any of the numeric arguments.
1826 : */
1827 : Datum
6904 neilc 1828 GIC 390 : width_bucket_numeric(PG_FUNCTION_ARGS)
6904 neilc 1829 ECB : {
6904 neilc 1830 GIC 390 : Numeric operand = PG_GETARG_NUMERIC(0);
1831 390 : Numeric bound1 = PG_GETARG_NUMERIC(1);
1832 390 : Numeric bound2 = PG_GETARG_NUMERIC(2);
6904 neilc 1833 CBC 390 : int32 count = PG_GETARG_INT32(3);
1834 : NumericVar count_var;
1835 : NumericVar result_var;
1836 : int32 result;
1837 :
6904 neilc 1838 GIC 390 : if (count <= 0)
1839 6 : ereport(ERROR,
1840 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
6385 bruce 1841 ECB : errmsg("count must be greater than zero")));
6904 neilc 1842 :
991 tgl 1843 CBC 384 : if (NUMERIC_IS_SPECIAL(operand) ||
991 tgl 1844 GIC 375 : NUMERIC_IS_SPECIAL(bound1) ||
991 tgl 1845 CBC 372 : NUMERIC_IS_SPECIAL(bound2))
991 tgl 1846 ECB : {
991 tgl 1847 CBC 18 : if (NUMERIC_IS_NAN(operand) ||
991 tgl 1848 GIC 15 : NUMERIC_IS_NAN(bound1) ||
991 tgl 1849 CBC 15 : NUMERIC_IS_NAN(bound2))
1850 3 : ereport(ERROR,
1851 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
1852 : errmsg("operand, lower bound, and upper bound cannot be NaN")));
1853 : /* We allow "operand" to be infinite; cmp_numerics will cope */
913 1854 15 : if (NUMERIC_IS_INF(bound1) || NUMERIC_IS_INF(bound2))
991 tgl 1855 GIC 9 : ereport(ERROR,
1856 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
1857 : errmsg("lower and upper bounds must be finite")));
1858 : }
1859 :
6904 neilc 1860 CBC 372 : init_var(&result_var);
6904 neilc 1861 GIC 372 : init_var(&count_var);
6904 neilc 1862 ECB :
1863 : /* Convert 'count' to a numeric, for ease of use later */
2942 andres 1864 CBC 372 : int64_to_numericvar((int64) count, &count_var);
6904 neilc 1865 ECB :
6904 neilc 1866 GIC 372 : switch (cmp_numerics(bound1, bound2))
6904 neilc 1867 ECB : {
6904 neilc 1868 GIC 3 : case 0:
1869 3 : ereport(ERROR,
2118 tgl 1870 ECB : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
1871 : errmsg("lower bound cannot equal upper bound")));
1872 : break;
6904 neilc 1873 :
6797 bruce 1874 : /* bound1 < bound2 */
6904 neilc 1875 GIC 273 : case -1:
1876 273 : if (cmp_numerics(operand, bound1) < 0)
6904 neilc 1877 CBC 57 : set_var_from_var(&const_zero, &result_var);
6904 neilc 1878 GIC 216 : else if (cmp_numerics(operand, bound2) >= 0)
1879 54 : add_var(&count_var, &const_one, &result_var);
1880 : else
913 tgl 1881 CBC 162 : compute_bucket(operand, bound1, bound2, &count_var, false,
1882 : &result_var);
6904 neilc 1883 GIC 273 : break;
1884 :
1885 : /* bound1 > bound2 */
1886 96 : case 1:
1887 96 : if (cmp_numerics(operand, bound1) > 0)
1888 6 : set_var_from_var(&const_zero, &result_var);
1889 90 : else if (cmp_numerics(operand, bound2) <= 0)
1890 12 : add_var(&count_var, &const_one, &result_var);
1891 : else
913 tgl 1892 78 : compute_bucket(operand, bound1, bound2, &count_var, true,
1893 : &result_var);
6904 neilc 1894 96 : break;
1895 : }
1896 :
1897 : /* if result exceeds the range of a legal int4, we ereport here */
1485 akorotkov 1898 369 : if (!numericvar_to_int32(&result_var, &result))
1485 akorotkov 1899 LBC 0 : ereport(ERROR,
1900 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1485 akorotkov 1901 ECB : errmsg("integer out of range")));
6904 neilc 1902 :
6904 neilc 1903 CBC 369 : free_var(&count_var);
1904 369 : free_var(&result_var);
1905 :
6904 neilc 1906 GIC 369 : PG_RETURN_INT32(result);
1907 : }
1908 :
6904 neilc 1909 ECB : /*
1910 : * 'operand' is inside the bucket range, so determine the correct
1911 : * bucket for it to go. The calculations performed by this function
1912 : * are derived directly from the SQL2003 spec. Note however that we
1913 : * multiply by count before dividing, to avoid unnecessary roundoff error.
1914 : */
1915 : static void
6904 neilc 1916 CBC 240 : compute_bucket(Numeric operand, Numeric bound1, Numeric bound2,
1917 : const NumericVar *count_var, bool reversed_bounds,
913 tgl 1918 ECB : NumericVar *result_var)
6904 neilc 1919 : {
6797 bruce 1920 : NumericVar bound1_var;
1921 : NumericVar bound2_var;
1922 : NumericVar operand_var;
1923 :
3791 heikki.linnakangas 1924 GIC 240 : init_var_from_num(bound1, &bound1_var);
3791 heikki.linnakangas 1925 CBC 240 : init_var_from_num(bound2, &bound2_var);
1926 240 : init_var_from_num(operand, &operand_var);
1927 :
913 tgl 1928 GIC 240 : if (!reversed_bounds)
1929 : {
6904 neilc 1930 162 : sub_var(&operand_var, &bound1_var, &operand_var);
6904 neilc 1931 CBC 162 : sub_var(&bound2_var, &bound1_var, &bound2_var);
6904 neilc 1932 ECB : }
1933 : else
1934 : {
6904 neilc 1935 CBC 78 : sub_var(&bound1_var, &operand_var, &operand_var);
913 tgl 1936 GIC 78 : sub_var(&bound1_var, &bound2_var, &bound2_var);
6904 neilc 1937 ECB : }
1938 :
913 tgl 1939 CBC 240 : mul_var(&operand_var, count_var, &operand_var,
1940 240 : operand_var.dscale + count_var->dscale);
913 tgl 1941 GIC 240 : div_var(&operand_var, &bound2_var, result_var,
1942 : select_div_scale(&operand_var, &bound2_var), true);
1943 :
1944 : /*
1945 : * Roundoff in the division could give us a quotient exactly equal to
1946 : * "count", which is too large. Clamp so that we do not emit a result
1947 : * larger than "count".
1948 : */
9 tgl 1949 GNC 240 : if (cmp_var(result_var, count_var) >= 0)
1950 6 : set_var_from_var(count_var, result_var);
1951 : else
1952 : {
1953 234 : add_var(result_var, &const_one, result_var);
1954 234 : floor_var(result_var, result_var);
1955 : }
1956 :
6904 neilc 1957 CBC 240 : free_var(&bound1_var);
1958 240 : free_var(&bound2_var);
1959 240 : free_var(&operand_var);
6797 bruce 1960 240 : }
8866 JanWieck 1961 ECB :
1962 : /* ----------------------------------------------------------------------
1963 : *
1964 : * Comparison functions
1965 : *
1966 : * Note: btree indexes need these routines not to leak memory; therefore,
1967 : * be careful to free working copies of toasted datums. Most places don't
8289 tgl 1968 : * need to be so careful.
2929 rhaas 1969 : *
1970 : * Sort support:
1971 : *
1972 : * We implement the sortsupport strategy routine in order to get the benefit of
1973 : * abbreviation. The ordinary numeric comparison can be quite slow as a result
1974 : * of palloc/pfree cycles (due to detoasting packed values for alignment);
1975 : * while this could be worked on itself, the abbreviation strategy gives more
1976 : * speedup in many common cases.
1977 : *
1978 : * Two different representations are used for the abbreviated form, one in
1979 : * int32 and one in int64, whichever fits into a by-value Datum. In both cases
1980 : * the representation is negated relative to the original value, because we use
2929 rhaas 1981 EUB : * the largest negative value for NaN, which sorts higher than other values. We
1982 : * convert the absolute value of the numeric to a 31-bit or 63-bit positive
1983 : * value, and then negate it if the original number was positive.
1984 : *
2929 rhaas 1985 ECB : * We abort the abbreviation process if the abbreviation cardinality is below
1986 : * 0.01% of the row count (1 per 10k non-null rows). The actual break-even
1987 : * point is somewhat below that, perhaps 1 per 30k (at 1 per 100k there's a
1988 : * very small penalty), but we don't want to build up too many abbreviated
1989 : * values before first testing for abort, so we take the slightly pessimistic
1990 : * number. We make no attempt to estimate the cardinality of the real values,
1991 : * since it plays no part in the cost model here (if the abbreviation is equal,
1992 : * the cost of comparing equal and unequal underlying values is comparable).
1993 : * We discontinue even checking for abort (saving us the hashing overhead) if
1994 : * the estimated cardinality gets to 100k; that would be enough to support many
1995 : * billions of rows while doing no worse than breaking even.
1996 : *
1997 : * ----------------------------------------------------------------------
8866 JanWieck 1998 : */
1999 :
2000 : /*
2001 : * Sort support strategy routine.
2002 : */
2003 : Datum
2929 rhaas 2004 GIC 463 : numeric_sortsupport(PG_FUNCTION_ARGS)
2005 : {
2929 rhaas 2006 CBC 463 : SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
2929 rhaas 2007 ECB :
2929 rhaas 2008 CBC 463 : ssup->comparator = numeric_fast_cmp;
2009 :
2010 463 : if (ssup->abbreviate)
2011 : {
2929 rhaas 2012 ECB : NumericSortSupport *nss;
2929 rhaas 2013 CBC 111 : MemoryContext oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
2014 :
2929 rhaas 2015 GIC 111 : nss = palloc(sizeof(NumericSortSupport));
2016 :
2929 rhaas 2017 ECB : /*
2018 : * palloc a buffer for handling unaligned packed values in addition to
2019 : * the support struct
2020 : */
2929 rhaas 2021 CBC 111 : nss->buf = palloc(VARATT_SHORT_MAX + VARHDRSZ + 1);
2929 rhaas 2022 ECB :
2929 rhaas 2023 CBC 111 : nss->input_count = 0;
2929 rhaas 2024 GIC 111 : nss->estimating = true;
2025 111 : initHyperLogLog(&nss->abbr_card, 10);
2026 :
2027 111 : ssup->ssup_extra = nss;
2028 :
2029 111 : ssup->abbrev_full_comparator = ssup->comparator;
2030 111 : ssup->comparator = numeric_cmp_abbrev;
2929 rhaas 2031 CBC 111 : ssup->abbrev_converter = numeric_abbrev_convert;
2032 111 : ssup->abbrev_abort = numeric_abbrev_abort;
2033 :
2929 rhaas 2034 GIC 111 : MemoryContextSwitchTo(oldcontext);
2929 rhaas 2035 ECB : }
2036 :
2929 rhaas 2037 GIC 463 : PG_RETURN_VOID();
2038 : }
2929 rhaas 2039 ECB :
2040 : /*
2041 : * Abbreviate a numeric datum, handling NaNs and detoasting
2042 : * (must not leak memory!)
2043 : */
2044 : static Datum
2929 rhaas 2045 GIC 443 : numeric_abbrev_convert(Datum original_datum, SortSupport ssup)
2046 : {
2047 443 : NumericSortSupport *nss = ssup->ssup_extra;
2048 443 : void *original_varatt = PG_DETOAST_DATUM_PACKED(original_datum);
2049 : Numeric value;
2050 : Datum result;
2051 :
2052 443 : nss->input_count += 1;
2053 :
2054 : /*
2055 : * This is to handle packed datums without needing a palloc/pfree cycle;
2056 : * we keep and reuse a buffer large enough to handle any short datum.
2057 : */
2058 443 : if (VARATT_IS_SHORT(original_varatt))
2059 : {
2060 408 : void *buf = nss->buf;
2061 408 : Size sz = VARSIZE_SHORT(original_varatt) - VARHDRSZ_SHORT;
2062 :
2063 408 : Assert(sz <= VARATT_SHORT_MAX - VARHDRSZ_SHORT);
2064 :
2065 408 : SET_VARSIZE(buf, VARHDRSZ + sz);
2066 408 : memcpy(VARDATA(buf), VARDATA_SHORT(original_varatt), sz);
2067 :
2068 408 : value = (Numeric) buf;
2069 : }
2070 : else
2071 35 : value = (Numeric) original_varatt;
2072 :
991 tgl 2073 443 : if (NUMERIC_IS_SPECIAL(value))
2074 : {
2075 75 : if (NUMERIC_IS_PINF(value))
2076 24 : result = NUMERIC_ABBREV_PINF;
2077 51 : else if (NUMERIC_IS_NINF(value))
2078 24 : result = NUMERIC_ABBREV_NINF;
2079 : else
2080 27 : result = NUMERIC_ABBREV_NAN;
2081 : }
2082 : else
2083 : {
2084 : NumericVar var;
2085 :
2929 rhaas 2086 CBC 368 : init_var_from_num(value, &var);
2087 :
2088 368 : result = numeric_abbrev_convert_var(&var, nss);
2089 : }
2929 rhaas 2090 ECB :
2091 : /* should happen only for external/compressed toasts */
2929 rhaas 2092 CBC 443 : if ((Pointer) original_varatt != DatumGetPointer(original_datum))
2929 rhaas 2093 UIC 0 : pfree(original_varatt);
2094 :
2929 rhaas 2095 CBC 443 : return result;
2096 : }
2929 rhaas 2097 ECB :
2098 : /*
2099 : * Consider whether to abort abbreviation.
2100 : *
2101 : * We pay no attention to the cardinality of the non-abbreviated data. There is
2102 : * no reason to do so: unlike text, we have no fast check for equal values, so
2103 : * we pay the full overhead whenever the abbreviations are equal regardless of
2104 : * whether the underlying values are also equal.
2105 : */
2106 : static bool
2929 rhaas 2107 CBC 3 : numeric_abbrev_abort(int memtupcount, SortSupport ssup)
2108 : {
2109 3 : NumericSortSupport *nss = ssup->ssup_extra;
2110 : double abbr_card;
2929 rhaas 2111 ECB :
2929 rhaas 2112 CBC 3 : if (memtupcount < 10000 || nss->input_count < 10000 || !nss->estimating)
2113 3 : return false;
2929 rhaas 2114 ECB :
2929 rhaas 2115 UIC 0 : abbr_card = estimateHyperLogLog(&nss->abbr_card);
2929 rhaas 2116 ECB :
2117 : /*
2118 : * If we have >100k distinct values, then even if we were sorting many
2119 : * billion rows we'd likely still break even, and the penalty of undoing
2120 : * that many rows of abbrevs would probably not be worth it. Stop even
2121 : * counting at that point.
2122 : */
2929 rhaas 2123 UIC 0 : if (abbr_card > 100000.0)
2124 : {
2125 : #ifdef TRACE_SORT
2126 0 : if (trace_sort)
2929 rhaas 2127 LBC 0 : elog(LOG,
2128 : "numeric_abbrev: estimation ends at cardinality %f"
2929 rhaas 2129 ECB : " after " INT64_FORMAT " values (%d rows)",
2130 : abbr_card, nss->input_count, memtupcount);
2131 : #endif
2929 rhaas 2132 UIC 0 : nss->estimating = false;
2133 0 : return false;
2929 rhaas 2134 ECB : }
2135 :
2136 : /*
2137 : * Target minimum cardinality is 1 per ~10k of non-null inputs. (The
2138 : * break even point is somewhere between one per 100k rows, where
2139 : * abbreviation has a very slight penalty, and 1 per 10k where it wins by
2140 : * a measurable percentage.) We use the relatively pessimistic 10k
2141 : * threshold, and add a 0.5 row fudge factor, because it allows us to
2142 : * abort earlier on genuinely pathological data where we've had exactly
2143 : * one abbreviated value in the first 10k (non-null) rows.
2144 : */
2929 rhaas 2145 LBC 0 : if (abbr_card < nss->input_count / 10000.0 + 0.5)
2146 : {
2929 rhaas 2147 ECB : #ifdef TRACE_SORT
2929 rhaas 2148 LBC 0 : if (trace_sort)
2929 rhaas 2149 UIC 0 : elog(LOG,
2929 rhaas 2150 ECB : "numeric_abbrev: aborting abbreviation at cardinality %f"
2151 : " below threshold %f after " INT64_FORMAT " values (%d rows)",
2152 : abbr_card, nss->input_count / 10000.0 + 0.5,
2153 : nss->input_count, memtupcount);
2154 : #endif
2929 rhaas 2155 LBC 0 : return true;
2156 : }
2929 rhaas 2157 ECB :
2158 : #ifdef TRACE_SORT
2929 rhaas 2159 LBC 0 : if (trace_sort)
2160 0 : elog(LOG,
2161 : "numeric_abbrev: cardinality %f"
2929 rhaas 2162 ECB : " after " INT64_FORMAT " values (%d rows)",
2163 : abbr_card, nss->input_count, memtupcount);
2164 : #endif
2165 :
2929 rhaas 2166 UIC 0 : return false;
2167 : }
2929 rhaas 2168 ECB :
2169 : /*
2170 : * Non-fmgr interface to the comparison routine to allow sortsupport to elide
2171 : * the fmgr call. The saving here is small given how slow numeric comparisons
2172 : * are, but it is a required part of the sort support API when abbreviations
2173 : * are performed.
2174 : *
2929 rhaas 2175 EUB : * Two palloc/pfree cycles could be saved here by using persistent buffers for
2176 : * aligning short-varlena inputs, but this has not so far been considered to
2929 rhaas 2177 ECB : * be worth the effort.
2178 : */
2179 : static int
2929 rhaas 2180 GIC 2345834 : numeric_fast_cmp(Datum x, Datum y, SortSupport ssup)
2181 : {
2182 2345834 : Numeric nx = DatumGetNumeric(x);
2183 2345834 : Numeric ny = DatumGetNumeric(y);
2184 : int result;
2185 :
2186 2345834 : result = cmp_numerics(nx, ny);
2187 :
2188 2345834 : if ((Pointer) nx != DatumGetPointer(x))
2929 rhaas 2189 CBC 86331 : pfree(nx);
2929 rhaas 2190 GIC 2345834 : if ((Pointer) ny != DatumGetPointer(y))
2929 rhaas 2191 CBC 86328 : pfree(ny);
2192 :
2929 rhaas 2193 GIC 2345834 : return result;
2929 rhaas 2194 ECB : }
2195 :
2196 : /*
2929 rhaas 2197 EUB : * Compare abbreviations of values. (Abbreviations may be equal where the true
2198 : * values differ, but if the abbreviations differ, they must reflect the
2199 : * ordering of the true values.)
2200 : */
2201 : static int
2929 rhaas 2202 GIC 463 : numeric_cmp_abbrev(Datum x, Datum y, SortSupport ssup)
2203 : {
2204 : /*
2929 rhaas 2205 EUB : * NOTE WELL: this is intentionally backwards, because the abbreviation is
2206 : * negated relative to the original value, to handle NaN/infinity cases.
2207 : */
2929 rhaas 2208 GBC 463 : if (DatumGetNumericAbbrev(x) < DatumGetNumericAbbrev(y))
2209 60 : return 1;
2929 rhaas 2210 GIC 403 : if (DatumGetNumericAbbrev(x) > DatumGetNumericAbbrev(y))
2211 370 : return -1;
2212 33 : return 0;
2213 : }
2929 rhaas 2214 EUB :
2215 : /*
2216 : * Abbreviate a NumericVar according to the available bit size.
2217 : *
2218 : * The 31-bit value is constructed as:
2219 : *
2220 : * 0 + 7bits digit weight + 24 bits digit value
2221 : *
2222 : * where the digit weight is in single decimal digits, not digit words, and
2223 : * stored in excess-44 representation[1]. The 24-bit digit value is the 7 most
2224 : * significant decimal digits of the value converted to binary. Values whose
2225 : * weights would fall outside the representable range are rounded off to zero
2226 : * (which is also used to represent actual zeros) or to 0x7FFFFFFF (which
2227 : * otherwise cannot occur). Abbreviation therefore fails to gain any advantage
2228 : * where values are outside the range 10^-44 to 10^83, which is not considered
2229 : * to be a serious limitation, or when values are of the same magnitude and
2230 : * equal in the first 7 decimal digits, which is considered to be an
2231 : * unavoidable limitation given the available bits. (Stealing three more bits
2232 : * to compare another digit would narrow the range of representable weights by
2233 : * a factor of 8, which starts to look like a real limiting factor.)
2234 : *
2235 : * (The value 44 for the excess is essentially arbitrary)
2236 : *
2237 : * The 63-bit value is constructed as:
2238 : *
2239 : * 0 + 7bits weight + 4 x 14-bit packed digit words
2240 : *
2241 : * The weight in this case is again stored in excess-44, but this time it is
2242 : * the original weight in digit words (i.e. powers of 10000). The first four
2243 : * digit words of the value (if present; trailing zeros are assumed as needed)
2244 : * are packed into 14 bits each to form the rest of the value. Again,
2245 : * out-of-range values are rounded off to 0 or 0x7FFFFFFFFFFFFFFF. The
2246 : * representable range in this case is 10^-176 to 10^332, which is considered
2247 : * to be good enough for all practical purposes, and comparison of 4 words
2248 : * means that at least 13 decimal digits are compared, which is considered to
2249 : * be a reasonable compromise between effectiveness and efficiency in computing
2250 : * the abbreviation.
2251 : *
2252 : * (The value 44 for the excess is even more arbitrary here, it was chosen just
2253 : * to match the value used in the 31-bit case)
2254 : *
2255 : * [1] - Excess-k representation means that the value is offset by adding 'k'
2256 : * and then treated as unsigned, so the smallest representable value is stored
2257 : * with all bits zero. This allows simple comparisons to work on the composite
2258 : * value.
2259 : */
2260 :
2261 : #if NUMERIC_ABBREV_BITS == 64
2929 rhaas 2262 ECB :
2263 : static Datum
2037 andres 2264 CBC 368 : numeric_abbrev_convert_var(const NumericVar *var, NumericSortSupport *nss)
2929 rhaas 2265 ECB : {
2929 rhaas 2266 GIC 368 : int ndigits = var->ndigits;
2267 368 : int weight = var->weight;
2929 rhaas 2268 ECB : int64 result;
2269 :
2929 rhaas 2270 CBC 368 : if (ndigits == 0 || weight < -44)
2929 rhaas 2271 ECB : {
2929 rhaas 2272 CBC 26 : result = 0;
2929 rhaas 2273 ECB : }
2929 rhaas 2274 GIC 342 : else if (weight > 83)
2929 rhaas 2275 ECB : {
2929 rhaas 2276 GIC 6 : result = PG_INT64_MAX;
2277 : }
2278 : else
2279 : {
2280 336 : result = ((int64) (weight + 44) << 56);
2281 :
2282 336 : switch (ndigits)
2283 : {
2929 rhaas 2284 LBC 0 : default:
2929 rhaas 2285 UIC 0 : result |= ((int64) var->digits[3]);
2286 : /* FALLTHROUGH */
2929 rhaas 2287 GIC 2 : case 3:
2288 2 : result |= ((int64) var->digits[2]) << 14;
2289 : /* FALLTHROUGH */
2929 rhaas 2290 CBC 80 : case 2:
2291 80 : result |= ((int64) var->digits[1]) << 28;
2929 rhaas 2292 ECB : /* FALLTHROUGH */
2929 rhaas 2293 CBC 336 : case 1:
2294 336 : result |= ((int64) var->digits[0]) << 42;
2929 rhaas 2295 GIC 336 : break;
2296 : }
2297 : }
2298 :
2299 : /* the abbrev is negated relative to the original */
2300 368 : if (var->sign == NUMERIC_POS)
2301 319 : result = -result;
2302 :
2303 368 : if (nss->estimating)
2304 : {
2305 368 : uint32 tmp = ((uint32) result
2306 368 : ^ (uint32) ((uint64) result >> 32));
2307 :
2308 368 : addHyperLogLog(&nss->abbr_card, DatumGetUInt32(hash_uint32(tmp)));
2309 : }
2310 :
2928 2311 368 : return NumericAbbrevGetDatum(result);
2312 : }
2313 :
2314 : #endif /* NUMERIC_ABBREV_BITS == 64 */
2315 :
2316 : #if NUMERIC_ABBREV_BITS == 32
2317 :
2318 : static Datum
2319 : numeric_abbrev_convert_var(const NumericVar *var, NumericSortSupport *nss)
2320 : {
2321 : int ndigits = var->ndigits;
2322 : int weight = var->weight;
2323 : int32 result;
2324 :
2325 : if (ndigits == 0 || weight < -11)
2326 : {
2327 : result = 0;
2328 : }
2329 : else if (weight > 20)
2330 : {
2331 : result = PG_INT32_MAX;
2332 : }
2333 : else
2334 : {
2335 : NumericDigit nxt1 = (ndigits > 1) ? var->digits[1] : 0;
2336 :
2337 : weight = (weight + 11) * 4;
2338 :
2339 : result = var->digits[0];
2340 :
2341 : /*
2342 : * "result" now has 1 to 4 nonzero decimal digits. We pack in more
2343 : * digits to make 7 in total (largest we can fit in 24 bits)
2344 : */
2345 :
2929 rhaas 2346 ECB : if (result > 999)
2347 : {
2348 : /* already have 4 digits, add 3 more */
2349 : result = (result * 1000) + (nxt1 / 10);
2350 : weight += 3;
2351 : }
2352 : else if (result > 99)
2353 : {
2354 : /* already have 3 digits, add 4 more */
2355 : result = (result * 10000) + nxt1;
2356 : weight += 2;
2357 : }
2358 : else if (result > 9)
2359 : {
2360 : NumericDigit nxt2 = (ndigits > 2) ? var->digits[2] : 0;
2361 :
2362 : /* already have 2 digits, add 5 more */
2363 : result = (result * 100000) + (nxt1 * 10) + (nxt2 / 1000);
2364 : weight += 1;
2365 : }
2929 rhaas 2366 EUB : else
2367 : {
2368 : NumericDigit nxt2 = (ndigits > 2) ? var->digits[2] : 0;
2929 rhaas 2369 ECB :
2370 : /* already have 1 digit, add 6 more */
2371 : result = (result * 1000000) + (nxt1 * 100) + (nxt2 / 100);
2372 : }
2373 :
2374 : result = result | (weight << 24);
2375 : }
2376 :
2377 : /* the abbrev is negated relative to the original */
2378 : if (var->sign == NUMERIC_POS)
2379 : result = -result;
2380 :
2381 : if (nss->estimating)
2382 : {
2383 : uint32 tmp = (uint32) result;
2384 :
2385 : addHyperLogLog(&nss->abbr_card, DatumGetUInt32(hash_uint32(tmp)));
2386 : }
2387 :
2928 2388 : return NumericAbbrevGetDatum(result);
2389 : }
2929 2390 :
2391 : #endif /* NUMERIC_ABBREV_BITS == 32 */
2392 :
2393 : /*
2394 : * Ordinary (non-sortsupport) comparisons follow.
2395 : */
2396 :
2397 : Datum
8289 tgl 2398 GIC 468176 : numeric_cmp(PG_FUNCTION_ARGS)
2399 : {
2400 468176 : Numeric num1 = PG_GETARG_NUMERIC(0);
2401 468176 : Numeric num2 = PG_GETARG_NUMERIC(1);
2402 : int result;
2403 :
8011 2404 468176 : result = cmp_numerics(num1, num2);
2405 :
8289 2406 468176 : PG_FREE_IF_COPY(num1, 0);
2407 468176 : PG_FREE_IF_COPY(num2, 1);
2408 :
2409 468176 : PG_RETURN_INT32(result);
2410 : }
2411 :
2412 :
2413 : Datum
2414 317512 : numeric_eq(PG_FUNCTION_ARGS)
2415 : {
2416 317512 : Numeric num1 = PG_GETARG_NUMERIC(0);
2417 317512 : Numeric num2 = PG_GETARG_NUMERIC(1);
2418 : bool result;
2419 :
8011 2420 317512 : result = cmp_numerics(num1, num2) == 0;
2421 :
8289 2422 317512 : PG_FREE_IF_COPY(num1, 0);
2423 317512 : PG_FREE_IF_COPY(num2, 1);
2424 :
2425 317512 : PG_RETURN_BOOL(result);
2426 : }
2427 :
2428 : Datum
2429 2661 : numeric_ne(PG_FUNCTION_ARGS)
2430 : {
2431 2661 : Numeric num1 = PG_GETARG_NUMERIC(0);
2432 2661 : Numeric num2 = PG_GETARG_NUMERIC(1);
2433 : bool result;
2434 :
8011 2435 2661 : result = cmp_numerics(num1, num2) != 0;
2436 :
8289 2437 2661 : PG_FREE_IF_COPY(num1, 0);
2438 2661 : PG_FREE_IF_COPY(num2, 1);
2439 :
2440 2661 : PG_RETURN_BOOL(result);
2441 : }
2442 :
2443 : Datum
2444 18620 : numeric_gt(PG_FUNCTION_ARGS)
2445 : {
2446 18620 : Numeric num1 = PG_GETARG_NUMERIC(0);
2447 18620 : Numeric num2 = PG_GETARG_NUMERIC(1);
2448 : bool result;
2449 :
8011 2450 18620 : result = cmp_numerics(num1, num2) > 0;
2451 :
8289 2452 18620 : PG_FREE_IF_COPY(num1, 0);
2453 18620 : PG_FREE_IF_COPY(num2, 1);
2454 :
2455 18620 : PG_RETURN_BOOL(result);
2456 : }
2457 :
2458 : Datum
2459 8364 : numeric_ge(PG_FUNCTION_ARGS)
2460 : {
2461 8364 : Numeric num1 = PG_GETARG_NUMERIC(0);
2462 8364 : Numeric num2 = PG_GETARG_NUMERIC(1);
2463 : bool result;
2464 :
8011 2465 8364 : result = cmp_numerics(num1, num2) >= 0;
2466 :
8289 2467 8364 : PG_FREE_IF_COPY(num1, 0);
2468 8364 : PG_FREE_IF_COPY(num2, 1);
2469 :
2470 8364 : PG_RETURN_BOOL(result);
2471 : }
2472 :
2473 : Datum
2474 53158 : numeric_lt(PG_FUNCTION_ARGS)
2475 : {
2476 53158 : Numeric num1 = PG_GETARG_NUMERIC(0);
2477 53158 : Numeric num2 = PG_GETARG_NUMERIC(1);
2478 : bool result;
2479 :
8011 tgl 2480 CBC 53158 : result = cmp_numerics(num1, num2) < 0;
2481 :
8289 2482 53158 : PG_FREE_IF_COPY(num1, 0);
2483 53158 : PG_FREE_IF_COPY(num2, 1);
2484 :
8289 tgl 2485 GIC 53158 : PG_RETURN_BOOL(result);
8289 tgl 2486 ECB : }
2487 :
2488 : Datum
8289 tgl 2489 CBC 8246 : numeric_le(PG_FUNCTION_ARGS)
2490 : {
2491 8246 : Numeric num1 = PG_GETARG_NUMERIC(0);
8289 tgl 2492 GIC 8246 : Numeric num2 = PG_GETARG_NUMERIC(1);
2493 : bool result;
2494 :
8011 2495 8246 : result = cmp_numerics(num1, num2) <= 0;
8011 tgl 2496 ECB :
8011 tgl 2497 GIC 8246 : PG_FREE_IF_COPY(num1, 0);
8011 tgl 2498 CBC 8246 : PG_FREE_IF_COPY(num2, 1);
8011 tgl 2499 ECB :
8011 tgl 2500 GIC 8246 : PG_RETURN_BOOL(result);
2501 : }
8011 tgl 2502 ECB :
2503 : static int
8011 tgl 2504 CBC 3223747 : cmp_numerics(Numeric num1, Numeric num2)
8011 tgl 2505 ECB : {
2506 : int result;
2507 :
2508 : /*
2509 : * We consider all NANs to be equal and larger than any non-NAN (including
2510 : * Infinity). This is somewhat arbitrary; the important thing is to have
991 2511 : * a consistent sort order.
2512 : */
991 tgl 2513 CBC 3223747 : if (NUMERIC_IS_SPECIAL(num1))
8011 tgl 2514 ECB : {
991 tgl 2515 GIC 4450 : if (NUMERIC_IS_NAN(num1))
2516 : {
991 tgl 2517 CBC 4405 : if (NUMERIC_IS_NAN(num2))
991 tgl 2518 GIC 574 : result = 0; /* NAN = NAN */
991 tgl 2519 ECB : else
991 tgl 2520 CBC 3831 : result = 1; /* NAN > non-NAN */
2521 : }
2522 45 : else if (NUMERIC_IS_PINF(num1))
2523 : {
991 tgl 2524 GIC 36 : if (NUMERIC_IS_NAN(num2))
991 tgl 2525 UIC 0 : result = -1; /* PINF < NAN */
991 tgl 2526 CBC 36 : else if (NUMERIC_IS_PINF(num2))
991 tgl 2527 GIC 3 : result = 0; /* PINF = PINF */
991 tgl 2528 ECB : else
991 tgl 2529 CBC 33 : result = 1; /* PINF > anything else */
2530 : }
2531 : else /* num1 must be NINF */
991 tgl 2532 ECB : {
991 tgl 2533 GIC 9 : if (NUMERIC_IS_NINF(num2))
991 tgl 2534 CBC 3 : result = 0; /* NINF = NINF */
991 tgl 2535 ECB : else
991 tgl 2536 GIC 6 : result = -1; /* NINF < anything else */
991 tgl 2537 ECB : }
2538 : }
991 tgl 2539 GIC 3219297 : else if (NUMERIC_IS_SPECIAL(num2))
2540 : {
991 tgl 2541 CBC 5628 : if (NUMERIC_IS_NINF(num2))
991 tgl 2542 GIC 6 : result = 1; /* normal > NINF */
991 tgl 2543 ECB : else
991 tgl 2544 CBC 5622 : result = -1; /* normal < NAN or PINF */
2545 : }
2546 : else
8289 tgl 2547 ECB : {
6270 bruce 2548 GIC 6427872 : result = cmp_var_common(NUMERIC_DIGITS(num1), NUMERIC_NDIGITS(num1),
4632 rhaas 2549 CBC 3213821 : NUMERIC_WEIGHT(num1), NUMERIC_SIGN(num1),
6270 bruce 2550 3213669 : NUMERIC_DIGITS(num2), NUMERIC_NDIGITS(num2),
4632 rhaas 2551 GIC 3214051 : NUMERIC_WEIGHT(num2), NUMERIC_SIGN(num2));
8289 tgl 2552 ECB : }
2553 :
8011 tgl 2554 GIC 3223747 : return result;
2555 : }
8866 JanWieck 2556 ECB :
2557 : /*
1870 tgl 2558 : * in_range support function for numeric.
2559 : */
2560 : Datum
1870 tgl 2561 GIC 576 : in_range_numeric_numeric(PG_FUNCTION_ARGS)
1870 tgl 2562 ECB : {
1870 tgl 2563 GIC 576 : Numeric val = PG_GETARG_NUMERIC(0);
1870 tgl 2564 CBC 576 : Numeric base = PG_GETARG_NUMERIC(1);
2565 576 : Numeric offset = PG_GETARG_NUMERIC(2);
1870 tgl 2566 GIC 576 : bool sub = PG_GETARG_BOOL(3);
1870 tgl 2567 CBC 576 : bool less = PG_GETARG_BOOL(4);
2568 : bool result;
2569 :
2570 : /*
991 tgl 2571 ECB : * Reject negative (including -Inf) or NaN offset. Negative is per spec,
2572 : * and NaN is because appropriate semantics for that seem non-obvious.
1870 2573 : */
991 tgl 2574 CBC 576 : if (NUMERIC_IS_NAN(offset) ||
991 tgl 2575 GIC 573 : NUMERIC_IS_NINF(offset) ||
2576 573 : NUMERIC_SIGN(offset) == NUMERIC_NEG)
1870 tgl 2577 CBC 3 : ereport(ERROR,
2578 : (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
1870 tgl 2579 ECB : errmsg("invalid preceding or following size in window function")));
2580 :
2581 : /*
2582 : * Deal with cases where val and/or base is NaN, following the rule that
2583 : * NaN sorts after non-NaN (cf cmp_numerics). The offset cannot affect
2584 : * the conclusion.
2585 : */
1870 tgl 2586 CBC 573 : if (NUMERIC_IS_NAN(val))
2587 : {
1870 tgl 2588 GIC 93 : if (NUMERIC_IS_NAN(base))
2589 30 : result = true; /* NAN = NAN */
2590 : else
2591 63 : result = !less; /* NAN > non-NAN */
2592 : }
2593 480 : else if (NUMERIC_IS_NAN(base))
2594 : {
1870 tgl 2595 CBC 63 : result = less; /* non-NAN < NAN */
2596 : }
991 tgl 2597 ECB :
2598 : /*
2599 : * Deal with infinite offset (necessarily +Inf, at this point).
2600 : */
991 tgl 2601 GIC 417 : else if (NUMERIC_IS_SPECIAL(offset))
991 tgl 2602 ECB : {
991 tgl 2603 GIC 210 : Assert(NUMERIC_IS_PINF(offset));
991 tgl 2604 CBC 210 : if (sub ? NUMERIC_IS_PINF(base) : NUMERIC_IS_NINF(base))
2605 : {
991 tgl 2606 ECB : /*
991 tgl 2607 EUB : * base +/- offset would produce NaN, so return true for any val
991 tgl 2608 ECB : * (see in_range_float8_float8() for reasoning).
2609 : */
991 tgl 2610 GIC 87 : result = true;
991 tgl 2611 ECB : }
991 tgl 2612 GIC 123 : else if (sub)
2613 : {
2614 : /* base - offset must be -inf */
991 tgl 2615 CBC 75 : if (less)
2616 27 : result = NUMERIC_IS_NINF(val); /* only -inf is <= sum */
2617 : else
2618 48 : result = true; /* any val is >= sum */
2619 : }
2620 : else
991 tgl 2621 ECB : {
2622 : /* base + offset must be +inf */
991 tgl 2623 CBC 48 : if (less)
991 tgl 2624 LBC 0 : result = true; /* any val is <= sum */
2625 : else
991 tgl 2626 CBC 48 : result = NUMERIC_IS_PINF(val); /* only +inf is >= sum */
2627 : }
2628 : }
2629 :
991 tgl 2630 ECB : /*
2631 : * Deal with cases where val and/or base is infinite. The offset, being
2632 : * now known finite, cannot affect the conclusion.
2633 : */
991 tgl 2634 GIC 207 : else if (NUMERIC_IS_SPECIAL(val))
2635 : {
991 tgl 2636 CBC 39 : if (NUMERIC_IS_PINF(val))
2637 : {
991 tgl 2638 GIC 18 : if (NUMERIC_IS_PINF(base))
2639 12 : result = true; /* PINF = PINF */
2640 : else
2641 6 : result = !less; /* PINF > any other non-NAN */
2642 : }
991 tgl 2643 ECB : else /* val must be NINF */
2644 : {
991 tgl 2645 CBC 21 : if (NUMERIC_IS_NINF(base))
2646 15 : result = true; /* NINF = NINF */
991 tgl 2647 ECB : else
991 tgl 2648 CBC 6 : result = less; /* NINF < anything else */
991 tgl 2649 ECB : }
2650 : }
991 tgl 2651 GIC 168 : else if (NUMERIC_IS_SPECIAL(base))
2652 : {
2653 12 : if (NUMERIC_IS_NINF(base))
2654 6 : result = !less; /* normal > NINF */
2655 : else
991 tgl 2656 CBC 6 : result = less; /* normal < PINF */
991 tgl 2657 ECB : }
1870 2658 : else
2659 : {
2660 : /*
2661 : * Otherwise go ahead and compute base +/- offset. While it's
2662 : * possible for this to overflow the numeric format, it's unlikely
2663 : * enough that we don't take measures to prevent it.
2664 : */
2665 : NumericVar valv;
2666 : NumericVar basev;
2667 : NumericVar offsetv;
2668 : NumericVar sum;
2669 :
1870 tgl 2670 CBC 156 : init_var_from_num(val, &valv);
2671 156 : init_var_from_num(base, &basev);
1870 tgl 2672 GIC 156 : init_var_from_num(offset, &offsetv);
1870 tgl 2673 CBC 156 : init_var(&sum);
2674 :
2675 156 : if (sub)
1870 tgl 2676 GIC 78 : sub_var(&basev, &offsetv, &sum);
1870 tgl 2677 ECB : else
1870 tgl 2678 GIC 78 : add_var(&basev, &offsetv, &sum);
2679 :
2680 156 : if (less)
2681 78 : result = (cmp_var(&valv, &sum) <= 0);
2682 : else
1870 tgl 2683 CBC 78 : result = (cmp_var(&valv, &sum) >= 0);
2684 :
2685 156 : free_var(&sum);
1870 tgl 2686 ECB : }
2687 :
1870 tgl 2688 GIC 573 : PG_FREE_IF_COPY(val, 0);
2689 573 : PG_FREE_IF_COPY(base, 1);
2690 573 : PG_FREE_IF_COPY(offset, 2);
2691 :
1870 tgl 2692 CBC 573 : PG_RETURN_BOOL(result);
2693 : }
1870 tgl 2694 ECB :
2695 : Datum
5815 neilc 2696 GIC 296013 : hash_numeric(PG_FUNCTION_ARGS)
5815 neilc 2697 ECB : {
5624 bruce 2698 CBC 296013 : Numeric key = PG_GETARG_NUMERIC(0);
2699 : Datum digit_hash;
5624 bruce 2700 ECB : Datum result;
2701 : int weight;
2702 : int start_offset;
2703 : int end_offset;
2704 : int i;
2705 : int hash_len;
4382 bruce 2706 EUB : NumericDigit *digits;
2707 :
991 tgl 2708 ECB : /* If it's NaN or infinity, don't try to hash the rest of the fields */
991 tgl 2709 GIC 296013 : if (NUMERIC_IS_SPECIAL(key))
5815 neilc 2710 UIC 0 : PG_RETURN_UINT32(0);
2711 :
4632 rhaas 2712 GIC 296013 : weight = NUMERIC_WEIGHT(key);
5815 neilc 2713 296013 : start_offset = 0;
5624 bruce 2714 296013 : end_offset = 0;
2715 :
5815 neilc 2716 ECB : /*
2717 : * Omit any leading or trailing zeros from the input to the hash. The
5624 bruce 2718 : * numeric implementation *should* guarantee that leading and trailing
2719 : * zeros are suppressed, but we're paranoid. Note that we measure the
2720 : * starting and ending offsets in units of NumericDigits, not bytes.
5815 neilc 2721 : */
4632 rhaas 2722 GIC 296013 : digits = NUMERIC_DIGITS(key);
5815 neilc 2723 CBC 296013 : for (i = 0; i < NUMERIC_NDIGITS(key); i++)
2724 : {
4632 rhaas 2725 GIC 295266 : if (digits[i] != (NumericDigit) 0)
5815 neilc 2726 295266 : break;
5815 neilc 2727 ECB :
5815 neilc 2728 LBC 0 : start_offset++;
2729 :
5815 neilc 2730 ECB : /*
2731 : * The weight is effectively the # of digits before the decimal point,
2732 : * so decrement it for each leading zero we skip.
2733 : */
5815 neilc 2734 UIC 0 : weight--;
5815 neilc 2735 ECB : }
2736 :
2737 : /*
5624 bruce 2738 : * If there are no non-zero digits, then the value of the number is zero,
2739 : * regardless of any other fields.
2740 : */
5815 neilc 2741 GIC 296013 : if (NUMERIC_NDIGITS(key) == start_offset)
2742 747 : PG_RETURN_UINT32(-1);
2743 :
2744 295266 : for (i = NUMERIC_NDIGITS(key) - 1; i >= 0; i--)
2745 : {
4632 rhaas 2746 295266 : if (digits[i] != (NumericDigit) 0)
5815 neilc 2747 295266 : break;
2748 :
5815 neilc 2749 UIC 0 : end_offset++;
2750 : }
2751 :
5815 neilc 2752 ECB : /* If we get here, there should be at least one non-zero digit */
5815 neilc 2753 CBC 295266 : Assert(start_offset + end_offset < NUMERIC_NDIGITS(key));
5815 neilc 2754 ECB :
2755 : /*
2756 : * Note that we don't hash on the Numeric's scale, since two numerics can
5624 bruce 2757 : * compare equal but have different scales. We also don't hash on the
2758 : * sign, although we could: since a sign difference implies inequality,
2759 : * this shouldn't affect correctness.
5815 neilc 2760 : */
5815 neilc 2761 GIC 295266 : hash_len = NUMERIC_NDIGITS(key) - start_offset - end_offset;
5815 neilc 2762 CBC 295266 : digit_hash = hash_any((unsigned char *) (NUMERIC_DIGITS(key) + start_offset),
5624 bruce 2763 ECB : hash_len * sizeof(NumericDigit));
2764 :
5815 neilc 2765 : /* Mix in the weight, via XOR */
5815 neilc 2766 GIC 295266 : result = digit_hash ^ weight;
5815 neilc 2767 ECB :
5815 neilc 2768 GIC 295266 : PG_RETURN_DATUM(result);
2769 : }
5815 neilc 2770 ECB :
2047 rhaas 2771 : /*
2772 : * Returns 64-bit value by hashing a value to a 64-bit value, with a seed.
2773 : * Otherwise, similar to hash_numeric.
2774 : */
2775 : Datum
2047 rhaas 2776 GIC 42 : hash_numeric_extended(PG_FUNCTION_ARGS)
2777 : {
2047 rhaas 2778 CBC 42 : Numeric key = PG_GETARG_NUMERIC(0);
2047 rhaas 2779 GIC 42 : uint64 seed = PG_GETARG_INT64(1);
2047 rhaas 2780 ECB : Datum digit_hash;
2781 : Datum result;
2782 : int weight;
2783 : int start_offset;
2784 : int end_offset;
2785 : int i;
2786 : int hash_len;
2787 : NumericDigit *digits;
2788 :
2789 : /* If it's NaN or infinity, don't try to hash the rest of the fields */
991 tgl 2790 GIC 42 : if (NUMERIC_IS_SPECIAL(key))
2047 rhaas 2791 LBC 0 : PG_RETURN_UINT64(seed);
2047 rhaas 2792 EUB :
2047 rhaas 2793 GIC 42 : weight = NUMERIC_WEIGHT(key);
2047 rhaas 2794 CBC 42 : start_offset = 0;
2795 42 : end_offset = 0;
2047 rhaas 2796 ECB :
2047 rhaas 2797 GIC 42 : digits = NUMERIC_DIGITS(key);
2798 42 : for (i = 0; i < NUMERIC_NDIGITS(key); i++)
2799 : {
2800 36 : if (digits[i] != (NumericDigit) 0)
2801 36 : break;
2802 :
2047 rhaas 2803 UIC 0 : start_offset++;
2047 rhaas 2804 ECB :
2047 rhaas 2805 LBC 0 : weight--;
2806 : }
2047 rhaas 2807 ECB :
2047 rhaas 2808 CBC 42 : if (NUMERIC_NDIGITS(key) == start_offset)
2047 rhaas 2809 GIC 6 : PG_RETURN_UINT64(seed - 1);
2047 rhaas 2810 EUB :
2047 rhaas 2811 GIC 36 : for (i = NUMERIC_NDIGITS(key) - 1; i >= 0; i--)
2812 : {
2813 36 : if (digits[i] != (NumericDigit) 0)
2814 36 : break;
2815 :
2047 rhaas 2816 UBC 0 : end_offset++;
2817 : }
2818 :
2047 rhaas 2819 GIC 36 : Assert(start_offset + end_offset < NUMERIC_NDIGITS(key));
2820 :
2821 36 : hash_len = NUMERIC_NDIGITS(key) - start_offset - end_offset;
2822 36 : digit_hash = hash_any_extended((unsigned char *) (NUMERIC_DIGITS(key)
2047 rhaas 2823 CBC 36 : + start_offset),
2047 rhaas 2824 ECB : hash_len * sizeof(NumericDigit),
2825 : seed);
2826 :
2046 rhaas 2827 GIC 36 : result = UInt64GetDatum(DatumGetUInt64(digit_hash) ^ weight);
2047 rhaas 2828 ECB :
2047 rhaas 2829 CBC 36 : PG_RETURN_DATUM(result);
2830 : }
2047 rhaas 2831 EUB :
2832 :
2833 : /* ----------------------------------------------------------------------
2834 : *
7324 tgl 2835 ECB : * Basic arithmetic functions
2836 : *
2837 : * ----------------------------------------------------------------------
2838 : */
2839 :
2840 :
2841 : /*
2842 : * numeric_add() -
8866 JanWieck 2843 : *
2844 : * Add two numerics
2845 : */
2846 : Datum
8289 tgl 2847 GIC 125968 : numeric_add(PG_FUNCTION_ARGS)
8866 JanWieck 2848 ECB : {
8289 tgl 2849 GIC 125968 : Numeric num1 = PG_GETARG_NUMERIC(0);
8289 tgl 2850 CBC 125968 : Numeric num2 = PG_GETARG_NUMERIC(1);
2851 : Numeric res;
2852 :
1485 akorotkov 2853 GIC 125968 : res = numeric_add_opt_error(num1, num2, NULL);
2854 :
2855 125968 : PG_RETURN_NUMERIC(res);
2856 : }
2857 :
1485 akorotkov 2858 ECB : /*
2859 : * numeric_add_opt_error() -
2860 : *
2861 : * Internal version of numeric_add(). If "*have_error" flag is provided,
2862 : * on error it's set to true, NULL returned. This is helpful when caller
2863 : * need to handle errors by itself.
2864 : */
2865 : Numeric
1485 akorotkov 2866 GIC 126391 : numeric_add_opt_error(Numeric num1, Numeric num2, bool *have_error)
2867 : {
2868 : NumericVar arg1;
2869 : NumericVar arg2;
2870 : NumericVar result;
2871 : Numeric res;
8866 JanWieck 2872 ECB :
8053 bruce 2873 EUB : /*
2874 : * Handle NaN and infinities
8866 JanWieck 2875 ECB : */
991 tgl 2876 CBC 126391 : if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
991 tgl 2877 ECB : {
991 tgl 2878 GIC 99 : if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
991 tgl 2879 CBC 39 : return make_result(&const_nan);
2880 60 : if (NUMERIC_IS_PINF(num1))
2881 : {
2882 18 : if (NUMERIC_IS_NINF(num2))
2883 3 : return make_result(&const_nan); /* Inf + -Inf */
2884 : else
991 tgl 2885 GBC 15 : return make_result(&const_pinf);
2886 : }
2887 42 : if (NUMERIC_IS_NINF(num1))
2888 : {
991 tgl 2889 GIC 18 : if (NUMERIC_IS_PINF(num2))
991 tgl 2890 CBC 3 : return make_result(&const_nan); /* -Inf + Inf */
991 tgl 2891 ECB : else
991 tgl 2892 GIC 15 : return make_result(&const_ninf);
991 tgl 2893 ECB : }
2894 : /* by here, num1 must be finite, so num2 is not */
991 tgl 2895 CBC 24 : if (NUMERIC_IS_PINF(num2))
2896 12 : return make_result(&const_pinf);
991 tgl 2897 GIC 12 : Assert(NUMERIC_IS_NINF(num2));
991 tgl 2898 GBC 12 : return make_result(&const_ninf);
2899 : }
2900 :
8053 bruce 2901 ECB : /*
2902 : * Unpack the values, let add_var() compute the result and return it.
8866 JanWieck 2903 : */
3791 heikki.linnakangas 2904 CBC 126292 : init_var_from_num(num1, &arg1);
2905 126292 : init_var_from_num(num2, &arg2);
2906 :
3791 heikki.linnakangas 2907 GIC 126292 : init_var(&result);
8866 JanWieck 2908 126292 : add_var(&arg1, &arg2, &result);
7324 tgl 2909 ECB :
1485 akorotkov 2910 GIC 126292 : res = make_result_opt_error(&result, have_error);
8866 JanWieck 2911 ECB :
8866 JanWieck 2912 GIC 126292 : free_var(&result);
2913 :
1485 akorotkov 2914 126292 : return res;
2915 : }
2916 :
2917 :
2918 : /*
2919 : * numeric_sub() -
2920 : *
2921 : * Subtract one numeric from another
2922 : */
2923 : Datum
8289 tgl 2924 27016 : numeric_sub(PG_FUNCTION_ARGS)
2925 : {
2926 27016 : Numeric num1 = PG_GETARG_NUMERIC(0);
2927 27016 : Numeric num2 = PG_GETARG_NUMERIC(1);
2928 : Numeric res;
1485 akorotkov 2929 ECB :
1485 akorotkov 2930 GIC 27016 : res = numeric_sub_opt_error(num1, num2, NULL);
1485 akorotkov 2931 ECB :
1485 akorotkov 2932 CBC 27016 : PG_RETURN_NUMERIC(res);
2933 : }
2934 :
1485 akorotkov 2935 ECB :
2936 : /*
2937 : * numeric_sub_opt_error() -
2938 : *
2939 : * Internal version of numeric_sub(). If "*have_error" flag is provided,
2940 : * on error it's set to true, NULL returned. This is helpful when caller
2941 : * need to handle errors by itself.
2942 : */
2943 : Numeric
1485 akorotkov 2944 GIC 27043 : numeric_sub_opt_error(Numeric num1, Numeric num2, bool *have_error)
2945 : {
2946 : NumericVar arg1;
2947 : NumericVar arg2;
8866 JanWieck 2948 ECB : NumericVar result;
2949 : Numeric res;
2950 :
2951 : /*
2952 : * Handle NaN and infinities
2953 : */
991 tgl 2954 GIC 27043 : if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
2955 : {
2956 1205 : if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2957 1145 : return make_result(&const_nan);
991 tgl 2958 CBC 60 : if (NUMERIC_IS_PINF(num1))
2959 : {
2960 18 : if (NUMERIC_IS_PINF(num2))
2961 3 : return make_result(&const_nan); /* Inf - Inf */
991 tgl 2962 ECB : else
991 tgl 2963 GIC 15 : return make_result(&const_pinf);
991 tgl 2964 ECB : }
991 tgl 2965 CBC 42 : if (NUMERIC_IS_NINF(num1))
2966 : {
2967 18 : if (NUMERIC_IS_NINF(num2))
991 tgl 2968 GIC 3 : return make_result(&const_nan); /* -Inf - -Inf */
991 tgl 2969 ECB : else
991 tgl 2970 GIC 15 : return make_result(&const_ninf);
991 tgl 2971 ECB : }
2972 : /* by here, num1 must be finite, so num2 is not */
991 tgl 2973 GIC 24 : if (NUMERIC_IS_PINF(num2))
991 tgl 2974 CBC 12 : return make_result(&const_ninf);
991 tgl 2975 GIC 12 : Assert(NUMERIC_IS_NINF(num2));
2976 12 : return make_result(&const_pinf);
991 tgl 2977 ECB : }
8866 JanWieck 2978 :
8053 bruce 2979 : /*
7324 tgl 2980 : * Unpack the values, let sub_var() compute the result and return it.
2981 : */
3791 heikki.linnakangas 2982 GIC 25838 : init_var_from_num(num1, &arg1);
2983 25838 : init_var_from_num(num2, &arg2);
2984 :
2985 25838 : init_var(&result);
8866 JanWieck 2986 CBC 25838 : sub_var(&arg1, &arg2, &result);
7324 tgl 2987 ECB :
1485 akorotkov 2988 GIC 25838 : res = make_result_opt_error(&result, have_error);
8866 JanWieck 2989 ECB :
8866 JanWieck 2990 CBC 25838 : free_var(&result);
2991 :
1485 akorotkov 2992 25838 : return res;
2993 : }
8866 JanWieck 2994 ECB :
2995 :
7324 tgl 2996 : /*
2997 : * numeric_mul() -
2998 : *
2999 : * Calculate the product of two numerics
3000 : */
3001 : Datum
8289 tgl 3002 GIC 244830 : numeric_mul(PG_FUNCTION_ARGS)
3003 : {
3004 244830 : Numeric num1 = PG_GETARG_NUMERIC(0);
3005 244830 : Numeric num2 = PG_GETARG_NUMERIC(1);
1485 akorotkov 3006 ECB : Numeric res;
3007 :
1485 akorotkov 3008 CBC 244830 : res = numeric_mul_opt_error(num1, num2, NULL);
1485 akorotkov 3009 ECB :
1485 akorotkov 3010 GIC 244830 : PG_RETURN_NUMERIC(res);
3011 : }
1485 akorotkov 3012 ECB :
3013 :
3014 : /*
3015 : * numeric_mul_opt_error() -
3016 : *
3017 : * Internal version of numeric_mul(). If "*have_error" flag is provided,
3018 : * on error it's set to true, NULL returned. This is helpful when caller
3019 : * need to handle errors by itself.
3020 : */
3021 : Numeric
1485 akorotkov 3022 GIC 244836 : numeric_mul_opt_error(Numeric num1, Numeric num2, bool *have_error)
3023 : {
3024 : NumericVar arg1;
3025 : NumericVar arg2;
8866 JanWieck 3026 ECB : NumericVar result;
3027 : Numeric res;
3028 :
3029 : /*
3030 : * Handle NaN and infinities
3031 : */
991 tgl 3032 GIC 244836 : if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
3033 : {
3034 99 : if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
3035 39 : return make_result(&const_nan);
991 tgl 3036 CBC 60 : if (NUMERIC_IS_PINF(num1))
3037 : {
3038 18 : switch (numeric_sign_internal(num2))
991 tgl 3039 ECB : {
991 tgl 3040 CBC 3 : case 0:
991 tgl 3041 GIC 3 : return make_result(&const_nan); /* Inf * 0 */
991 tgl 3042 CBC 9 : case 1:
3043 9 : return make_result(&const_pinf);
991 tgl 3044 GIC 6 : case -1:
991 tgl 3045 CBC 6 : return make_result(&const_ninf);
3046 : }
991 tgl 3047 LBC 0 : Assert(false);
3048 : }
991 tgl 3049 CBC 42 : if (NUMERIC_IS_NINF(num1))
991 tgl 3050 ECB : {
991 tgl 3051 GIC 18 : switch (numeric_sign_internal(num2))
991 tgl 3052 ECB : {
991 tgl 3053 GIC 3 : case 0:
3054 3 : return make_result(&const_nan); /* -Inf * 0 */
991 tgl 3055 CBC 9 : case 1:
3056 9 : return make_result(&const_ninf);
3057 6 : case -1:
3058 6 : return make_result(&const_pinf);
3059 : }
991 tgl 3060 UIC 0 : Assert(false);
3061 : }
3062 : /* by here, num1 must be finite, so num2 is not */
991 tgl 3063 GIC 24 : if (NUMERIC_IS_PINF(num2))
991 tgl 3064 ECB : {
991 tgl 3065 CBC 12 : switch (numeric_sign_internal(num1))
3066 : {
3067 3 : case 0:
3068 3 : return make_result(&const_nan); /* 0 * Inf */
991 tgl 3069 GIC 6 : case 1:
991 tgl 3070 CBC 6 : return make_result(&const_pinf);
991 tgl 3071 GIC 3 : case -1:
991 tgl 3072 CBC 3 : return make_result(&const_ninf);
3073 : }
991 tgl 3074 LBC 0 : Assert(false);
3075 : }
991 tgl 3076 GIC 12 : Assert(NUMERIC_IS_NINF(num2));
3077 12 : switch (numeric_sign_internal(num1))
3078 : {
3079 3 : case 0:
3080 3 : return make_result(&const_nan); /* 0 * -Inf */
3081 6 : case 1:
3082 6 : return make_result(&const_ninf);
3083 3 : case -1:
991 tgl 3084 CBC 3 : return make_result(&const_pinf);
3085 : }
991 tgl 3086 LBC 0 : Assert(false);
991 tgl 3087 ECB : }
3088 :
3089 : /*
7324 3090 : * Unpack the values, let mul_var() compute the result and return it.
3091 : * Unlike add_var() and sub_var(), mul_var() will round its result. In the
6385 bruce 3092 : * case of numeric_mul(), which is invoked for the * operator on numerics,
3093 : * we request exact representation for the product (rscale = sum(dscale of
3094 : * arg1, dscale of arg2)). If the exact result has more digits after the
3095 : * decimal point than can be stored in a numeric, we round it. Rounding
3096 : * after computing the exact result ensures that the final result is
3097 : * correctly rounded (rounding in mul_var() using a truncated product
3098 : * would not guarantee this).
3099 : */
3791 heikki.linnakangas 3100 GIC 244737 : init_var_from_num(num1, &arg1);
3101 244737 : init_var_from_num(num2, &arg2);
3102 :
3103 244737 : init_var(&result);
7324 tgl 3104 CBC 244737 : mul_var(&arg1, &arg2, &result, arg1.dscale + arg2.dscale);
3105 :
638 dean.a.rasheed 3106 GIC 244737 : if (result.dscale > NUMERIC_DSCALE_MAX)
3107 3 : round_var(&result, NUMERIC_DSCALE_MAX);
3108 :
1485 akorotkov 3109 244737 : res = make_result_opt_error(&result, have_error);
3110 :
8866 JanWieck 3111 244737 : free_var(&result);
3112 :
1485 akorotkov 3113 244737 : return res;
8866 JanWieck 3114 ECB : }
3115 :
3116 :
7324 tgl 3117 : /*
8866 JanWieck 3118 : * numeric_div() -
3119 : *
3120 : * Divide one numeric into another
3121 : */
8289 tgl 3122 : Datum
8289 tgl 3123 CBC 60494 : numeric_div(PG_FUNCTION_ARGS)
8866 JanWieck 3124 ECB : {
8289 tgl 3125 CBC 60494 : Numeric num1 = PG_GETARG_NUMERIC(0);
3126 60494 : Numeric num2 = PG_GETARG_NUMERIC(1);
1485 akorotkov 3127 ECB : Numeric res;
3128 :
1485 akorotkov 3129 GBC 60494 : res = numeric_div_opt_error(num1, num2, NULL);
3130 :
1485 akorotkov 3131 CBC 60478 : PG_RETURN_NUMERIC(res);
3132 : }
1485 akorotkov 3133 ECB :
3134 :
3135 : /*
3136 : * numeric_div_opt_error() -
3137 : *
3138 : * Internal version of numeric_div(). If "*have_error" flag is provided,
3139 : * on error it's set to true, NULL returned. This is helpful when caller
3140 : * need to handle errors by itself.
3141 : */
1485 akorotkov 3142 EUB : Numeric
1485 akorotkov 3143 GIC 60914 : numeric_div_opt_error(Numeric num1, Numeric num2, bool *have_error)
3144 : {
8866 JanWieck 3145 ECB : NumericVar arg1;
3146 : NumericVar arg2;
3147 : NumericVar result;
3148 : Numeric res;
7324 tgl 3149 : int rscale;
8866 JanWieck 3150 :
1343 michael 3151 CBC 60914 : if (have_error)
3152 24 : *have_error = false;
1343 michael 3153 ECB :
8053 bruce 3154 : /*
3155 : * Handle NaN and infinities
8866 JanWieck 3156 EUB : */
991 tgl 3157 GIC 60914 : if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
991 tgl 3158 ECB : {
991 tgl 3159 CBC 99 : if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
991 tgl 3160 GIC 39 : return make_result(&const_nan);
991 tgl 3161 CBC 60 : if (NUMERIC_IS_PINF(num1))
991 tgl 3162 ECB : {
991 tgl 3163 CBC 18 : if (NUMERIC_IS_SPECIAL(num2))
3164 6 : return make_result(&const_nan); /* Inf / [-]Inf */
3165 12 : switch (numeric_sign_internal(num2))
991 tgl 3166 ECB : {
991 tgl 3167 GIC 3 : case 0:
991 tgl 3168 GBC 3 : if (have_error)
3169 : {
991 tgl 3170 UIC 0 : *have_error = true;
3171 0 : return NULL;
3172 : }
991 tgl 3173 GIC 3 : ereport(ERROR,
3174 : (errcode(ERRCODE_DIVISION_BY_ZERO),
3175 : errmsg("division by zero")));
3176 : break;
3177 6 : case 1:
3178 6 : return make_result(&const_pinf);
3179 3 : case -1:
3180 3 : return make_result(&const_ninf);
3181 : }
991 tgl 3182 LBC 0 : Assert(false);
991 tgl 3183 ECB : }
991 tgl 3184 GIC 42 : if (NUMERIC_IS_NINF(num1))
991 tgl 3185 ECB : {
991 tgl 3186 CBC 18 : if (NUMERIC_IS_SPECIAL(num2))
991 tgl 3187 GIC 6 : return make_result(&const_nan); /* -Inf / [-]Inf */
991 tgl 3188 CBC 12 : switch (numeric_sign_internal(num2))
991 tgl 3189 ECB : {
991 tgl 3190 GIC 3 : case 0:
991 tgl 3191 CBC 3 : if (have_error)
3192 : {
991 tgl 3193 LBC 0 : *have_error = true;
991 tgl 3194 UIC 0 : return NULL;
991 tgl 3195 ECB : }
991 tgl 3196 GIC 3 : ereport(ERROR,
3197 : (errcode(ERRCODE_DIVISION_BY_ZERO),
3198 : errmsg("division by zero")));
3199 : break;
3200 6 : case 1:
3201 6 : return make_result(&const_ninf);
3202 3 : case -1:
3203 3 : return make_result(&const_pinf);
3204 : }
991 tgl 3205 LBC 0 : Assert(false);
3206 : }
991 tgl 3207 ECB : /* by here, num1 must be finite, so num2 is not */
3208 :
3209 : /*
3210 : * POSIX would have us return zero or minus zero if num1 is zero, and
3211 : * otherwise throw an underflow error. But the numeric type doesn't
3212 : * really do underflow, so let's just return zero.
3213 : */
991 tgl 3214 GIC 24 : return make_result(&const_zero);
3215 : }
3216 :
3217 : /*
3218 : * Unpack the arguments
3219 : */
3791 heikki.linnakangas 3220 60815 : init_var_from_num(num1, &arg1);
3221 60815 : init_var_from_num(num2, &arg2);
3222 :
3223 60815 : init_var(&result);
3224 :
8053 bruce 3225 ECB : /*
3226 : * Select scale for division result
3227 : */
7324 tgl 3228 GIC 60815 : rscale = select_div_scale(&arg1, &arg2);
3229 :
3230 : /*
3231 : * If "have_error" is provided, check for division by zero here
3232 : */
1485 akorotkov 3233 CBC 60815 : if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
1485 akorotkov 3234 ECB : {
1485 akorotkov 3235 GIC 6 : *have_error = true;
3236 6 : return NULL;
3237 : }
3238 :
7324 tgl 3239 ECB : /*
3240 : * Do the divide and return the result
3241 : */
6518 bruce 3242 CBC 60809 : div_var(&arg1, &arg2, &result, rscale, true);
8866 JanWieck 3243 ECB :
1485 akorotkov 3244 GIC 60790 : res = make_result_opt_error(&result, have_error);
8866 JanWieck 3245 ECB :
8866 JanWieck 3246 CBC 60790 : free_var(&result);
8866 JanWieck 3247 ECB :
1485 akorotkov 3248 GIC 60790 : return res;
8866 JanWieck 3249 ECB : }
3250 :
3251 :
5483 tgl 3252 EUB : /*
3253 : * numeric_div_trunc() -
3254 : *
5483 tgl 3255 ECB : * Divide one numeric into another, truncating the result to an integer
3256 : */
3257 : Datum
5483 tgl 3258 GIC 600 : numeric_div_trunc(PG_FUNCTION_ARGS)
5483 tgl 3259 ECB : {
5483 tgl 3260 CBC 600 : Numeric num1 = PG_GETARG_NUMERIC(0);
3261 600 : Numeric num2 = PG_GETARG_NUMERIC(1);
5483 tgl 3262 ECB : NumericVar arg1;
3263 : NumericVar arg2;
5483 tgl 3264 EUB : NumericVar result;
3265 : Numeric res;
5483 tgl 3266 ECB :
3267 : /*
991 3268 : * Handle NaN and infinities
3269 : */
991 tgl 3270 CBC 600 : if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
3271 : {
3272 99 : if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
3273 39 : PG_RETURN_NUMERIC(make_result(&const_nan));
991 tgl 3274 GIC 60 : if (NUMERIC_IS_PINF(num1))
991 tgl 3275 EUB : {
991 tgl 3276 GBC 18 : if (NUMERIC_IS_SPECIAL(num2))
991 tgl 3277 GIC 6 : PG_RETURN_NUMERIC(make_result(&const_nan)); /* Inf / [-]Inf */
991 tgl 3278 CBC 12 : switch (numeric_sign_internal(num2))
3279 : {
991 tgl 3280 GIC 3 : case 0:
3281 3 : ereport(ERROR,
991 tgl 3282 ECB : (errcode(ERRCODE_DIVISION_BY_ZERO),
3283 : errmsg("division by zero")));
3284 : break;
991 tgl 3285 CBC 6 : case 1:
991 tgl 3286 GIC 6 : PG_RETURN_NUMERIC(make_result(&const_pinf));
991 tgl 3287 GBC 3 : case -1:
991 tgl 3288 GIC 3 : PG_RETURN_NUMERIC(make_result(&const_ninf));
3289 : }
991 tgl 3290 UIC 0 : Assert(false);
3291 : }
991 tgl 3292 GIC 42 : if (NUMERIC_IS_NINF(num1))
3293 : {
3294 18 : if (NUMERIC_IS_SPECIAL(num2))
3295 6 : PG_RETURN_NUMERIC(make_result(&const_nan)); /* -Inf / [-]Inf */
991 tgl 3296 CBC 12 : switch (numeric_sign_internal(num2))
3297 : {
991 tgl 3298 GIC 3 : case 0:
3299 3 : ereport(ERROR,
3300 : (errcode(ERRCODE_DIVISION_BY_ZERO),
3301 : errmsg("division by zero")));
991 tgl 3302 ECB : break;
991 tgl 3303 CBC 6 : case 1:
991 tgl 3304 GIC 6 : PG_RETURN_NUMERIC(make_result(&const_ninf));
991 tgl 3305 CBC 3 : case -1:
991 tgl 3306 GIC 3 : PG_RETURN_NUMERIC(make_result(&const_pinf));
3307 : }
991 tgl 3308 UIC 0 : Assert(false);
3309 : }
991 tgl 3310 ECB : /* by here, num1 must be finite, so num2 is not */
3311 :
3312 : /*
3313 : * POSIX would have us return zero or minus zero if num1 is zero, and
3314 : * otherwise throw an underflow error. But the numeric type doesn't
3315 : * really do underflow, so let's just return zero.
3316 : */
991 tgl 3317 CBC 24 : PG_RETURN_NUMERIC(make_result(&const_zero));
991 tgl 3318 ECB : }
3319 :
3320 : /*
3321 : * Unpack the arguments
3322 : */
3791 heikki.linnakangas 3323 GIC 501 : init_var_from_num(num1, &arg1);
3791 heikki.linnakangas 3324 CBC 501 : init_var_from_num(num2, &arg2);
3325 :
3326 501 : init_var(&result);
3327 :
5483 tgl 3328 ECB : /*
3329 : * Do the divide and return the result
3330 : */
5483 tgl 3331 GIC 501 : div_var(&arg1, &arg2, &result, 0, false);
3332 :
3333 498 : res = make_result(&result);
3334 :
3335 498 : free_var(&result);
3336 :
3337 498 : PG_RETURN_NUMERIC(res);
3338 : }
3339 :
5483 tgl 3340 ECB :
3341 : /*
8866 JanWieck 3342 : * numeric_mod() -
3343 : *
3344 : * Calculate the modulo of two numerics
3345 : */
3346 : Datum
8289 tgl 3347 GIC 26283 : numeric_mod(PG_FUNCTION_ARGS)
3348 : {
3349 26283 : Numeric num1 = PG_GETARG_NUMERIC(0);
3350 26283 : Numeric num2 = PG_GETARG_NUMERIC(1);
3351 : Numeric res;
1485 akorotkov 3352 ECB :
1485 akorotkov 3353 GIC 26283 : res = numeric_mod_opt_error(num1, num2, NULL);
1485 akorotkov 3354 ECB :
1485 akorotkov 3355 CBC 26274 : PG_RETURN_NUMERIC(res);
1485 akorotkov 3356 ECB : }
3357 :
3358 :
3359 : /*
3360 : * numeric_mod_opt_error() -
3361 : *
3362 : * Internal version of numeric_mod(). If "*have_error" flag is provided,
3363 : * on error it's set to true, NULL returned. This is helpful when caller
3364 : * need to handle errors by itself.
3365 : */
3366 : Numeric
1485 akorotkov 3367 CBC 26289 : numeric_mod_opt_error(Numeric num1, Numeric num2, bool *have_error)
1485 akorotkov 3368 ECB : {
3369 : Numeric res;
8866 JanWieck 3370 : NumericVar arg1;
3371 : NumericVar arg2;
8866 JanWieck 3372 EUB : NumericVar result;
3373 :
1343 michael 3374 CBC 26289 : if (have_error)
1343 michael 3375 UIC 0 : *have_error = false;
1343 michael 3376 ECB :
991 tgl 3377 : /*
3378 : * Handle NaN and infinities. We follow POSIX fmod() on this, except that
3379 : * POSIX treats x-is-infinite and y-is-zero identically, raising EDOM and
3380 : * returning NaN. We choose to throw error only for y-is-zero.
3381 : */
991 tgl 3382 GIC 26289 : if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
3383 : {
3384 99 : if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
991 tgl 3385 CBC 39 : return make_result(&const_nan);
3386 60 : if (NUMERIC_IS_INF(num1))
991 tgl 3387 ECB : {
991 tgl 3388 CBC 36 : if (numeric_sign_internal(num2) == 0)
3389 : {
991 tgl 3390 GBC 6 : if (have_error)
3391 : {
991 tgl 3392 UIC 0 : *have_error = true;
3393 0 : return NULL;
3394 : }
991 tgl 3395 GIC 6 : ereport(ERROR,
3396 : (errcode(ERRCODE_DIVISION_BY_ZERO),
3397 : errmsg("division by zero")));
3398 : }
991 tgl 3399 ECB : /* Inf % any nonzero = NaN */
991 tgl 3400 GIC 30 : return make_result(&const_nan);
3401 : }
3402 : /* num2 must be [-]Inf; result is num1 regardless of sign of num2 */
3403 24 : return duplicate_numeric(num1);
3404 : }
8866 JanWieck 3405 ECB :
3791 heikki.linnakangas 3406 CBC 26190 : init_var_from_num(num1, &arg1);
3791 heikki.linnakangas 3407 GIC 26190 : init_var_from_num(num2, &arg2);
8866 JanWieck 3408 ECB :
3791 heikki.linnakangas 3409 GIC 26190 : init_var(&result);
3410 :
3411 : /*
3412 : * If "have_error" is provided, check for division by zero here
1485 akorotkov 3413 ECB : */
1485 akorotkov 3414 GIC 26190 : if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
1485 akorotkov 3415 ECB : {
1485 akorotkov 3416 UIC 0 : *have_error = true;
1485 akorotkov 3417 LBC 0 : return NULL;
3418 : }
1485 akorotkov 3419 ECB :
8866 JanWieck 3420 GIC 26190 : mod_var(&arg1, &arg2, &result);
3421 :
1485 akorotkov 3422 26184 : res = make_result_opt_error(&result, NULL);
3423 :
8866 JanWieck 3424 26184 : free_var(&result);
3425 :
1485 akorotkov 3426 26184 : return res;
3427 : }
3428 :
8866 JanWieck 3429 ECB :
3430 : /*
3431 : * numeric_inc() -
3432 : *
3433 : * Increment a number by one
3434 : */
8289 tgl 3435 : Datum
8289 tgl 3436 GIC 24 : numeric_inc(PG_FUNCTION_ARGS)
8866 JanWieck 3437 ECB : {
8289 tgl 3438 GIC 24 : Numeric num = PG_GETARG_NUMERIC(0);
3439 : NumericVar arg;
3440 : Numeric res;
3441 :
3442 : /*
3443 : * Handle NaN and infinities
3444 : */
991 3445 24 : if (NUMERIC_IS_SPECIAL(num))
3446 9 : PG_RETURN_NUMERIC(duplicate_numeric(num));
3447 :
3448 : /*
8866 JanWieck 3449 ECB : * Compute the result and return it
3450 : */
3791 heikki.linnakangas 3451 GIC 15 : init_var_from_num(num, &arg);
3452 :
8866 JanWieck 3453 15 : add_var(&arg, &const_one, &arg);
3454 :
3455 15 : res = make_result(&arg);
8866 JanWieck 3456 ECB :
8866 JanWieck 3457 GBC 15 : free_var(&arg);
3458 :
8289 tgl 3459 GIC 15 : PG_RETURN_NUMERIC(res);
3460 : }
3461 :
3462 :
3463 : /*
8866 JanWieck 3464 ECB : * numeric_smaller() -
3465 : *
3466 : * Return the smaller of two numbers
3467 : */
8289 tgl 3468 : Datum
8289 tgl 3469 GIC 102 : numeric_smaller(PG_FUNCTION_ARGS)
8866 JanWieck 3470 ECB : {
8289 tgl 3471 GIC 102 : Numeric num1 = PG_GETARG_NUMERIC(0);
8289 tgl 3472 CBC 102 : Numeric num2 = PG_GETARG_NUMERIC(1);
3473 :
8053 bruce 3474 EUB : /*
6385 3475 : * Use cmp_numerics so that this will agree with the comparison operators,
3476 : * particularly as regards comparisons involving NaN.
8866 JanWieck 3477 ECB : */
7193 tgl 3478 GIC 102 : if (cmp_numerics(num1, num2) < 0)
3479 42 : PG_RETURN_NUMERIC(num1);
3480 : else
3481 60 : PG_RETURN_NUMERIC(num2);
8866 JanWieck 3482 ECB : }
3483 :
3484 :
7324 tgl 3485 : /*
3486 : * numeric_larger() -
3487 : *
8866 JanWieck 3488 : * Return the larger of two numbers
3489 : */
3490 : Datum
8289 tgl 3491 CBC 27 : numeric_larger(PG_FUNCTION_ARGS)
3492 : {
8289 tgl 3493 GIC 27 : Numeric num1 = PG_GETARG_NUMERIC(0);
3494 27 : Numeric num2 = PG_GETARG_NUMERIC(1);
3495 :
8053 bruce 3496 ECB : /*
3497 : * Use cmp_numerics so that this will agree with the comparison operators,
6385 bruce 3498 EUB : * particularly as regards comparisons involving NaN.
8866 JanWieck 3499 : */
7193 tgl 3500 GIC 27 : if (cmp_numerics(num1, num2) > 0)
3501 18 : PG_RETURN_NUMERIC(num1);
8866 JanWieck 3502 ECB : else
7193 tgl 3503 GIC 9 : PG_RETURN_NUMERIC(num2);
8866 JanWieck 3504 ECB : }
3505 :
3506 :
3507 : /* ----------------------------------------------------------------------
3508 : *
3509 : * Advanced math functions
3510 : *
3511 : * ----------------------------------------------------------------------
3512 : */
3513 :
3514 : /*
3515 : * numeric_gcd() -
3516 : *
3517 : * Calculate the greatest common divisor of two numerics
1170 dean.a.rasheed 3518 : */
3519 : Datum
1170 dean.a.rasheed 3520 CBC 108 : numeric_gcd(PG_FUNCTION_ARGS)
3521 : {
1170 dean.a.rasheed 3522 GIC 108 : Numeric num1 = PG_GETARG_NUMERIC(0);
3523 108 : Numeric num2 = PG_GETARG_NUMERIC(1);
3524 : NumericVar arg1;
3525 : NumericVar arg2;
3526 : NumericVar result;
1170 dean.a.rasheed 3527 ECB : Numeric res;
3528 :
3529 : /*
3530 : * Handle NaN and infinities: we consider the result to be NaN in all such
3531 : * cases.
3532 : */
991 tgl 3533 CBC 108 : if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
1170 dean.a.rasheed 3534 GIC 48 : PG_RETURN_NUMERIC(make_result(&const_nan));
1170 dean.a.rasheed 3535 ECB :
3536 : /*
3537 : * Unpack the arguments
3538 : */
1170 dean.a.rasheed 3539 CBC 60 : init_var_from_num(num1, &arg1);
1170 dean.a.rasheed 3540 GIC 60 : init_var_from_num(num2, &arg2);
1170 dean.a.rasheed 3541 ECB :
1170 dean.a.rasheed 3542 GIC 60 : init_var(&result);
3543 :
3544 : /*
3545 : * Find the GCD and return the result
3546 : */
3547 60 : gcd_var(&arg1, &arg2, &result);
3548 :
3549 60 : res = make_result(&result);
3550 :
1170 dean.a.rasheed 3551 CBC 60 : free_var(&result);
3552 :
3553 60 : PG_RETURN_NUMERIC(res);
1170 dean.a.rasheed 3554 ECB : }
3555 :
3556 :
3557 : /*
3558 : * numeric_lcm() -
3559 : *
3560 : * Calculate the least common multiple of two numerics
3561 : */
3562 : Datum
1170 dean.a.rasheed 3563 CBC 123 : numeric_lcm(PG_FUNCTION_ARGS)
3564 : {
1170 dean.a.rasheed 3565 GIC 123 : Numeric num1 = PG_GETARG_NUMERIC(0);
3566 123 : Numeric num2 = PG_GETARG_NUMERIC(1);
3567 : NumericVar arg1;
3568 : NumericVar arg2;
3569 : NumericVar result;
3570 : Numeric res;
3571 :
3572 : /*
991 tgl 3573 ECB : * Handle NaN and infinities: we consider the result to be NaN in all such
3574 : * cases.
1170 dean.a.rasheed 3575 : */
991 tgl 3576 CBC 123 : if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
1170 dean.a.rasheed 3577 GIC 48 : PG_RETURN_NUMERIC(make_result(&const_nan));
3578 :
3579 : /*
3580 : * Unpack the arguments
3581 : */
1170 dean.a.rasheed 3582 CBC 75 : init_var_from_num(num1, &arg1);
3583 75 : init_var_from_num(num2, &arg2);
3584 :
3585 75 : init_var(&result);
3586 :
3587 : /*
3588 : * Compute the result using lcm(x, y) = abs(x / gcd(x, y) * y), returning
3589 : * zero if either input is zero.
3590 : *
3591 : * Note that the division is guaranteed to be exact, returning an integer
3592 : * result, so the LCM is an integral multiple of both x and y. A display
3593 : * scale of Min(x.dscale, y.dscale) would be sufficient to represent it,
3594 : * but as with other numeric functions, we choose to return a result whose
3595 : * display scale is no smaller than either input.
3596 : */
1170 dean.a.rasheed 3597 GIC 75 : if (arg1.ndigits == 0 || arg2.ndigits == 0)
3598 24 : set_var_from_var(&const_zero, &result);
3599 : else
3600 : {
3601 51 : gcd_var(&arg1, &arg2, &result);
1170 dean.a.rasheed 3602 CBC 51 : div_var(&arg1, &result, &result, 0, false);
1170 dean.a.rasheed 3603 GIC 51 : mul_var(&arg2, &result, &result, arg2.dscale);
1170 dean.a.rasheed 3604 CBC 51 : result.sign = NUMERIC_POS;
1170 dean.a.rasheed 3605 ECB : }
3606 :
1170 dean.a.rasheed 3607 GIC 75 : result.dscale = Max(arg1.dscale, arg2.dscale);
3608 :
3609 75 : res = make_result(&result);
3610 :
3611 72 : free_var(&result);
3612 :
3613 72 : PG_RETURN_NUMERIC(res);
3614 : }
1170 dean.a.rasheed 3615 ECB :
3616 :
3617 : /*
3618 : * numeric_fac()
3619 : *
3620 : * Compute factorial
7069 bruce 3621 : */
3622 : Datum
7069 bruce 3623 GIC 21 : numeric_fac(PG_FUNCTION_ARGS)
7069 bruce 3624 ECB : {
7069 bruce 3625 GIC 21 : int64 num = PG_GETARG_INT64(0);
3626 : Numeric res;
3627 : NumericVar fact;
3628 : NumericVar result;
7069 bruce 3629 ECB :
1025 peter 3630 GIC 21 : if (num < 0)
1025 peter 3631 CBC 3 : ereport(ERROR,
3632 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1025 peter 3633 ECB : errmsg("factorial of a negative number is undefined")));
7068 tgl 3634 GIC 18 : if (num <= 1)
7068 tgl 3635 ECB : {
7069 bruce 3636 GIC 3 : res = make_result(&const_one);
3637 3 : PG_RETURN_NUMERIC(res);
3638 : }
3639 : /* Fail immediately if the result would overflow */
5783 tgl 3640 15 : if (num > 32177)
3641 3 : ereport(ERROR,
3642 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
3643 : errmsg("value overflows numeric format")));
3644 :
7069 bruce 3645 CBC 12 : init_var(&fact);
7069 bruce 3646 GIC 12 : init_var(&result);
7069 bruce 3647 ECB :
2942 andres 3648 CBC 12 : int64_to_numericvar(num, &result);
3649 :
7068 tgl 3650 GIC 147 : for (num = num - 1; num > 1; num--)
3651 : {
3652 : /* this loop can take awhile, so allow it to be interrupted */
5783 3653 135 : CHECK_FOR_INTERRUPTS();
3654 :
2942 andres 3655 135 : int64_to_numericvar(num, &fact);
3656 :
7068 tgl 3657 135 : mul_var(&result, &fact, &result, 0);
7069 bruce 3658 ECB : }
3659 :
7068 tgl 3660 GIC 12 : res = make_result(&result);
3661 :
7069 bruce 3662 12 : free_var(&fact);
3663 12 : free_var(&result);
7069 bruce 3664 ECB :
7069 bruce 3665 CBC 12 : PG_RETURN_NUMERIC(res);
3666 : }
7069 bruce 3667 ECB :
3668 :
3669 : /*
3670 : * numeric_sqrt() -
3671 : *
3672 : * Compute the square root of a numeric.
3673 : */
3674 : Datum
8289 tgl 3675 GIC 75 : numeric_sqrt(PG_FUNCTION_ARGS)
3676 : {
3677 75 : Numeric num = PG_GETARG_NUMERIC(0);
3678 : Numeric res;
8720 bruce 3679 ECB : NumericVar arg;
3680 : NumericVar result;
3681 : int sweight;
3682 : int rscale;
8866 JanWieck 3683 :
8053 bruce 3684 : /*
991 tgl 3685 : * Handle NaN and infinities
8866 JanWieck 3686 : */
991 tgl 3687 GIC 75 : if (NUMERIC_IS_SPECIAL(num))
3688 : {
991 tgl 3689 ECB : /* error should match that in sqrt_var() */
991 tgl 3690 GIC 9 : if (NUMERIC_IS_NINF(num))
991 tgl 3691 CBC 3 : ereport(ERROR,
3692 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
991 tgl 3693 ECB : errmsg("cannot take square root of a negative number")));
3694 : /* For NAN or PINF, just duplicate the input */
991 tgl 3695 CBC 6 : PG_RETURN_NUMERIC(duplicate_numeric(num));
3696 : }
3697 :
3698 : /*
3699 : * Unpack the argument and determine the result scale. We choose a scale
3700 : * to give at least NUMERIC_MIN_SIG_DIGITS significant digits; but in any
3701 : * case not less than the input's dscale.
3702 : */
3791 heikki.linnakangas 3703 GIC 66 : init_var_from_num(num, &arg);
3704 :
3791 heikki.linnakangas 3705 CBC 66 : init_var(&result);
3706 :
3707 : /*
3708 : * Assume the input was normalized, so arg.weight is accurate. The result
3709 : * then has at least sweight = floor(arg.weight * DEC_DIGITS / 2 + 1)
3710 : * digits before the decimal point. When DEC_DIGITS is even, we can save
3711 : * a few cycles, since the division is exact and there is no need to round
3712 : * towards negative infinity.
3713 : */
3714 : #if DEC_DIGITS == ((DEC_DIGITS / 2) * 2)
66 dean.a.rasheed 3715 GNC 66 : sweight = arg.weight * DEC_DIGITS / 2 + 1;
3716 : #else
3717 : if (arg.weight >= 0)
3718 : sweight = arg.weight * DEC_DIGITS / 2 + 1;
3719 : else
3720 : sweight = 1 - (1 - arg.weight * DEC_DIGITS) / 2;
3721 : #endif
3722 :
7324 tgl 3723 GIC 66 : rscale = NUMERIC_MIN_SIG_DIGITS - sweight;
3724 66 : rscale = Max(rscale, arg.dscale);
7324 tgl 3725 CBC 66 : rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
3726 66 : rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
3727 :
3728 : /*
7494 tgl 3729 ECB : * Let sqrt_var() do the calculation and return the result.
3730 : */
7324 tgl 3731 CBC 66 : sqrt_var(&arg, &result, rscale);
8866 JanWieck 3732 ECB :
8866 JanWieck 3733 GIC 63 : res = make_result(&result);
3734 :
8866 JanWieck 3735 CBC 63 : free_var(&result);
8866 JanWieck 3736 ECB :
8289 tgl 3737 GIC 63 : PG_RETURN_NUMERIC(res);
3738 : }
3739 :
8866 JanWieck 3740 ECB :
7324 tgl 3741 : /*
3742 : * numeric_exp() -
8866 JanWieck 3743 : *
3744 : * Raise e to the power of x
3745 : */
3746 : Datum
8289 tgl 3747 GIC 39 : numeric_exp(PG_FUNCTION_ARGS)
8866 JanWieck 3748 ECB : {
8289 tgl 3749 GIC 39 : Numeric num = PG_GETARG_NUMERIC(0);
8720 bruce 3750 ECB : Numeric res;
3751 : NumericVar arg;
3752 : NumericVar result;
3753 : int rscale;
3754 : double val;
8866 JanWieck 3755 :
3756 : /*
991 tgl 3757 : * Handle NaN and infinities
8866 JanWieck 3758 : */
991 tgl 3759 GIC 39 : if (NUMERIC_IS_SPECIAL(num))
991 tgl 3760 ECB : {
3761 : /* Per POSIX, exp(-Inf) is zero */
991 tgl 3762 GIC 9 : if (NUMERIC_IS_NINF(num))
3763 3 : PG_RETURN_NUMERIC(make_result(&const_zero));
3764 : /* For NAN or PINF, just duplicate the input */
3765 6 : PG_RETURN_NUMERIC(duplicate_numeric(num));
3766 : }
3767 :
3768 : /*
3769 : * Unpack the argument and determine the result scale. We choose a scale
6385 bruce 3770 ECB : * to give at least NUMERIC_MIN_SIG_DIGITS significant digits; but in any
3771 : * case not less than the input's dscale.
8866 JanWieck 3772 : */
3791 heikki.linnakangas 3773 GIC 30 : init_var_from_num(num, &arg);
3774 :
3775 30 : init_var(&result);
3776 :
3777 : /* convert input to float8, ignoring overflow */
7324 tgl 3778 30 : val = numericvar_to_double_no_overflow(&arg);
3779 :
3780 : /*
3781 : * log10(result) = num * log10(e), so this is approximately the decimal
6385 bruce 3782 ECB : * weight of the result:
3783 : */
7494 tgl 3784 GIC 30 : val *= 0.434294481903252;
7494 tgl 3785 ECB :
3786 : /* limit to something that won't cause integer overflow */
7494 tgl 3787 GIC 30 : val = Max(val, -NUMERIC_MAX_RESULT_SCALE);
3788 30 : val = Min(val, NUMERIC_MAX_RESULT_SCALE);
3789 :
7324 tgl 3790 CBC 30 : rscale = NUMERIC_MIN_SIG_DIGITS - (int) val;
7324 tgl 3791 GIC 30 : rscale = Max(rscale, arg.dscale);
3792 30 : rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
3793 30 : rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
3794 :
3795 : /*
3796 : * Let exp_var() do the calculation and return the result.
3797 : */
7324 tgl 3798 CBC 30 : exp_var(&arg, &result, rscale);
3799 :
8866 JanWieck 3800 30 : res = make_result(&result);
3801 :
8866 JanWieck 3802 GIC 30 : free_var(&result);
3803 :
8289 tgl 3804 30 : PG_RETURN_NUMERIC(res);
3805 : }
3806 :
3807 :
3808 : /*
3809 : * numeric_ln() -
8866 JanWieck 3810 ECB : *
3811 : * Compute the natural logarithm of x
3812 : */
3813 : Datum
8289 tgl 3814 GIC 99 : numeric_ln(PG_FUNCTION_ARGS)
3815 : {
3816 99 : Numeric num = PG_GETARG_NUMERIC(0);
3817 : Numeric res;
8720 bruce 3818 ECB : NumericVar arg;
3819 : NumericVar result;
2703 tgl 3820 : int ln_dweight;
7324 3821 : int rscale;
3822 :
3823 : /*
3824 : * Handle NaN and infinities
3825 : */
991 tgl 3826 CBC 99 : if (NUMERIC_IS_SPECIAL(num))
3827 : {
3828 9 : if (NUMERIC_IS_NINF(num))
991 tgl 3829 GIC 3 : ereport(ERROR,
991 tgl 3830 ECB : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
3831 : errmsg("cannot take logarithm of a negative number")));
3832 : /* For NAN or PINF, just duplicate the input */
991 tgl 3833 GIC 6 : PG_RETURN_NUMERIC(duplicate_numeric(num));
3834 : }
3835 :
3791 heikki.linnakangas 3836 90 : init_var_from_num(num, &arg);
8866 JanWieck 3837 90 : init_var(&result);
3838 :
3839 : /* Estimated dweight of logarithm */
2703 tgl 3840 90 : ln_dweight = estimate_ln_dweight(&arg);
3841 :
2703 tgl 3842 CBC 90 : rscale = NUMERIC_MIN_SIG_DIGITS - ln_dweight;
7324 tgl 3843 GIC 90 : rscale = Max(rscale, arg.dscale);
7324 tgl 3844 CBC 90 : rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
7324 tgl 3845 GIC 90 : rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
3846 :
3847 90 : ln_var(&arg, &result, rscale);
3848 :
8866 JanWieck 3849 78 : res = make_result(&result);
3850 :
3851 78 : free_var(&result);
3852 :
8289 tgl 3853 78 : PG_RETURN_NUMERIC(res);
8866 JanWieck 3854 ECB : }
3855 :
3856 :
7324 tgl 3857 : /*
8445 3858 : * numeric_log() -
3859 : *
8866 JanWieck 3860 : * Compute the logarithm of x in a given base
3861 : */
3862 : Datum
8289 tgl 3863 GIC 171 : numeric_log(PG_FUNCTION_ARGS)
3864 : {
3865 171 : Numeric num1 = PG_GETARG_NUMERIC(0);
3866 171 : Numeric num2 = PG_GETARG_NUMERIC(1);
3867 : Numeric res;
8720 bruce 3868 ECB : NumericVar arg1;
3869 : NumericVar arg2;
3870 : NumericVar result;
3871 :
3872 : /*
991 tgl 3873 : * Handle NaN and infinities
3874 : */
991 tgl 3875 GIC 171 : if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
3876 : {
3877 : int sign1,
3878 : sign2;
991 tgl 3879 ECB :
991 tgl 3880 GIC 63 : if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
3881 27 : PG_RETURN_NUMERIC(make_result(&const_nan));
991 tgl 3882 ECB : /* fail on negative inputs including -Inf, as log_var would */
991 tgl 3883 CBC 36 : sign1 = numeric_sign_internal(num1);
991 tgl 3884 GIC 36 : sign2 = numeric_sign_internal(num2);
991 tgl 3885 CBC 36 : if (sign1 < 0 || sign2 < 0)
3886 12 : ereport(ERROR,
991 tgl 3887 ECB : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
3888 : errmsg("cannot take logarithm of a negative number")));
3889 : /* fail on zero inputs, as log_var would */
991 tgl 3890 GIC 24 : if (sign1 == 0 || sign2 == 0)
3891 3 : ereport(ERROR,
3892 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
991 tgl 3893 ECB : errmsg("cannot take logarithm of zero")));
991 tgl 3894 GIC 21 : if (NUMERIC_IS_PINF(num1))
991 tgl 3895 ECB : {
3896 : /* log(Inf, Inf) reduces to Inf/Inf, so it's NaN */
991 tgl 3897 CBC 9 : if (NUMERIC_IS_PINF(num2))
991 tgl 3898 GIC 3 : PG_RETURN_NUMERIC(make_result(&const_nan));
991 tgl 3899 ECB : /* log(Inf, finite-positive) is zero (we don't throw underflow) */
991 tgl 3900 GIC 6 : PG_RETURN_NUMERIC(make_result(&const_zero));
3901 : }
3902 12 : Assert(NUMERIC_IS_PINF(num2));
3903 : /* log(finite-positive, Inf) is Inf */
3904 12 : PG_RETURN_NUMERIC(make_result(&const_pinf));
3905 : }
3906 :
3907 : /*
3908 : * Initialize things
8866 JanWieck 3909 ECB : */
3791 heikki.linnakangas 3910 GIC 108 : init_var_from_num(num1, &arg1);
3791 heikki.linnakangas 3911 CBC 108 : init_var_from_num(num2, &arg2);
8866 JanWieck 3912 GIC 108 : init_var(&result);
3913 :
3914 : /*
3915 : * Call log_var() to compute and return the result; note it handles scale
3916 : * selection itself.
3917 : */
3918 108 : log_var(&arg1, &arg2, &result);
3919 :
3920 78 : res = make_result(&result);
8866 JanWieck 3921 ECB :
8866 JanWieck 3922 GIC 78 : free_var(&result);
8866 JanWieck 3923 ECB :
8289 tgl 3924 CBC 78 : PG_RETURN_NUMERIC(res);
3925 : }
3926 :
3927 :
7324 tgl 3928 ECB : /*
3929 : * numeric_power() -
3930 : *
991 3931 : * Raise x to the power of y
8866 JanWieck 3932 : */
3933 : Datum
8289 tgl 3934 GIC 693 : numeric_power(PG_FUNCTION_ARGS)
8866 JanWieck 3935 ECB : {
8289 tgl 3936 GIC 693 : Numeric num1 = PG_GETARG_NUMERIC(0);
8289 tgl 3937 CBC 693 : Numeric num2 = PG_GETARG_NUMERIC(1);
8720 bruce 3938 ECB : Numeric res;
3939 : NumericVar arg1;
3940 : NumericVar arg2;
3941 : NumericVar result;
991 tgl 3942 : int sign1,
3943 : sign2;
8866 JanWieck 3944 :
3945 : /*
991 tgl 3946 : * Handle NaN and infinities
3947 : */
991 tgl 3948 CBC 693 : if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
3949 : {
3950 : /*
3951 : * We follow the POSIX spec for pow(3), which says that NaN ^ 0 = 1,
3952 : * and 1 ^ NaN = 1, while all other cases with NaN inputs yield NaN
3953 : * (with no error).
3954 : */
991 tgl 3955 GIC 117 : if (NUMERIC_IS_NAN(num1))
3956 : {
3957 27 : if (!NUMERIC_IS_SPECIAL(num2))
991 tgl 3958 ECB : {
991 tgl 3959 GIC 18 : init_var_from_num(num2, &arg2);
991 tgl 3960 CBC 18 : if (cmp_var(&arg2, &const_zero) == 0)
3961 6 : PG_RETURN_NUMERIC(make_result(&const_one));
3962 : }
991 tgl 3963 GIC 21 : PG_RETURN_NUMERIC(make_result(&const_nan));
3964 : }
3965 90 : if (NUMERIC_IS_NAN(num2))
3966 : {
3967 21 : if (!NUMERIC_IS_SPECIAL(num1))
3968 : {
3969 18 : init_var_from_num(num1, &arg1);
991 tgl 3970 CBC 18 : if (cmp_var(&arg1, &const_one) == 0)
991 tgl 3971 GIC 6 : PG_RETURN_NUMERIC(make_result(&const_one));
3972 : }
3973 15 : PG_RETURN_NUMERIC(make_result(&const_nan));
3974 : }
991 tgl 3975 ECB : /* At least one input is infinite, but error rules still apply */
991 tgl 3976 CBC 69 : sign1 = numeric_sign_internal(num1);
991 tgl 3977 GIC 69 : sign2 = numeric_sign_internal(num2);
991 tgl 3978 CBC 69 : if (sign1 == 0 && sign2 < 0)
3979 3 : ereport(ERROR,
991 tgl 3980 ECB : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
3981 : errmsg("zero raised to a negative power is undefined")));
991 tgl 3982 GIC 66 : if (sign1 < 0 && !numeric_is_integral(num2))
3983 3 : ereport(ERROR,
3984 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
991 tgl 3985 ECB : errmsg("a negative number raised to a non-integer power yields a complex result")));
3986 :
3987 : /*
3988 : * POSIX gives this series of rules for pow(3) with infinite inputs:
3989 : *
3990 : * For any value of y, if x is +1, 1.0 shall be returned.
3991 : */
991 tgl 3992 CBC 63 : if (!NUMERIC_IS_SPECIAL(num1))
1788 tgl 3993 ECB : {
991 tgl 3994 GIC 21 : init_var_from_num(num1, &arg1);
991 tgl 3995 CBC 21 : if (cmp_var(&arg1, &const_one) == 0)
1788 tgl 3996 GIC 3 : PG_RETURN_NUMERIC(make_result(&const_one));
1788 tgl 3997 ECB : }
3998 :
991 3999 : /*
4000 : * For any value of x, if y is [-]0, 1.0 shall be returned.
4001 : */
991 tgl 4002 GIC 60 : if (sign2 == 0)
1788 4003 6 : PG_RETURN_NUMERIC(make_result(&const_one));
4004 :
991 tgl 4005 ECB : /*
4006 : * For any odd integer value of y > 0, if x is [-]0, [-]0 shall be
4007 : * returned. For y > 0 and not an odd integer, if x is [-]0, +0 shall
4008 : * be returned. (Since we don't deal in minus zero, we need not
4009 : * distinguish these two cases.)
4010 : */
991 tgl 4011 GIC 54 : if (sign1 == 0 && sign2 > 0)
4012 3 : PG_RETURN_NUMERIC(make_result(&const_zero));
991 tgl 4013 ECB :
4014 : /*
4015 : * If x is -1, and y is [-]Inf, 1.0 shall be returned.
4016 : *
4017 : * For |x| < 1, if y is -Inf, +Inf shall be returned.
4018 : *
4019 : * For |x| > 1, if y is -Inf, +0 shall be returned.
4020 : *
4021 : * For |x| < 1, if y is +Inf, +0 shall be returned.
4022 : *
4023 : * For |x| > 1, if y is +Inf, +Inf shall be returned.
4024 : */
991 tgl 4025 GIC 51 : if (NUMERIC_IS_INF(num2))
4026 : {
4027 : bool abs_x_gt_one;
4028 :
991 tgl 4029 CBC 27 : if (NUMERIC_IS_SPECIAL(num1))
991 tgl 4030 GIC 12 : abs_x_gt_one = true; /* x is either Inf or -Inf */
991 tgl 4031 ECB : else
4032 : {
991 tgl 4033 GIC 15 : init_var_from_num(num1, &arg1);
4034 15 : if (cmp_var(&arg1, &const_minus_one) == 0)
4035 3 : PG_RETURN_NUMERIC(make_result(&const_one));
4036 12 : arg1.sign = NUMERIC_POS; /* now arg1 = abs(x) */
4037 12 : abs_x_gt_one = (cmp_var(&arg1, &const_one) > 0);
4038 : }
4039 24 : if (abs_x_gt_one == (sign2 > 0))
4040 15 : PG_RETURN_NUMERIC(make_result(&const_pinf));
4041 : else
4042 9 : PG_RETURN_NUMERIC(make_result(&const_zero));
991 tgl 4043 ECB : }
4044 :
4045 : /*
4046 : * For y < 0, if x is +Inf, +0 shall be returned.
4047 : *
4048 : * For y > 0, if x is +Inf, +Inf shall be returned.
4049 : */
991 tgl 4050 CBC 24 : if (NUMERIC_IS_PINF(num1))
4051 : {
4052 12 : if (sign2 > 0)
991 tgl 4053 GIC 9 : PG_RETURN_NUMERIC(make_result(&const_pinf));
991 tgl 4054 ECB : else
991 tgl 4055 CBC 3 : PG_RETURN_NUMERIC(make_result(&const_zero));
991 tgl 4056 ECB : }
4057 :
991 tgl 4058 CBC 12 : Assert(NUMERIC_IS_NINF(num1));
4059 :
991 tgl 4060 ECB : /*
4061 : * For y an odd integer < 0, if x is -Inf, -0 shall be returned. For
4062 : * y < 0 and not an odd integer, if x is -Inf, +0 shall be returned.
4063 : * (Again, we need not distinguish these two cases.)
4064 : */
991 tgl 4065 CBC 12 : if (sign2 < 0)
4066 6 : PG_RETURN_NUMERIC(make_result(&const_zero));
4067 :
991 tgl 4068 ECB : /*
4069 : * For y an odd integer > 0, if x is -Inf, -Inf shall be returned. For
4070 : * y > 0 and not an odd integer, if x is -Inf, +Inf shall be returned.
4071 : */
991 tgl 4072 CBC 6 : init_var_from_num(num2, &arg2);
4073 6 : if (arg2.ndigits > 0 && arg2.ndigits == arg2.weight + 1 &&
4074 6 : (arg2.digits[arg2.ndigits - 1] & 1))
991 tgl 4075 GIC 3 : PG_RETURN_NUMERIC(make_result(&const_ninf));
4076 : else
991 tgl 4077 CBC 3 : PG_RETURN_NUMERIC(make_result(&const_pinf));
991 tgl 4078 ECB : }
4079 :
4080 : /*
4081 : * The SQL spec requires that we emit a particular SQLSTATE error code for
4082 : * certain error conditions. Specifically, we don't return a
4083 : * divide-by-zero error code for 0 ^ -1. Raising a negative number to a
4084 : * non-integer power must produce the same error code, but that case is
4085 : * handled in power_var().
4086 : */
991 tgl 4087 CBC 576 : sign1 = numeric_sign_internal(num1);
991 tgl 4088 GIC 576 : sign2 = numeric_sign_internal(num2);
991 tgl 4089 ECB :
991 tgl 4090 CBC 576 : if (sign1 == 0 && sign2 < 0)
6902 neilc 4091 6 : ereport(ERROR,
4092 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
4093 : errmsg("zero raised to a negative power is undefined")));
4094 :
4095 : /*
4096 : * Initialize things
991 tgl 4097 ECB : */
991 tgl 4098 CBC 570 : init_var(&result);
991 tgl 4099 GIC 570 : init_var_from_num(num1, &arg1);
4100 570 : init_var_from_num(num2, &arg2);
4101 :
4102 : /*
4103 : * Call power_var() to compute and return the result; note it handles
4104 : * scale selection itself.
4105 : */
8866 JanWieck 4106 CBC 570 : power_var(&arg1, &arg2, &result);
8866 JanWieck 4107 ECB :
8866 JanWieck 4108 GIC 555 : res = make_result(&result);
4109 :
4110 555 : free_var(&result);
4111 :
8289 tgl 4112 555 : PG_RETURN_NUMERIC(res);
4113 : }
4114 :
4115 : /*
4116 : * numeric_scale() -
4117 : *
4118 : * Returns the scale, i.e. the count of decimal digits in the fractional part
4119 : */
2651 alvherre 4120 ECB : Datum
2651 alvherre 4121 GIC 54 : numeric_scale(PG_FUNCTION_ARGS)
4122 : {
4123 54 : Numeric num = PG_GETARG_NUMERIC(0);
2651 alvherre 4124 ECB :
991 tgl 4125 CBC 54 : if (NUMERIC_IS_SPECIAL(num))
2651 alvherre 4126 GIC 9 : PG_RETURN_NULL();
4127 :
2651 alvherre 4128 CBC 45 : PG_RETURN_INT32(NUMERIC_DSCALE(num));
2651 alvherre 4129 ECB : }
4130 :
1189 tgl 4131 : /*
4132 : * Calculate minimum scale for value.
4133 : */
4134 : static int
1189 tgl 4135 CBC 63 : get_min_scale(NumericVar *var)
4136 : {
1189 tgl 4137 ECB : int min_scale;
4138 : int last_digit_pos;
4139 :
4140 : /*
4141 : * Ordinarily, the input value will be "stripped" so that the last
4142 : * NumericDigit is nonzero. But we don't want to get into an infinite
4143 : * loop if it isn't, so explicitly find the last nonzero digit.
4144 : */
1189 tgl 4145 CBC 63 : last_digit_pos = var->ndigits - 1;
1189 tgl 4146 GIC 63 : while (last_digit_pos >= 0 &&
1189 tgl 4147 CBC 51 : var->digits[last_digit_pos] == 0)
1189 tgl 4148 LBC 0 : last_digit_pos--;
4149 :
1189 tgl 4150 CBC 63 : if (last_digit_pos >= 0)
4151 : {
4152 : /* compute min_scale assuming that last ndigit has no zeroes */
4153 51 : min_scale = (last_digit_pos - var->weight) * DEC_DIGITS;
4154 :
4155 : /*
4156 : * We could get a negative result if there are no digits after the
4157 : * decimal point. In this case the min_scale must be zero.
4158 : */
1189 tgl 4159 GIC 51 : if (min_scale > 0)
1189 tgl 4160 ECB : {
4161 : /*
4162 : * Reduce min_scale if trailing digit(s) in last NumericDigit are
4163 : * zero.
4164 : */
1189 tgl 4165 GIC 33 : NumericDigit last_digit = var->digits[last_digit_pos];
4166 :
1189 tgl 4167 CBC 99 : while (last_digit % 10 == 0)
1189 tgl 4168 ECB : {
1189 tgl 4169 CBC 66 : min_scale--;
4170 66 : last_digit /= 10;
4171 : }
1189 tgl 4172 ECB : }
4173 : else
1189 tgl 4174 GIC 18 : min_scale = 0;
4175 : }
4176 : else
4177 12 : min_scale = 0; /* result if input is zero */
4178 :
4179 63 : return min_scale;
4180 : }
4181 :
1189 tgl 4182 ECB : /*
4183 : * Returns minimum scale required to represent supplied value without loss.
4184 : */
4185 : Datum
1189 tgl 4186 CBC 36 : numeric_min_scale(PG_FUNCTION_ARGS)
4187 : {
1189 tgl 4188 GIC 36 : Numeric num = PG_GETARG_NUMERIC(0);
4189 : NumericVar arg;
4190 : int min_scale;
4191 :
991 4192 36 : if (NUMERIC_IS_SPECIAL(num))
1189 tgl 4193 CBC 6 : PG_RETURN_NULL();
1189 tgl 4194 ECB :
1189 tgl 4195 CBC 30 : init_var_from_num(num, &arg);
1189 tgl 4196 GIC 30 : min_scale = get_min_scale(&arg);
4197 30 : free_var(&arg);
4198 :
4199 30 : PG_RETURN_INT32(min_scale);
4200 : }
1189 tgl 4201 ECB :
4202 : /*
4203 : * Reduce scale of numeric value to represent supplied value without loss.
4204 : */
4205 : Datum
1189 tgl 4206 GIC 39 : numeric_trim_scale(PG_FUNCTION_ARGS)
1189 tgl 4207 ECB : {
1189 tgl 4208 GIC 39 : Numeric num = PG_GETARG_NUMERIC(0);
4209 : Numeric res;
4210 : NumericVar result;
4211 :
991 4212 39 : if (NUMERIC_IS_SPECIAL(num))
4213 6 : PG_RETURN_NUMERIC(duplicate_numeric(num));
4214 :
1189 4215 33 : init_var_from_num(num, &result);
1189 tgl 4216 CBC 33 : result.dscale = get_min_scale(&result);
1189 tgl 4217 GIC 33 : res = make_result(&result);
1189 tgl 4218 CBC 33 : free_var(&result);
4219 :
4220 33 : PG_RETURN_NUMERIC(res);
1189 tgl 4221 ECB : }
4222 :
8866 JanWieck 4223 :
4224 : /* ----------------------------------------------------------------------
4225 : *
4226 : * Type conversion functions
4227 : *
4228 : * ----------------------------------------------------------------------
4229 : */
8445 tgl 4230 :
4231 : Numeric
942 peter 4232 GIC 906490 : int64_to_numeric(int64 val)
4233 : {
4234 : Numeric res;
4235 : NumericVar result;
4236 :
8866 JanWieck 4237 906490 : init_var(&result);
4238 :
942 peter 4239 906490 : int64_to_numericvar(val, &result);
7324 tgl 4240 ECB :
8866 JanWieck 4241 CBC 906490 : res = make_result(&result);
8866 JanWieck 4242 ECB :
8866 JanWieck 4243 GBC 906490 : free_var(&result);
4244 :
942 peter 4245 CBC 906490 : return res;
4246 : }
4247 :
733 peter 4248 ECB : /*
4249 : * Convert val1/(10**log10val2) to numeric. This is much faster than normal
4250 : * numeric division.
4251 : */
4252 : Numeric
733 peter 4253 GIC 14600 : int64_div_fast_to_numeric(int64 val1, int log10val2)
733 peter 4254 ECB : {
4255 : Numeric res;
4256 : NumericVar result;
4257 : int rscale;
4258 : int w;
4259 : int m;
4260 :
65 dean.a.rasheed 4261 GIC 14600 : init_var(&result);
65 dean.a.rasheed 4262 ECB :
4263 : /* result scale */
65 dean.a.rasheed 4264 CBC 14600 : rscale = log10val2 < 0 ? 0 : log10val2;
65 dean.a.rasheed 4265 ECB :
4266 : /* how much to decrease the weight by */
733 peter 4267 GIC 14600 : w = log10val2 / DEC_DIGITS;
4268 : /* how much is left to divide by */
733 peter 4269 CBC 14600 : m = log10val2 % DEC_DIGITS;
65 dean.a.rasheed 4270 GIC 14600 : if (m < 0)
4271 : {
65 dean.a.rasheed 4272 LBC 0 : m += DEC_DIGITS;
65 dean.a.rasheed 4273 UIC 0 : w--;
65 dean.a.rasheed 4274 ECB : }
4275 :
4276 : /*
4277 : * If there is anything left to divide by (10^m with 0 < m < DEC_DIGITS),
4278 : * multiply the dividend by 10^(DEC_DIGITS - m), and shift the weight by
4279 : * one more.
4280 : */
733 peter 4281 CBC 14600 : if (m > 0)
4282 : {
66 dean.a.rasheed 4283 ECB : #if DEC_DIGITS == 4
4284 : static const int pow10[] = {1, 10, 100, 1000};
4285 : #elif DEC_DIGITS == 2
4286 : static const int pow10[] = {1, 10};
4287 : #elif DEC_DIGITS == 1
65 4288 : static const int pow10[] = {1};
4289 : #else
66 4290 : #error unsupported NBASE
4291 : #endif
65 dean.a.rasheed 4292 CBC 14600 : int64 factor = pow10[DEC_DIGITS - m];
4293 : int64 new_val1;
733 peter 4294 ECB :
4295 : StaticAssertDecl(lengthof(pow10) == DEC_DIGITS, "mismatch with DEC_DIGITS");
4296 :
65 dean.a.rasheed 4297 GIC 14600 : if (unlikely(pg_mul_s64_overflow(val1, factor, &new_val1)))
4298 : {
4299 : #ifdef HAVE_INT128
4300 : /* do the multiplication using 128-bit integers */
65 dean.a.rasheed 4301 ECB : int128 tmp;
4302 :
65 dean.a.rasheed 4303 CBC 6 : tmp = (int128) val1 * (int128) factor;
4304 :
65 dean.a.rasheed 4305 GIC 6 : int128_to_numericvar(tmp, &result);
4306 : #else
65 dean.a.rasheed 4307 ECB : /* do the multiplication using numerics */
4308 : NumericVar tmp;
4309 :
4310 : init_var(&tmp);
4311 :
4312 : int64_to_numericvar(val1, &result);
4313 : int64_to_numericvar(factor, &tmp);
4314 : mul_var(&result, &tmp, &result, 0);
4315 :
4316 : free_var(&tmp);
4317 : #endif
4318 : }
4319 : else
65 dean.a.rasheed 4320 GIC 14594 : int64_to_numericvar(new_val1, &result);
4321 :
733 peter 4322 14600 : w++;
4323 : }
4324 : else
65 dean.a.rasheed 4325 UIC 0 : int64_to_numericvar(val1, &result);
4326 :
733 peter 4327 CBC 14600 : result.weight -= w;
65 dean.a.rasheed 4328 GIC 14600 : result.dscale = rscale;
4329 :
733 peter 4330 14600 : res = make_result(&result);
4331 :
733 peter 4332 CBC 14600 : free_var(&result);
4333 :
4334 14600 : return res;
4335 : }
733 peter 4336 ECB :
4337 : Datum
942 peter 4338 CBC 760051 : int4_numeric(PG_FUNCTION_ARGS)
4339 : {
4340 760051 : int32 val = PG_GETARG_INT32(0);
4341 :
942 peter 4342 GIC 760051 : PG_RETURN_NUMERIC(int64_to_numeric(val));
4343 : }
4344 :
4345 : int32
1485 akorotkov 4346 2777 : numeric_int4_opt_error(Numeric num, bool *have_error)
4347 : {
8482 tgl 4348 ECB : NumericVar x;
4349 : int32 result;
4350 :
1343 michael 4351 GIC 2777 : if (have_error)
4352 144 : *have_error = false;
4353 :
991 tgl 4354 2777 : if (NUMERIC_IS_SPECIAL(num))
4355 : {
1485 akorotkov 4356 CBC 9 : if (have_error)
4357 : {
1485 akorotkov 4358 UIC 0 : *have_error = true;
1485 akorotkov 4359 LBC 0 : return 0;
4360 : }
4361 : else
1485 akorotkov 4362 ECB : {
991 tgl 4363 GIC 9 : if (NUMERIC_IS_NAN(num))
991 tgl 4364 CBC 3 : ereport(ERROR,
991 tgl 4365 ECB : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4366 : errmsg("cannot convert NaN to %s", "integer")));
991 tgl 4367 EUB : else
991 tgl 4368 GBC 6 : ereport(ERROR,
4369 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4370 : errmsg("cannot convert infinity to %s", "integer")));
4371 : }
4372 : }
4373 :
4374 : /* Convert to variable format, then convert to int4 */
3791 heikki.linnakangas 4375 GIC 2768 : init_var_from_num(num, &x);
1485 akorotkov 4376 ECB :
1485 akorotkov 4377 GIC 2768 : if (!numericvar_to_int32(&x, &result))
4378 : {
4379 18 : if (have_error)
4380 : {
4381 12 : *have_error = true;
4382 12 : return 0;
4383 : }
4384 : else
4385 : {
4386 6 : ereport(ERROR,
1485 akorotkov 4387 ECB : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4388 : errmsg("integer out of range")));
4389 : }
4390 : }
4391 :
1485 akorotkov 4392 CBC 2750 : return result;
4393 : }
4394 :
4395 : Datum
1485 akorotkov 4396 GIC 2633 : numeric_int4(PG_FUNCTION_ARGS)
4397 : {
1485 akorotkov 4398 CBC 2633 : Numeric num = PG_GETARG_NUMERIC(0);
4399 :
4400 2633 : PG_RETURN_INT32(numeric_int4_opt_error(num, NULL));
4401 : }
4402 :
4403 : /*
4404 : * Given a NumericVar, convert it to an int32. If the NumericVar
4405 : * exceeds the range of an int32, false is returned, otherwise true is returned.
4406 : * The input NumericVar is *not* free'd.
4407 : */
4408 : static bool
1485 akorotkov 4409 GIC 3137 : numericvar_to_int32(const NumericVar *var, int32 *result)
4410 : {
4411 : int64 val;
4412 :
2942 andres 4413 3137 : if (!numericvar_to_int64(var, &val))
1485 akorotkov 4414 UIC 0 : return false;
8482 tgl 4415 ECB :
611 dean.a.rasheed 4416 GIC 3137 : if (unlikely(val < PG_INT32_MIN) || unlikely(val > PG_INT32_MAX))
611 dean.a.rasheed 4417 CBC 18 : return false;
4418 :
4419 : /* Down-convert to int4 */
1485 akorotkov 4420 GBC 3119 : *result = (int32) val;
4421 :
611 dean.a.rasheed 4422 CBC 3119 : return true;
8866 JanWieck 4423 ECB : }
4424 :
8301 tgl 4425 : Datum
8301 tgl 4426 GIC 6378 : int8_numeric(PG_FUNCTION_ARGS)
8445 tgl 4427 ECB : {
7324 tgl 4428 GIC 6378 : int64 val = PG_GETARG_INT64(0);
8445 tgl 4429 ECB :
942 peter 4430 GIC 6378 : PG_RETURN_NUMERIC(int64_to_numeric(val));
4431 : }
4432 :
8445 tgl 4433 ECB :
4434 : Datum
8289 tgl 4435 CBC 258 : numeric_int8(PG_FUNCTION_ARGS)
4436 : {
4437 258 : Numeric num = PG_GETARG_NUMERIC(0);
4438 : NumericVar x;
4439 : int64 result;
4440 :
991 4441 258 : if (NUMERIC_IS_SPECIAL(num))
4442 : {
991 tgl 4443 GIC 9 : if (NUMERIC_IS_NAN(num))
4444 3 : ereport(ERROR,
4445 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
651 peter 4446 ECB : errmsg("cannot convert NaN to %s", "bigint")));
991 tgl 4447 : else
991 tgl 4448 GIC 6 : ereport(ERROR,
991 tgl 4449 ECB : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4450 : errmsg("cannot convert infinity to %s", "bigint")));
4451 : }
4452 :
7324 tgl 4453 EUB : /* Convert to variable format and thence to int8 */
3791 heikki.linnakangas 4454 GBC 249 : init_var_from_num(num, &x);
4455 :
2942 andres 4456 GIC 249 : if (!numericvar_to_int64(&x, &result))
7196 tgl 4457 24 : ereport(ERROR,
7196 tgl 4458 ECB : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
6761 4459 : errmsg("bigint out of range")));
4460 :
7324 tgl 4461 GIC 225 : PG_RETURN_INT64(result);
4462 : }
8445 tgl 4463 ECB :
4464 :
4465 : Datum
8343 tgl 4466 GIC 3 : int2_numeric(PG_FUNCTION_ARGS)
4467 : {
4468 3 : int16 val = PG_GETARG_INT16(0);
4469 :
942 peter 4470 CBC 3 : PG_RETURN_NUMERIC(int64_to_numeric(val));
4471 : }
8445 tgl 4472 ECB :
4473 :
8343 4474 : Datum
8343 tgl 4475 GIC 48 : numeric_int2(PG_FUNCTION_ARGS)
8445 tgl 4476 ECB : {
8343 tgl 4477 CBC 48 : Numeric num = PG_GETARG_NUMERIC(0);
4478 : NumericVar x;
4479 : int64 val;
4480 : int16 result;
8445 tgl 4481 ECB :
991 tgl 4482 GIC 48 : if (NUMERIC_IS_SPECIAL(num))
4483 : {
4484 9 : if (NUMERIC_IS_NAN(num))
4485 3 : ereport(ERROR,
4486 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
651 peter 4487 ECB : errmsg("cannot convert NaN to %s", "smallint")));
4488 : else
991 tgl 4489 GIC 6 : ereport(ERROR,
4490 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
651 peter 4491 ECB : errmsg("cannot convert infinity to %s", "smallint")));
4492 : }
8445 tgl 4493 :
4494 : /* Convert to variable format and thence to int8 */
3791 heikki.linnakangas 4495 CBC 39 : init_var_from_num(num, &x);
4496 :
2942 andres 4497 GIC 39 : if (!numericvar_to_int64(&x, &val))
7196 tgl 4498 UIC 0 : ereport(ERROR,
4499 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4500 : errmsg("smallint out of range")));
4501 :
611 dean.a.rasheed 4502 GIC 39 : if (unlikely(val < PG_INT16_MIN) || unlikely(val > PG_INT16_MAX))
7196 tgl 4503 6 : ereport(ERROR,
7196 tgl 4504 ECB : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4505 : errmsg("smallint out of range")));
4506 :
4507 : /* Down-convert to int2 */
611 dean.a.rasheed 4508 CBC 33 : result = (int16) val;
611 dean.a.rasheed 4509 EUB :
7324 tgl 4510 GIC 33 : PG_RETURN_INT16(result);
8445 tgl 4511 ECB : }
4512 :
4513 :
4514 : Datum
8289 tgl 4515 CBC 417 : float8_numeric(PG_FUNCTION_ARGS)
4516 : {
4517 417 : float8 val = PG_GETARG_FLOAT8(0);
4518 : Numeric res;
4519 : NumericVar result;
4520 : char buf[DBL_DIG + 100];
4521 : const char *endptr;
8866 JanWieck 4522 ECB :
8289 tgl 4523 GIC 417 : if (isnan(val))
8289 tgl 4524 CBC 3 : PG_RETURN_NUMERIC(make_result(&const_nan));
4525 :
2020 4526 414 : if (isinf(val))
4527 : {
991 tgl 4528 GIC 6 : if (val < 0)
4529 3 : PG_RETURN_NUMERIC(make_result(&const_ninf));
4530 : else
991 tgl 4531 CBC 3 : PG_RETURN_NUMERIC(make_result(&const_pinf));
4532 : }
2020 tgl 4533 ECB :
2020 tgl 4534 GIC 408 : snprintf(buf, sizeof(buf), "%.*g", DBL_DIG, val);
4535 :
8866 JanWieck 4536 408 : init_var(&result);
8866 JanWieck 4537 ECB :
4538 : /* Assume we need not worry about leading/trailing spaces */
121 tgl 4539 GNC 408 : (void) set_var_from_str(buf, buf, &result, &endptr, NULL);
5114 tgl 4540 ECB :
8866 JanWieck 4541 GIC 408 : res = make_result(&result);
4542 :
4543 408 : free_var(&result);
8866 JanWieck 4544 ECB :
8289 tgl 4545 GIC 408 : PG_RETURN_NUMERIC(res);
4546 : }
4547 :
4548 :
4549 : Datum
8289 tgl 4550 CBC 259429 : numeric_float8(PG_FUNCTION_ARGS)
4551 : {
4552 259429 : Numeric num = PG_GETARG_NUMERIC(0);
8720 bruce 4553 ECB : char *tmp;
4554 : Datum result;
4555 :
991 tgl 4556 GIC 259429 : if (NUMERIC_IS_SPECIAL(num))
991 tgl 4557 ECB : {
991 tgl 4558 GIC 39 : if (NUMERIC_IS_PINF(num))
4559 12 : PG_RETURN_FLOAT8(get_float8_infinity());
4560 27 : else if (NUMERIC_IS_NINF(num))
4561 12 : PG_RETURN_FLOAT8(-get_float8_infinity());
991 tgl 4562 ECB : else
991 tgl 4563 GIC 15 : PG_RETURN_FLOAT8(get_float8_nan());
991 tgl 4564 ECB : }
4565 :
8335 tgl 4566 CBC 259390 : tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
4567 : NumericGetDatum(num)));
4568 :
8286 tgl 4569 GIC 259390 : result = DirectFunctionCall1(float8in, CStringGetDatum(tmp));
4570 :
8866 JanWieck 4571 CBC 259390 : pfree(tmp);
4572 :
8286 tgl 4573 259390 : PG_RETURN_DATUM(result);
4574 : }
4575 :
4576 :
4577 : /*
2293 peter_e 4578 ECB : * Convert numeric to float8; if out of range, return +/- HUGE_VAL
4579 : *
4580 : * (internal helper function, not directly callable from SQL)
4581 : */
4582 : Datum
7848 tgl 4583 GIC 1433 : numeric_float8_no_overflow(PG_FUNCTION_ARGS)
4584 : {
7848 tgl 4585 CBC 1433 : Numeric num = PG_GETARG_NUMERIC(0);
4586 : double val;
4587 :
991 tgl 4588 GIC 1433 : if (NUMERIC_IS_SPECIAL(num))
4589 : {
991 tgl 4590 UIC 0 : if (NUMERIC_IS_PINF(num))
991 tgl 4591 LBC 0 : val = HUGE_VAL;
991 tgl 4592 UIC 0 : else if (NUMERIC_IS_NINF(num))
991 tgl 4593 LBC 0 : val = -HUGE_VAL;
991 tgl 4594 EUB : else
991 tgl 4595 UIC 0 : val = get_float8_nan();
4596 : }
4597 : else
991 tgl 4598 ECB : {
4599 : NumericVar x;
4600 :
991 tgl 4601 GIC 1433 : init_var_from_num(num, &x);
4602 1433 : val = numericvar_to_double_no_overflow(&x);
4603 : }
7848 tgl 4604 ECB :
7848 tgl 4605 GIC 1433 : PG_RETURN_FLOAT8(val);
7848 tgl 4606 ECB : }
4607 :
4608 : Datum
8289 tgl 4609 GIC 10788 : float4_numeric(PG_FUNCTION_ARGS)
4610 : {
8289 tgl 4611 CBC 10788 : float4 val = PG_GETARG_FLOAT4(0);
4612 : Numeric res;
8866 JanWieck 4613 ECB : NumericVar result;
4614 : char buf[FLT_DIG + 100];
4615 : const char *endptr;
4616 :
8289 tgl 4617 GIC 10788 : if (isnan(val))
4618 3 : PG_RETURN_NUMERIC(make_result(&const_nan));
4619 :
2020 tgl 4620 CBC 10785 : if (isinf(val))
991 tgl 4621 ECB : {
991 tgl 4622 GIC 6 : if (val < 0)
991 tgl 4623 CBC 3 : PG_RETURN_NUMERIC(make_result(&const_ninf));
4624 : else
4625 3 : PG_RETURN_NUMERIC(make_result(&const_pinf));
991 tgl 4626 ECB : }
4627 :
2020 tgl 4628 CBC 10779 : snprintf(buf, sizeof(buf), "%.*g", FLT_DIG, val);
4629 :
8866 JanWieck 4630 GIC 10779 : init_var(&result);
8866 JanWieck 4631 ECB :
4632 : /* Assume we need not worry about leading/trailing spaces */
121 tgl 4633 GNC 10779 : (void) set_var_from_str(buf, buf, &result, &endptr, NULL);
4634 :
8866 JanWieck 4635 GIC 10779 : res = make_result(&result);
8866 JanWieck 4636 ECB :
8866 JanWieck 4637 GIC 10779 : free_var(&result);
8866 JanWieck 4638 ECB :
8289 tgl 4639 GIC 10779 : PG_RETURN_NUMERIC(res);
8866 JanWieck 4640 ECB : }
4641 :
4642 :
4643 : Datum
8289 tgl 4644 GIC 1090 : numeric_float4(PG_FUNCTION_ARGS)
4645 : {
4646 1090 : Numeric num = PG_GETARG_NUMERIC(0);
8720 bruce 4647 ECB : char *tmp;
4648 : Datum result;
8866 JanWieck 4649 :
991 tgl 4650 GIC 1090 : if (NUMERIC_IS_SPECIAL(num))
4651 : {
4652 39 : if (NUMERIC_IS_PINF(num))
991 tgl 4653 CBC 12 : PG_RETURN_FLOAT4(get_float4_infinity());
991 tgl 4654 GIC 27 : else if (NUMERIC_IS_NINF(num))
991 tgl 4655 CBC 12 : PG_RETURN_FLOAT4(-get_float4_infinity());
991 tgl 4656 ECB : else
991 tgl 4657 CBC 15 : PG_RETURN_FLOAT4(get_float4_nan());
991 tgl 4658 ECB : }
4659 :
8335 tgl 4660 CBC 1051 : tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
4661 : NumericGetDatum(num)));
4662 :
8286 4663 1051 : result = DirectFunctionCall1(float4in, CStringGetDatum(tmp));
4664 :
8866 JanWieck 4665 GIC 1051 : pfree(tmp);
8866 JanWieck 4666 ECB :
8286 tgl 4667 GIC 1051 : PG_RETURN_DATUM(result);
8866 JanWieck 4668 ECB : }
4669 :
4670 :
4671 : Datum
1013 fujii 4672 GIC 45 : numeric_pg_lsn(PG_FUNCTION_ARGS)
4673 : {
4674 45 : Numeric num = PG_GETARG_NUMERIC(0);
4675 : NumericVar x;
4676 : XLogRecPtr result;
4677 :
991 tgl 4678 45 : if (NUMERIC_IS_SPECIAL(num))
4679 : {
991 tgl 4680 CBC 3 : if (NUMERIC_IS_NAN(num))
991 tgl 4681 GIC 3 : ereport(ERROR,
991 tgl 4682 ECB : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4683 : errmsg("cannot convert NaN to %s", "pg_lsn")));
4684 : else
991 tgl 4685 LBC 0 : ereport(ERROR,
4686 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
651 peter 4687 EUB : errmsg("cannot convert infinity to %s", "pg_lsn")));
991 tgl 4688 : }
1013 fujii 4689 :
4690 : /* Convert to variable format and thence to pg_lsn */
1013 fujii 4691 GIC 42 : init_var_from_num(num, &x);
1013 fujii 4692 EUB :
1013 fujii 4693 GIC 42 : if (!numericvar_to_uint64(&x, (uint64 *) &result))
4694 12 : ereport(ERROR,
4695 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4696 : errmsg("pg_lsn out of range")));
4697 :
1013 fujii 4698 CBC 30 : PG_RETURN_LSN(result);
1013 fujii 4699 ECB : }
4700 :
4701 :
8301 tgl 4702 : /* ----------------------------------------------------------------------
4703 : *
4704 : * Aggregate functions
4705 : *
3431 4706 : * The transition datatype for all these aggregates is declared as INTERNAL.
4707 : * Actually, it's a pointer to a NumericAggState allocated in the aggregate
4708 : * context. The digit buffers for the NumericVars will be there too.
4709 : *
4710 : * On platforms which support 128-bit integers some aggregates instead use a
4711 : * 128-bit integer based transition datatype to speed up calculations.
4712 : *
4713 : * ----------------------------------------------------------------------
8301 4714 : */
4715 :
4716 : typedef struct NumericAggState
3431 4717 : {
4718 : bool calcSumX2; /* if true, calculate sumX2 */
4719 : MemoryContext agg_context; /* context we're calculating in */
4720 : int64 N; /* count of processed numbers */
4721 : NumericSumAccum sumX; /* sum of processed numbers */
2410 heikki.linnakangas 4722 : NumericSumAccum sumX2; /* sum of squares of processed numbers */
4723 : int maxScale; /* maximum scale seen so far */
4724 : int64 maxScaleCount; /* number of values seen with maximum scale */
991 tgl 4725 : /* These counts are *not* included in N! Use NA_TOTAL_COUNT() as needed */
4726 : int64 NaNcount; /* count of NaN values */
4727 : int64 pInfcount; /* count of +Inf values */
4728 : int64 nInfcount; /* count of -Inf values */
4729 : } NumericAggState;
8301 4730 :
4731 : #define NA_TOTAL_COUNT(na) \
991 4732 : ((na)->N + (na)->NaNcount + (na)->pInfcount + (na)->nInfcount)
4733 :
3431 4734 : /*
4735 : * Prepare state data for a numeric aggregate function that needs to compute
4736 : * sum, count and optionally sum of squares of the input.
4737 : */
4738 : static NumericAggState *
3431 tgl 4739 GIC 85568 : makeNumericAggState(FunctionCallInfo fcinfo, bool calcSumX2)
4740 : {
3431 tgl 4741 ECB : NumericAggState *state;
4742 : MemoryContext agg_context;
4743 : MemoryContext old_context;
4744 :
3431 tgl 4745 GIC 85568 : if (!AggCheckCallContext(fcinfo, &agg_context))
3431 tgl 4746 UIC 0 : elog(ERROR, "aggregate function called in non-aggregate context");
3431 tgl 4747 ECB :
3431 tgl 4748 GIC 85568 : old_context = MemoryContextSwitchTo(agg_context);
3431 tgl 4749 ECB :
3431 tgl 4750 CBC 85568 : state = (NumericAggState *) palloc0(sizeof(NumericAggState));
4751 85568 : state->calcSumX2 = calcSumX2;
4752 85568 : state->agg_context = agg_context;
4753 :
4754 85568 : MemoryContextSwitchTo(old_context);
4755 :
3431 tgl 4756 GIC 85568 : return state;
8301 tgl 4757 ECB : }
4758 :
4759 : /*
2481 4760 : * Like makeNumericAggState(), but allocate the state in the current memory
4761 : * context.
4762 : */
4763 : static NumericAggState *
2481 tgl 4764 CBC 40 : makeNumericAggStateCurrentContext(bool calcSumX2)
4765 : {
4766 : NumericAggState *state;
4767 :
2481 tgl 4768 GIC 40 : state = (NumericAggState *) palloc0(sizeof(NumericAggState));
2481 tgl 4769 CBC 40 : state->calcSumX2 = calcSumX2;
2481 tgl 4770 GIC 40 : state->agg_context = CurrentMemoryContext;
2481 tgl 4771 ECB :
2481 tgl 4772 GIC 40 : return state;
4773 : }
4774 :
5895 bruce 4775 ECB : /*
4776 : * Accumulate a new input value for numeric aggregate functions.
4777 : */
3431 tgl 4778 : static void
3431 tgl 4779 GIC 1056776 : do_numeric_accum(NumericAggState *state, Numeric newval)
4780 : {
4781 : NumericVar X;
3431 tgl 4782 EUB : NumericVar X2;
4783 : MemoryContext old_context;
4784 :
4785 : /* Count NaN/infinity inputs separately from all else */
991 tgl 4786 GIC 1056776 : if (NUMERIC_IS_SPECIAL(newval))
4787 : {
991 tgl 4788 CBC 81 : if (NUMERIC_IS_PINF(newval))
991 tgl 4789 GIC 36 : state->pInfcount++;
991 tgl 4790 CBC 45 : else if (NUMERIC_IS_NINF(newval))
4791 18 : state->nInfcount++;
4792 : else
991 tgl 4793 GIC 27 : state->NaNcount++;
3431 4794 81 : return;
3431 tgl 4795 ECB : }
4796 :
4797 : /* load processed number in short-lived context */
3431 tgl 4798 GIC 1056695 : init_var_from_num(newval, &X);
4799 :
4800 : /*
4801 : * Track the highest input dscale that we've seen, to support inverse
4802 : * transitions (see do_numeric_discard).
4803 : */
3284 4804 1056695 : if (X.dscale > state->maxScale)
4805 : {
4806 78 : state->maxScale = X.dscale;
4807 78 : state->maxScaleCount = 1;
4808 : }
4809 1056617 : else if (X.dscale == state->maxScale)
4810 1056599 : state->maxScaleCount++;
4811 :
4812 : /* if we need X^2, calculate that in short-lived context */
3431 4813 1056695 : if (state->calcSumX2)
4814 : {
4815 120366 : init_var(&X2);
4816 120366 : mul_var(&X, &X, &X2, X.dscale * 2);
4817 : }
4818 :
4819 : /* The rest of this needs to work in the aggregate context */
4820 1056695 : old_context = MemoryContextSwitchTo(state->agg_context);
4821 :
2410 heikki.linnakangas 4822 1056695 : state->N++;
4823 :
4824 : /* Accumulate sums */
4825 1056695 : accum_sum_add(&(state->sumX), &X);
4826 :
4827 1056695 : if (state->calcSumX2)
4828 120366 : accum_sum_add(&(state->sumX2), &X2);
4829 :
3431 tgl 4830 1056695 : MemoryContextSwitchTo(old_context);
4831 : }
4832 :
4833 : /*
4834 : * Attempt to remove an input value from the aggregated state.
4835 : *
3284 tgl 4836 ECB : * If the value cannot be removed then the function will return false; the
4837 : * possible reasons for failing are described below.
4838 : *
4839 : * If we aggregate the values 1.01 and 2 then the result will be 3.01.
4840 : * If we are then asked to un-aggregate the 1.01 then we must fail as we
4841 : * won't be able to tell what the new aggregated value's dscale should be.
4842 : * We don't want to return 2.00 (dscale = 2), since the sum's dscale would
3284 tgl 4843 EUB : * have been zero if we'd really aggregated only 2.
4844 : *
3284 tgl 4845 ECB : * Note: alternatively, we could count the number of inputs with each possible
4846 : * dscale (up to some sane limit). Not yet clear if it's worth the trouble.
4847 : */
4848 : static bool
3284 tgl 4849 CBC 171 : do_numeric_discard(NumericAggState *state, Numeric newval)
4850 : {
3284 tgl 4851 ECB : NumericVar X;
4852 : NumericVar X2;
4853 : MemoryContext old_context;
4854 :
4855 : /* Count NaN/infinity inputs separately from all else */
991 tgl 4856 GIC 171 : if (NUMERIC_IS_SPECIAL(newval))
4857 : {
4858 3 : if (NUMERIC_IS_PINF(newval))
991 tgl 4859 UIC 0 : state->pInfcount--;
991 tgl 4860 GIC 3 : else if (NUMERIC_IS_NINF(newval))
991 tgl 4861 LBC 0 : state->nInfcount--;
4862 : else
991 tgl 4863 GIC 3 : state->NaNcount--;
3284 4864 3 : return true;
3284 tgl 4865 ECB : }
4866 :
4867 : /* load processed number in short-lived context */
3284 tgl 4868 GIC 168 : init_var_from_num(newval, &X);
3284 tgl 4869 ECB :
4870 : /*
4871 : * state->sumX's dscale is the maximum dscale of any of the inputs.
4872 : * Removing the last input with that dscale would require us to recompute
4873 : * the maximum dscale of the *remaining* inputs, which we cannot do unless
4874 : * no more non-NaN inputs remain at all. So we report a failure instead,
4875 : * and force the aggregation to be redone from scratch.
4876 : */
3284 tgl 4877 GIC 168 : if (X.dscale == state->maxScale)
4878 : {
4879 168 : if (state->maxScaleCount > 1 || state->maxScale == 0)
4880 : {
4881 : /*
4882 : * Some remaining inputs have same dscale, or dscale hasn't gotten
3260 bruce 4883 ECB : * above zero anyway
4884 : */
3284 tgl 4885 CBC 159 : state->maxScaleCount--;
3284 tgl 4886 ECB : }
3284 tgl 4887 CBC 9 : else if (state->N == 1)
3284 tgl 4888 ECB : {
4889 : /* No remaining non-NaN inputs at all, so reset maxScale */
3284 tgl 4890 CBC 6 : state->maxScale = 0;
4891 6 : state->maxScaleCount = 0;
4892 : }
4893 : else
4894 : {
3284 tgl 4895 ECB : /* Correct new maxScale is uncertain, must fail */
3284 tgl 4896 GIC 3 : return false;
4897 : }
4898 : }
4899 :
4900 : /* if we need X^2, calculate that in short-lived context */
3284 tgl 4901 CBC 165 : if (state->calcSumX2)
4902 : {
4903 144 : init_var(&X2);
4904 144 : mul_var(&X, &X, &X2, X.dscale * 2);
4905 : }
3284 tgl 4906 ECB :
4907 : /* The rest of this needs to work in the aggregate context */
3284 tgl 4908 GIC 165 : old_context = MemoryContextSwitchTo(state->agg_context);
4909 :
3284 tgl 4910 CBC 165 : if (state->N-- > 1)
4911 : {
2410 heikki.linnakangas 4912 ECB : /* Negate X, to subtract it from the sum */
2410 heikki.linnakangas 4913 CBC 156 : X.sign = (X.sign == NUMERIC_POS ? NUMERIC_NEG : NUMERIC_POS);
2410 heikki.linnakangas 4914 GIC 156 : accum_sum_add(&(state->sumX), &X);
4915 :
3284 tgl 4916 156 : if (state->calcSumX2)
2410 heikki.linnakangas 4917 ECB : {
4918 : /* Negate X^2. X^2 is always positive */
2410 heikki.linnakangas 4919 CBC 144 : X2.sign = NUMERIC_NEG;
2410 heikki.linnakangas 4920 GIC 144 : accum_sum_add(&(state->sumX2), &X2);
4921 : }
3284 tgl 4922 ECB : }
4923 : else
4924 : {
2410 heikki.linnakangas 4925 : /* Zero the sums */
3284 tgl 4926 GIC 9 : Assert(state->N == 0);
2410 heikki.linnakangas 4927 ECB :
2410 heikki.linnakangas 4928 GIC 9 : accum_sum_reset(&state->sumX);
4929 9 : if (state->calcSumX2)
2410 heikki.linnakangas 4930 UIC 0 : accum_sum_reset(&state->sumX2);
4931 : }
4932 :
3284 tgl 4933 GIC 165 : MemoryContextSwitchTo(old_context);
4934 :
4935 165 : return true;
4936 : }
4937 :
4938 : /*
4939 : * Generic transition function for numeric aggregates that require sumX2.
4940 : */
4941 : Datum
8301 4942 321 : numeric_accum(PG_FUNCTION_ARGS)
4943 : {
4944 : NumericAggState *state;
4945 :
3431 tgl 4946 CBC 321 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
4947 :
4948 : /* Create the state data on the first call */
3284 tgl 4949 GIC 321 : if (state == NULL)
4950 87 : state = makeNumericAggState(fcinfo, true);
4951 :
4952 321 : if (!PG_ARGISNULL(1))
3431 tgl 4953 CBC 312 : do_numeric_accum(state, PG_GETARG_NUMERIC(1));
4954 :
4955 321 : PG_RETURN_POINTER(state);
8301 tgl 4956 EUB : }
8301 tgl 4957 ECB :
2560 rhaas 4958 EUB : /*
4959 : * Generic combine function for numeric aggregates which require sumX2
2560 rhaas 4960 ECB : */
4961 : Datum
2560 rhaas 4962 GIC 17 : numeric_combine(PG_FUNCTION_ARGS)
4963 : {
4964 : NumericAggState *state1;
2495 rhaas 4965 ECB : NumericAggState *state2;
4966 : MemoryContext agg_context;
4967 : MemoryContext old_context;
4968 :
2560 rhaas 4969 GIC 17 : if (!AggCheckCallContext(fcinfo, &agg_context))
2560 rhaas 4970 UIC 0 : elog(ERROR, "aggregate function called in non-aggregate context");
4971 :
2560 rhaas 4972 GIC 17 : state1 = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
4973 17 : state2 = PG_ARGISNULL(1) ? NULL : (NumericAggState *) PG_GETARG_POINTER(1);
2560 rhaas 4974 ECB :
2560 rhaas 4975 GIC 17 : if (state2 == NULL)
2560 rhaas 4976 LBC 0 : PG_RETURN_POINTER(state1);
4977 :
4978 : /* manually copy all fields from state2 to state1 */
2560 rhaas 4979 GIC 17 : if (state1 == NULL)
4980 : {
4981 9 : old_context = MemoryContextSwitchTo(agg_context);
2560 rhaas 4982 ECB :
2481 tgl 4983 GIC 9 : state1 = makeNumericAggStateCurrentContext(true);
2560 rhaas 4984 CBC 9 : state1->N = state2->N;
2560 rhaas 4985 GIC 9 : state1->NaNcount = state2->NaNcount;
991 tgl 4986 9 : state1->pInfcount = state2->pInfcount;
991 tgl 4987 CBC 9 : state1->nInfcount = state2->nInfcount;
2560 rhaas 4988 9 : state1->maxScale = state2->maxScale;
2560 rhaas 4989 GIC 9 : state1->maxScaleCount = state2->maxScaleCount;
4990 :
2410 heikki.linnakangas 4991 9 : accum_sum_copy(&state1->sumX, &state2->sumX);
4992 9 : accum_sum_copy(&state1->sumX2, &state2->sumX2);
2560 rhaas 4993 ECB :
2560 rhaas 4994 GIC 9 : MemoryContextSwitchTo(old_context);
4995 :
4996 9 : PG_RETURN_POINTER(state1);
4997 : }
2560 rhaas 4998 ECB :
1032 tgl 4999 GIC 8 : state1->N += state2->N;
1032 tgl 5000 CBC 8 : state1->NaNcount += state2->NaNcount;
991 5001 8 : state1->pInfcount += state2->pInfcount;
991 tgl 5002 GIC 8 : state1->nInfcount += state2->nInfcount;
5003 :
2560 rhaas 5004 8 : if (state2->N > 0)
2560 rhaas 5005 ECB : {
5006 : /*
2495 5007 : * These are currently only needed for moving aggregates, but let's do
5008 : * the right thing anyway...
5009 : */
2560 rhaas 5010 CBC 8 : if (state2->maxScale > state1->maxScale)
2560 rhaas 5011 ECB : {
2560 rhaas 5012 UIC 0 : state1->maxScale = state2->maxScale;
2560 rhaas 5013 LBC 0 : state1->maxScaleCount = state2->maxScaleCount;
5014 : }
2560 rhaas 5015 GIC 8 : else if (state2->maxScale == state1->maxScale)
2560 rhaas 5016 CBC 8 : state1->maxScaleCount += state2->maxScaleCount;
2560 rhaas 5017 ECB :
5018 : /* The rest of this needs to work in the aggregate context */
2560 rhaas 5019 GIC 8 : old_context = MemoryContextSwitchTo(agg_context);
5020 :
5021 : /* Accumulate sums */
2410 heikki.linnakangas 5022 8 : accum_sum_combine(&state1->sumX, &state2->sumX);
2410 heikki.linnakangas 5023 CBC 8 : accum_sum_combine(&state1->sumX2, &state2->sumX2);
5024 :
2560 rhaas 5025 8 : MemoryContextSwitchTo(old_context);
2560 rhaas 5026 ECB : }
2560 rhaas 5027 GBC 8 : PG_RETURN_POINTER(state1);
5028 : }
5029 :
5895 bruce 5030 ECB : /*
5031 : * Generic transition function for numeric aggregates that don't require sumX2.
5032 : */
5033 : Datum
5895 bruce 5034 GIC 936404 : numeric_avg_accum(PG_FUNCTION_ARGS)
5035 : {
5036 : NumericAggState *state;
5037 :
3431 tgl 5038 936404 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
3431 tgl 5039 ECB :
5040 : /* Create the state data on the first call */
3284 tgl 5041 GIC 936404 : if (state == NULL)
5042 85452 : state = makeNumericAggState(fcinfo, false);
3431 tgl 5043 ECB :
3284 tgl 5044 GIC 936404 : if (!PG_ARGISNULL(1))
3431 5045 936374 : do_numeric_accum(state, PG_GETARG_NUMERIC(1));
3284 tgl 5046 ECB :
3284 tgl 5047 CBC 936404 : PG_RETURN_POINTER(state);
5048 : }
3284 tgl 5049 ECB :
2560 rhaas 5050 : /*
5051 : * Combine function for numeric aggregates which don't require sumX2
5052 : */
5053 : Datum
2560 rhaas 5054 GIC 11 : numeric_avg_combine(PG_FUNCTION_ARGS)
5055 : {
5056 : NumericAggState *state1;
5057 : NumericAggState *state2;
5058 : MemoryContext agg_context;
2495 rhaas 5059 ECB : MemoryContext old_context;
5060 :
2560 rhaas 5061 GIC 11 : if (!AggCheckCallContext(fcinfo, &agg_context))
2560 rhaas 5062 UIC 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5063 :
2560 rhaas 5064 GIC 11 : state1 = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
5065 11 : state2 = PG_ARGISNULL(1) ? NULL : (NumericAggState *) PG_GETARG_POINTER(1);
2560 rhaas 5066 ECB :
2560 rhaas 5067 GBC 11 : if (state2 == NULL)
2560 rhaas 5068 UIC 0 : PG_RETURN_POINTER(state1);
2560 rhaas 5069 ECB :
5070 : /* manually copy all fields from state2 to state1 */
2560 rhaas 5071 GIC 11 : if (state1 == NULL)
2560 rhaas 5072 ECB : {
2560 rhaas 5073 GBC 3 : old_context = MemoryContextSwitchTo(agg_context);
5074 :
2481 tgl 5075 GIC 3 : state1 = makeNumericAggStateCurrentContext(false);
2560 rhaas 5076 CBC 3 : state1->N = state2->N;
2560 rhaas 5077 GIC 3 : state1->NaNcount = state2->NaNcount;
991 tgl 5078 CBC 3 : state1->pInfcount = state2->pInfcount;
991 tgl 5079 GIC 3 : state1->nInfcount = state2->nInfcount;
2560 rhaas 5080 CBC 3 : state1->maxScale = state2->maxScale;
5081 3 : state1->maxScaleCount = state2->maxScaleCount;
2560 rhaas 5082 ECB :
2410 heikki.linnakangas 5083 CBC 3 : accum_sum_copy(&state1->sumX, &state2->sumX);
2560 rhaas 5084 ECB :
2560 rhaas 5085 CBC 3 : MemoryContextSwitchTo(old_context);
2560 rhaas 5086 ECB :
2560 rhaas 5087 GIC 3 : PG_RETURN_POINTER(state1);
2560 rhaas 5088 ECB : }
5089 :
1032 tgl 5090 GIC 8 : state1->N += state2->N;
1032 tgl 5091 CBC 8 : state1->NaNcount += state2->NaNcount;
991 tgl 5092 GIC 8 : state1->pInfcount += state2->pInfcount;
991 tgl 5093 CBC 8 : state1->nInfcount += state2->nInfcount;
5094 :
2560 rhaas 5095 GIC 8 : if (state2->N > 0)
2560 rhaas 5096 ECB : {
5097 : /*
2495 5098 : * These are currently only needed for moving aggregates, but let's do
5099 : * the right thing anyway...
5100 : */
2560 rhaas 5101 CBC 8 : if (state2->maxScale > state1->maxScale)
5102 : {
2560 rhaas 5103 UIC 0 : state1->maxScale = state2->maxScale;
5104 0 : state1->maxScaleCount = state2->maxScaleCount;
5105 : }
2560 rhaas 5106 GIC 8 : else if (state2->maxScale == state1->maxScale)
2560 rhaas 5107 CBC 8 : state1->maxScaleCount += state2->maxScaleCount;
5108 :
2560 rhaas 5109 EUB : /* The rest of this needs to work in the aggregate context */
2560 rhaas 5110 GBC 8 : old_context = MemoryContextSwitchTo(agg_context);
5111 :
2560 rhaas 5112 ECB : /* Accumulate sums */
2410 heikki.linnakangas 5113 CBC 8 : accum_sum_combine(&state1->sumX, &state2->sumX);
5114 :
2560 rhaas 5115 GIC 8 : MemoryContextSwitchTo(old_context);
2560 rhaas 5116 ECB : }
2560 rhaas 5117 GIC 8 : PG_RETURN_POINTER(state1);
5118 : }
2560 rhaas 5119 ECB :
5120 : /*
5121 : * numeric_avg_serialize
5122 : * Serialize NumericAggState for numeric aggregates that don't require
5123 : * sumX2.
5124 : */
5125 : Datum
2560 rhaas 5126 GIC 11 : numeric_avg_serialize(PG_FUNCTION_ARGS)
5127 : {
5128 : NumericAggState *state;
5129 : StringInfoData buf;
5130 : bytea *result;
2410 heikki.linnakangas 5131 ECB : NumericVar tmp_var;
5132 :
5133 : /* Ensure we disallow calling when not in aggregate context */
2560 rhaas 5134 GIC 11 : if (!AggCheckCallContext(fcinfo, NULL))
2560 rhaas 5135 LBC 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5136 :
2560 rhaas 5137 GIC 11 : state = (NumericAggState *) PG_GETARG_POINTER(0);
2560 rhaas 5138 ECB :
2410 heikki.linnakangas 5139 CBC 11 : init_var(&tmp_var);
5140 :
2560 rhaas 5141 11 : pq_begintypsend(&buf);
2560 rhaas 5142 ECB :
5143 : /* N */
2560 rhaas 5144 CBC 11 : pq_sendint64(&buf, state->N);
5145 :
5146 : /* sumX */
643 dean.a.rasheed 5147 GIC 11 : accum_sum_final(&state->sumX, &tmp_var);
5148 11 : numericvar_serialize(&buf, &tmp_var);
5149 :
5150 : /* maxScale */
2006 andres 5151 CBC 11 : pq_sendint32(&buf, state->maxScale);
5152 :
5153 : /* maxScaleCount */
2560 rhaas 5154 GIC 11 : pq_sendint64(&buf, state->maxScaleCount);
5155 :
5156 : /* NaNcount */
5157 11 : pq_sendint64(&buf, state->NaNcount);
2560 rhaas 5158 ECB :
991 tgl 5159 EUB : /* pInfcount */
991 tgl 5160 GIC 11 : pq_sendint64(&buf, state->pInfcount);
991 tgl 5161 ECB :
5162 : /* nInfcount */
991 tgl 5163 GIC 11 : pq_sendint64(&buf, state->nInfcount);
991 tgl 5164 ECB :
2560 rhaas 5165 GBC 11 : result = pq_endtypsend(&buf);
5166 :
643 dean.a.rasheed 5167 GIC 11 : free_var(&tmp_var);
643 dean.a.rasheed 5168 ECB :
2560 rhaas 5169 GIC 11 : PG_RETURN_BYTEA_P(result);
2560 rhaas 5170 ECB : }
5171 :
5172 : /*
5173 : * numeric_avg_deserialize
2482 tgl 5174 : * Deserialize bytea into NumericAggState for numeric aggregates that
5175 : * don't require sumX2.
2560 rhaas 5176 : */
5177 : Datum
2560 rhaas 5178 CBC 11 : numeric_avg_deserialize(PG_FUNCTION_ARGS)
5179 : {
2482 tgl 5180 ECB : bytea *sstate;
5181 : NumericAggState *result;
2495 rhaas 5182 : StringInfoData buf;
5183 : NumericVar tmp_var;
2560 5184 :
2560 rhaas 5185 GIC 11 : if (!AggCheckCallContext(fcinfo, NULL))
2560 rhaas 5186 UIC 0 : elog(ERROR, "aggregate function called in non-aggregate context");
2560 rhaas 5187 ECB :
2219 noah 5188 CBC 11 : sstate = PG_GETARG_BYTEA_PP(0);
2482 tgl 5189 ECB :
643 dean.a.rasheed 5190 CBC 11 : init_var(&tmp_var);
5191 :
2560 rhaas 5192 ECB : /*
5193 : * Copy the bytea into a StringInfo so that we can "receive" it using the
5194 : * standard recv-function infrastructure.
5195 : */
2560 rhaas 5196 GIC 11 : initStringInfo(&buf);
2219 noah 5197 22 : appendBinaryStringInfo(&buf,
2219 noah 5198 CBC 22 : VARDATA_ANY(sstate), VARSIZE_ANY_EXHDR(sstate));
5199 :
2481 tgl 5200 GBC 11 : result = makeNumericAggStateCurrentContext(false);
2560 rhaas 5201 EUB :
5202 : /* N */
2560 rhaas 5203 CBC 11 : result->N = pq_getmsgint64(&buf);
2560 rhaas 5204 ECB :
5205 : /* sumX */
643 dean.a.rasheed 5206 GIC 11 : numericvar_deserialize(&buf, &tmp_var);
2410 heikki.linnakangas 5207 CBC 11 : accum_sum_add(&(result->sumX), &tmp_var);
5208 :
5209 : /* maxScale */
2560 rhaas 5210 11 : result->maxScale = pq_getmsgint(&buf, 4);
5211 :
2560 rhaas 5212 ECB : /* maxScaleCount */
2560 rhaas 5213 GIC 11 : result->maxScaleCount = pq_getmsgint64(&buf);
2560 rhaas 5214 ECB :
5215 : /* NaNcount */
2560 rhaas 5216 GIC 11 : result->NaNcount = pq_getmsgint64(&buf);
5217 :
5218 : /* pInfcount */
991 tgl 5219 11 : result->pInfcount = pq_getmsgint64(&buf);
5220 :
5221 : /* nInfcount */
5222 11 : result->nInfcount = pq_getmsgint64(&buf);
991 tgl 5223 ECB :
2560 rhaas 5224 GIC 11 : pq_getmsgend(&buf);
5225 11 : pfree(buf.data);
5226 :
643 dean.a.rasheed 5227 11 : free_var(&tmp_var);
5228 :
2560 rhaas 5229 11 : PG_RETURN_POINTER(result);
5230 : }
2560 rhaas 5231 ECB :
2560 rhaas 5232 EUB : /*
5233 : * numeric_serialize
2560 rhaas 5234 ECB : * Serialization function for NumericAggState for numeric aggregates that
5235 : * require sumX2.
5236 : */
5237 : Datum
2560 rhaas 5238 CBC 17 : numeric_serialize(PG_FUNCTION_ARGS)
5239 : {
5240 : NumericAggState *state;
2495 rhaas 5241 ECB : StringInfoData buf;
5242 : bytea *result;
5243 : NumericVar tmp_var;
2560 5244 :
5245 : /* Ensure we disallow calling when not in aggregate context */
2560 rhaas 5246 GIC 17 : if (!AggCheckCallContext(fcinfo, NULL))
2560 rhaas 5247 UIC 0 : elog(ERROR, "aggregate function called in non-aggregate context");
2560 rhaas 5248 ECB :
2560 rhaas 5249 GIC 17 : state = (NumericAggState *) PG_GETARG_POINTER(0);
5250 :
2410 heikki.linnakangas 5251 CBC 17 : init_var(&tmp_var);
5252 :
2560 rhaas 5253 GIC 17 : pq_begintypsend(&buf);
2560 rhaas 5254 ECB :
5255 : /* N */
2560 rhaas 5256 GIC 17 : pq_sendint64(&buf, state->N);
2560 rhaas 5257 ECB :
5258 : /* sumX */
643 dean.a.rasheed 5259 GIC 17 : accum_sum_final(&state->sumX, &tmp_var);
643 dean.a.rasheed 5260 CBC 17 : numericvar_serialize(&buf, &tmp_var);
5261 :
2560 rhaas 5262 ECB : /* sumX2 */
643 dean.a.rasheed 5263 GIC 17 : accum_sum_final(&state->sumX2, &tmp_var);
643 dean.a.rasheed 5264 CBC 17 : numericvar_serialize(&buf, &tmp_var);
5265 :
2560 rhaas 5266 ECB : /* maxScale */
2006 andres 5267 GIC 17 : pq_sendint32(&buf, state->maxScale);
5268 :
5269 : /* maxScaleCount */
2560 rhaas 5270 17 : pq_sendint64(&buf, state->maxScaleCount);
5271 :
5272 : /* NaNcount */
5273 17 : pq_sendint64(&buf, state->NaNcount);
5274 :
991 tgl 5275 ECB : /* pInfcount */
991 tgl 5276 GIC 17 : pq_sendint64(&buf, state->pInfcount);
5277 :
5278 : /* nInfcount */
5279 17 : pq_sendint64(&buf, state->nInfcount);
5280 :
2560 rhaas 5281 17 : result = pq_endtypsend(&buf);
2560 rhaas 5282 ECB :
643 dean.a.rasheed 5283 GBC 17 : free_var(&tmp_var);
5284 :
2560 rhaas 5285 CBC 17 : PG_RETURN_BYTEA_P(result);
5286 : }
2560 rhaas 5287 ECB :
5288 : /*
5289 : * numeric_deserialize
5290 : * Deserialization function for NumericAggState for numeric aggregates that
5291 : * require sumX2.
5292 : */
5293 : Datum
2560 rhaas 5294 CBC 17 : numeric_deserialize(PG_FUNCTION_ARGS)
2560 rhaas 5295 ECB : {
5296 : bytea *sstate;
2495 5297 : NumericAggState *result;
5298 : StringInfoData buf;
5299 : NumericVar tmp_var;
2560 5300 :
2560 rhaas 5301 GIC 17 : if (!AggCheckCallContext(fcinfo, NULL))
2560 rhaas 5302 UIC 0 : elog(ERROR, "aggregate function called in non-aggregate context");
2560 rhaas 5303 ECB :
2219 noah 5304 CBC 17 : sstate = PG_GETARG_BYTEA_PP(0);
5305 :
643 dean.a.rasheed 5306 GIC 17 : init_var(&tmp_var);
643 dean.a.rasheed 5307 ECB :
5308 : /*
5309 : * Copy the bytea into a StringInfo so that we can "receive" it using the
2481 tgl 5310 : * standard recv-function infrastructure.
5311 : */
2560 rhaas 5312 GIC 17 : initStringInfo(&buf);
2219 noah 5313 CBC 34 : appendBinaryStringInfo(&buf,
2219 noah 5314 GIC 34 : VARDATA_ANY(sstate), VARSIZE_ANY_EXHDR(sstate));
5315 :
2481 tgl 5316 CBC 17 : result = makeNumericAggStateCurrentContext(false);
5317 :
5318 : /* N */
2560 rhaas 5319 17 : result->N = pq_getmsgint64(&buf);
5320 :
2560 rhaas 5321 ECB : /* sumX */
643 dean.a.rasheed 5322 CBC 17 : numericvar_deserialize(&buf, &tmp_var);
643 dean.a.rasheed 5323 GIC 17 : accum_sum_add(&(result->sumX), &tmp_var);
2560 rhaas 5324 ECB :
5325 : /* sumX2 */
643 dean.a.rasheed 5326 CBC 17 : numericvar_deserialize(&buf, &tmp_var);
643 dean.a.rasheed 5327 GIC 17 : accum_sum_add(&(result->sumX2), &tmp_var);
5328 :
5329 : /* maxScale */
2560 rhaas 5330 17 : result->maxScale = pq_getmsgint(&buf, 4);
5331 :
5332 : /* maxScaleCount */
5333 17 : result->maxScaleCount = pq_getmsgint64(&buf);
5334 :
2560 rhaas 5335 ECB : /* NaNcount */
2560 rhaas 5336 GIC 17 : result->NaNcount = pq_getmsgint64(&buf);
5337 :
5338 : /* pInfcount */
991 tgl 5339 17 : result->pInfcount = pq_getmsgint64(&buf);
5340 :
5341 : /* nInfcount */
5342 17 : result->nInfcount = pq_getmsgint64(&buf);
991 tgl 5343 ECB :
2560 rhaas 5344 GBC 17 : pq_getmsgend(&buf);
2560 rhaas 5345 GIC 17 : pfree(buf.data);
2560 rhaas 5346 ECB :
643 dean.a.rasheed 5347 GIC 17 : free_var(&tmp_var);
643 dean.a.rasheed 5348 ECB :
2560 rhaas 5349 GIC 17 : PG_RETURN_POINTER(result);
2560 rhaas 5350 ECB : }
5351 :
5352 : /*
3284 tgl 5353 : * Generic inverse transition function for numeric aggregates
5354 : * (with or without requirement for X^2).
5355 : */
5356 : Datum
3284 tgl 5357 CBC 114 : numeric_accum_inv(PG_FUNCTION_ARGS)
5358 : {
5359 : NumericAggState *state;
3284 tgl 5360 ECB :
3284 tgl 5361 CBC 114 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
5362 :
5363 : /* Should not get here with no state */
5364 114 : if (state == NULL)
3284 tgl 5365 UIC 0 : elog(ERROR, "numeric_accum_inv called with NULL state");
5366 :
3284 tgl 5367 CBC 114 : if (!PG_ARGISNULL(1))
5368 : {
5369 : /* If we fail to perform the inverse transition, return NULL */
5370 99 : if (!do_numeric_discard(state, PG_GETARG_NUMERIC(1)))
3284 tgl 5371 GIC 3 : PG_RETURN_NULL();
5372 : }
5895 bruce 5373 ECB :
3431 tgl 5374 GIC 111 : PG_RETURN_POINTER(state);
5375 : }
5895 bruce 5376 ECB :
5377 :
8301 tgl 5378 : /*
5379 : * Integer data types in general use Numeric accumulators to share code
2942 andres 5380 : * and avoid risk of overflow.
5381 : *
5382 : * However for performance reasons optimized special-purpose accumulator
5383 : * routines are used when possible.
5384 : *
5385 : * On platforms with 128-bit integer support, the 128-bit routines will be
5386 : * used when sum(X) or sum(X*X) fit into 128-bit.
5387 : *
5388 : * For 16 and 32 bit inputs, the N and sum(X) fit into 64-bit so the 64-bit
5389 : * accumulators will be used for SUM and AVG of these data types.
5390 : */
5391 :
5392 : #ifdef HAVE_INT128
5393 : typedef struct Int128AggState
5394 : {
5395 : bool calcSumX2; /* if true, calculate sumX2 */
5396 : int64 N; /* count of processed numbers */
5397 : int128 sumX; /* sum of processed numbers */
2878 bruce 5398 : int128 sumX2; /* sum of squares of processed numbers */
2942 andres 5399 EUB : } Int128AggState;
5400 :
2942 andres 5401 ECB : /*
5402 : * Prepare state data for a 128-bit aggregate function that needs to compute
5403 : * sum, count and optionally sum of squares of the input.
5404 : */
5405 : static Int128AggState *
2942 andres 5406 GIC 322 : makeInt128AggState(FunctionCallInfo fcinfo, bool calcSumX2)
5407 : {
5408 : Int128AggState *state;
2942 andres 5409 ECB : MemoryContext agg_context;
5410 : MemoryContext old_context;
5411 :
2942 andres 5412 GIC 322 : if (!AggCheckCallContext(fcinfo, &agg_context))
2942 andres 5413 LBC 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5414 :
2942 andres 5415 GIC 322 : old_context = MemoryContextSwitchTo(agg_context);
2942 andres 5416 ECB :
2942 andres 5417 GIC 322 : state = (Int128AggState *) palloc0(sizeof(Int128AggState));
5418 322 : state->calcSumX2 = calcSumX2;
2942 andres 5419 ECB :
2942 andres 5420 CBC 322 : MemoryContextSwitchTo(old_context);
5421 :
2942 andres 5422 GIC 322 : return state;
2942 andres 5423 ECB : }
5424 :
5425 : /*
5426 : * Like makeInt128AggState(), but allocate the state in the current memory
2481 tgl 5427 : * context.
5428 : */
5429 : static Int128AggState *
2481 tgl 5430 CBC 19 : makeInt128AggStateCurrentContext(bool calcSumX2)
5431 : {
5432 : Int128AggState *state;
2481 tgl 5433 ECB :
2481 tgl 5434 GIC 19 : state = (Int128AggState *) palloc0(sizeof(Int128AggState));
5435 19 : state->calcSumX2 = calcSumX2;
2481 tgl 5436 ECB :
2481 tgl 5437 GIC 19 : return state;
5438 : }
2481 tgl 5439 ECB :
5440 : /*
2942 andres 5441 : * Accumulate a new input value for 128-bit aggregate functions.
5442 : */
5443 : static void
2942 andres 5444 CBC 276265 : do_int128_accum(Int128AggState *state, int128 newval)
5445 : {
5446 276265 : if (state->calcSumX2)
2942 andres 5447 GIC 121180 : state->sumX2 += newval * newval;
5448 :
5449 276265 : state->sumX += newval;
5450 276265 : state->N++;
5451 276265 : }
5452 :
5453 : /*
2942 andres 5454 ECB : * Remove an input value from the aggregated state.
5455 : */
5456 : static void
2942 andres 5457 GIC 156 : do_int128_discard(Int128AggState *state, int128 newval)
2942 andres 5458 ECB : {
2942 andres 5459 GIC 156 : if (state->calcSumX2)
5460 144 : state->sumX2 -= newval * newval;
2942 andres 5461 ECB :
2942 andres 5462 GBC 156 : state->sumX -= newval;
2942 andres 5463 GIC 156 : state->N--;
2942 andres 5464 CBC 156 : }
5465 :
5466 : typedef Int128AggState PolyNumAggState;
2942 andres 5467 ECB : #define makePolyNumAggState makeInt128AggState
2481 tgl 5468 : #define makePolyNumAggStateCurrentContext makeInt128AggStateCurrentContext
5469 : #else
5470 : typedef NumericAggState PolyNumAggState;
2942 andres 5471 : #define makePolyNumAggState makeNumericAggState
5472 : #define makePolyNumAggStateCurrentContext makeNumericAggStateCurrentContext
5473 : #endif
5474 :
5475 : Datum
8301 tgl 5476 GIC 99 : int2_accum(PG_FUNCTION_ARGS)
5477 : {
5478 : PolyNumAggState *state;
5479 :
2942 andres 5480 99 : state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
5481 :
5482 : /* Create the state data on the first call */
3284 tgl 5483 99 : if (state == NULL)
2942 andres 5484 18 : state = makePolyNumAggState(fcinfo, true);
5485 :
3431 tgl 5486 99 : if (!PG_ARGISNULL(1))
5487 : {
5488 : #ifdef HAVE_INT128
2940 andres 5489 90 : do_int128_accum(state, (int128) PG_GETARG_INT16(1));
5490 : #else
5491 : do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT16(1)));
5492 : #endif
5493 : }
5494 :
3431 tgl 5495 99 : PG_RETURN_POINTER(state);
5496 : }
5497 :
5498 : Datum
8301 5499 121099 : int4_accum(PG_FUNCTION_ARGS)
5500 : {
5501 : PolyNumAggState *state;
5502 :
2942 andres 5503 CBC 121099 : state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
5504 :
5505 : /* Create the state data on the first call */
3284 tgl 5506 GIC 121099 : if (state == NULL)
2942 andres 5507 36 : state = makePolyNumAggState(fcinfo, true);
5508 :
3431 tgl 5509 CBC 121099 : if (!PG_ARGISNULL(1))
3431 tgl 5510 EUB : {
5511 : #ifdef HAVE_INT128
2942 andres 5512 CBC 121090 : do_int128_accum(state, (int128) PG_GETARG_INT32(1));
5513 : #else
942 peter 5514 ECB : do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT32(1)));
2942 andres 5515 : #endif
5516 : }
8301 tgl 5517 :
3431 tgl 5518 GIC 121099 : PG_RETURN_POINTER(state);
8301 tgl 5519 ECB : }
5520 :
5521 : Datum
8301 tgl 5522 GIC 120099 : int8_accum(PG_FUNCTION_ARGS)
5523 : {
5524 : NumericAggState *state;
5525 :
3431 5526 120099 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
3431 tgl 5527 ECB :
5528 : /* Create the state data on the first call */
3284 tgl 5529 GIC 120099 : if (state == NULL)
5530 29 : state = makeNumericAggState(fcinfo, true);
3284 tgl 5531 ECB :
3431 tgl 5532 CBC 120099 : if (!PG_ARGISNULL(1))
942 peter 5533 GIC 120090 : do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT64(1)));
3431 tgl 5534 ECB :
3431 tgl 5535 GIC 120099 : PG_RETURN_POINTER(state);
5536 : }
5537 :
5538 : /*
5539 : * Combine function for numeric aggregates which require sumX2
5540 : */
2560 rhaas 5541 ECB : Datum
2560 rhaas 5542 GIC 8 : numeric_poly_combine(PG_FUNCTION_ARGS)
2560 rhaas 5543 ECB : {
5544 : PolyNumAggState *state1;
5545 : PolyNumAggState *state2;
2495 5546 : MemoryContext agg_context;
5547 : MemoryContext old_context;
2560 5548 :
2560 rhaas 5549 GIC 8 : if (!AggCheckCallContext(fcinfo, &agg_context))
2560 rhaas 5550 UIC 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5551 :
2560 rhaas 5552 GIC 8 : state1 = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
5553 8 : state2 = PG_ARGISNULL(1) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(1);
2560 rhaas 5554 ECB :
2560 rhaas 5555 GIC 8 : if (state2 == NULL)
2560 rhaas 5556 LBC 0 : PG_RETURN_POINTER(state1);
2560 rhaas 5557 ECB :
5558 : /* manually copy all fields from state2 to state1 */
2560 rhaas 5559 CBC 8 : if (state1 == NULL)
2560 rhaas 5560 ECB : {
2560 rhaas 5561 CBC 3 : old_context = MemoryContextSwitchTo(agg_context);
5562 :
2560 rhaas 5563 GIC 3 : state1 = makePolyNumAggState(fcinfo, true);
5564 3 : state1->N = state2->N;
5565 :
5566 : #ifdef HAVE_INT128
5567 3 : state1->sumX = state2->sumX;
5568 3 : state1->sumX2 = state2->sumX2;
5569 : #else
5570 : accum_sum_copy(&state1->sumX, &state2->sumX);
5571 : accum_sum_copy(&state1->sumX2, &state2->sumX2);
5572 : #endif
2560 rhaas 5573 ECB :
2560 rhaas 5574 GIC 3 : MemoryContextSwitchTo(old_context);
5575 :
5576 3 : PG_RETURN_POINTER(state1);
2560 rhaas 5577 ECB : }
5578 :
2560 rhaas 5579 GIC 5 : if (state2->N > 0)
2560 rhaas 5580 ECB : {
2560 rhaas 5581 CBC 5 : state1->N += state2->N;
5582 :
2560 rhaas 5583 ECB : #ifdef HAVE_INT128
2560 rhaas 5584 GIC 5 : state1->sumX += state2->sumX;
5585 5 : state1->sumX2 += state2->sumX2;
2560 rhaas 5586 ECB : #else
5587 : /* The rest of this needs to work in the aggregate context */
5588 : old_context = MemoryContextSwitchTo(agg_context);
5589 :
5590 : /* Accumulate sums */
5591 : accum_sum_combine(&state1->sumX, &state2->sumX);
2410 heikki.linnakangas 5592 : accum_sum_combine(&state1->sumX2, &state2->sumX2);
5593 :
5594 : MemoryContextSwitchTo(old_context);
5595 : #endif
2560 rhaas 5596 :
5597 : }
2560 rhaas 5598 GIC 5 : PG_RETURN_POINTER(state1);
5599 : }
2560 rhaas 5600 ECB :
5601 : /*
5602 : * numeric_poly_serialize
2482 tgl 5603 : * Serialize PolyNumAggState into bytea for aggregate functions which
5604 : * require sumX2.
5605 : */
2560 rhaas 5606 : Datum
2560 rhaas 5607 GIC 8 : numeric_poly_serialize(PG_FUNCTION_ARGS)
5608 : {
2495 rhaas 5609 ECB : PolyNumAggState *state;
5610 : StringInfoData buf;
5611 : bytea *result;
5612 : NumericVar tmp_var;
5613 :
5614 : /* Ensure we disallow calling when not in aggregate context */
2560 rhaas 5615 CBC 8 : if (!AggCheckCallContext(fcinfo, NULL))
2560 rhaas 5616 UIC 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5617 :
2560 rhaas 5618 GIC 8 : state = (PolyNumAggState *) PG_GETARG_POINTER(0);
2560 rhaas 5619 ECB :
5620 : /*
5621 : * If the platform supports int128 then sumX and sumX2 will be a 128 bit
5622 : * integer type. Here we'll convert that into a numeric type so that the
5623 : * combine state is in the same format for both int128 enabled machines
5624 : * and machines which don't support that type. The logic here is that one
5625 : * day we might like to send these over to another server for further
5626 : * processing and we want a standard format to work with.
5627 : */
5628 :
643 dean.a.rasheed 5629 CBC 8 : init_var(&tmp_var);
2560 rhaas 5630 ECB :
2560 rhaas 5631 GIC 8 : pq_begintypsend(&buf);
2560 rhaas 5632 ECB :
5633 : /* N */
2560 rhaas 5634 GIC 8 : pq_sendint64(&buf, state->N);
5635 :
5636 : /* sumX */
5637 : #ifdef HAVE_INT128
643 dean.a.rasheed 5638 8 : int128_to_numericvar(state->sumX, &tmp_var);
643 dean.a.rasheed 5639 ECB : #else
5640 : accum_sum_final(&state->sumX, &tmp_var);
5641 : #endif
643 dean.a.rasheed 5642 GIC 8 : numericvar_serialize(&buf, &tmp_var);
5643 :
5644 : /* sumX2 */
5645 : #ifdef HAVE_INT128
643 dean.a.rasheed 5646 CBC 8 : int128_to_numericvar(state->sumX2, &tmp_var);
643 dean.a.rasheed 5647 EUB : #else
5648 : accum_sum_final(&state->sumX2, &tmp_var);
643 dean.a.rasheed 5649 ECB : #endif
643 dean.a.rasheed 5650 CBC 8 : numericvar_serialize(&buf, &tmp_var);
5651 :
2560 rhaas 5652 8 : result = pq_endtypsend(&buf);
2560 rhaas 5653 EUB :
643 dean.a.rasheed 5654 GIC 8 : free_var(&tmp_var);
5655 :
2560 rhaas 5656 CBC 8 : PG_RETURN_BYTEA_P(result);
5657 : }
2560 rhaas 5658 ECB :
5659 : /*
5660 : * numeric_poly_deserialize
2482 tgl 5661 : * Deserialize PolyNumAggState from bytea for aggregate functions which
5662 : * require sumX2.
5663 : */
2560 rhaas 5664 : Datum
2560 rhaas 5665 CBC 8 : numeric_poly_deserialize(PG_FUNCTION_ARGS)
5666 : {
5667 : bytea *sstate;
5668 : PolyNumAggState *result;
5669 : StringInfoData buf;
5670 : NumericVar tmp_var;
2560 rhaas 5671 ECB :
2560 rhaas 5672 GIC 8 : if (!AggCheckCallContext(fcinfo, NULL))
2560 rhaas 5673 LBC 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5674 :
2219 noah 5675 GIC 8 : sstate = PG_GETARG_BYTEA_PP(0);
2482 tgl 5676 ECB :
643 dean.a.rasheed 5677 GIC 8 : init_var(&tmp_var);
643 dean.a.rasheed 5678 ECB :
5679 : /*
5680 : * Copy the bytea into a StringInfo so that we can "receive" it using the
2481 tgl 5681 : * standard recv-function infrastructure.
2560 rhaas 5682 : */
2560 rhaas 5683 GIC 8 : initStringInfo(&buf);
2219 noah 5684 16 : appendBinaryStringInfo(&buf,
5685 16 : VARDATA_ANY(sstate), VARSIZE_ANY_EXHDR(sstate));
5686 :
2481 tgl 5687 8 : result = makePolyNumAggStateCurrentContext(false);
5688 :
5689 : /* N */
2560 rhaas 5690 8 : result->N = pq_getmsgint64(&buf);
5691 :
5692 : /* sumX */
643 dean.a.rasheed 5693 8 : numericvar_deserialize(&buf, &tmp_var);
5694 : #ifdef HAVE_INT128
643 dean.a.rasheed 5695 CBC 8 : numericvar_to_int128(&tmp_var, &result->sumX);
5696 : #else
5697 : accum_sum_add(&result->sumX, &tmp_var);
5698 : #endif
5699 :
5700 : /* sumX2 */
643 dean.a.rasheed 5701 GIC 8 : numericvar_deserialize(&buf, &tmp_var);
5702 : #ifdef HAVE_INT128
5703 8 : numericvar_to_int128(&tmp_var, &result->sumX2);
2560 rhaas 5704 ECB : #else
5705 : accum_sum_add(&result->sumX2, &tmp_var);
5706 : #endif
5707 :
2560 rhaas 5708 GIC 8 : pq_getmsgend(&buf);
5709 8 : pfree(buf.data);
5710 :
643 dean.a.rasheed 5711 8 : free_var(&tmp_var);
643 dean.a.rasheed 5712 ECB :
2560 rhaas 5713 GBC 8 : PG_RETURN_POINTER(result);
5714 : }
2560 rhaas 5715 ECB :
5716 : /*
5717 : * Transition function for int8 input when we don't need sumX2.
5718 : */
5719 : Datum
5895 bruce 5720 GIC 155559 : int8_avg_accum(PG_FUNCTION_ARGS)
5721 : {
5722 : PolyNumAggState *state;
5723 :
2942 andres 5724 155559 : state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
5725 :
3284 tgl 5726 ECB : /* Create the state data on the first call */
3284 tgl 5727 GIC 155559 : if (state == NULL)
2942 andres 5728 CBC 259 : state = makePolyNumAggState(fcinfo, false);
5729 :
3431 tgl 5730 GIC 155559 : if (!PG_ARGISNULL(1))
3431 tgl 5731 ECB : {
5732 : #ifdef HAVE_INT128
2942 andres 5733 GIC 155085 : do_int128_accum(state, (int128) PG_GETARG_INT64(1));
5734 : #else
942 peter 5735 ECB : do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT64(1)));
5736 : #endif
5737 : }
5738 :
3284 tgl 5739 CBC 155559 : PG_RETURN_POINTER(state);
5740 : }
5741 :
5742 : /*
2560 rhaas 5743 ECB : * Combine function for PolyNumAggState for aggregates which don't require
5744 : * sumX2
5745 : */
5746 : Datum
2560 rhaas 5747 CBC 11 : int8_avg_combine(PG_FUNCTION_ARGS)
5748 : {
2495 rhaas 5749 ECB : PolyNumAggState *state1;
5750 : PolyNumAggState *state2;
5751 : MemoryContext agg_context;
5752 : MemoryContext old_context;
2560 5753 :
2560 rhaas 5754 GIC 11 : if (!AggCheckCallContext(fcinfo, &agg_context))
2560 rhaas 5755 UIC 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5756 :
2560 rhaas 5757 GIC 11 : state1 = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
5758 11 : state2 = PG_ARGISNULL(1) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(1);
5759 :
5760 11 : if (state2 == NULL)
2560 rhaas 5761 UIC 0 : PG_RETURN_POINTER(state1);
2560 rhaas 5762 ECB :
5763 : /* manually copy all fields from state2 to state1 */
2560 rhaas 5764 GIC 11 : if (state1 == NULL)
5765 : {
5766 6 : old_context = MemoryContextSwitchTo(agg_context);
5767 :
5768 6 : state1 = makePolyNumAggState(fcinfo, false);
2560 rhaas 5769 CBC 6 : state1->N = state2->N;
2560 rhaas 5770 EUB :
5771 : #ifdef HAVE_INT128
2560 rhaas 5772 CBC 6 : state1->sumX = state2->sumX;
5773 : #else
2410 heikki.linnakangas 5774 ECB : accum_sum_copy(&state1->sumX, &state2->sumX);
5775 : #endif
2560 rhaas 5776 GIC 6 : MemoryContextSwitchTo(old_context);
5777 :
5778 6 : PG_RETURN_POINTER(state1);
5779 : }
2560 rhaas 5780 ECB :
2560 rhaas 5781 CBC 5 : if (state2->N > 0)
2560 rhaas 5782 ECB : {
2560 rhaas 5783 GIC 5 : state1->N += state2->N;
2560 rhaas 5784 ECB :
5785 : #ifdef HAVE_INT128
2560 rhaas 5786 GIC 5 : state1->sumX += state2->sumX;
2560 rhaas 5787 ECB : #else
5788 : /* The rest of this needs to work in the aggregate context */
5789 : old_context = MemoryContextSwitchTo(agg_context);
5790 :
5791 : /* Accumulate sums */
2410 heikki.linnakangas 5792 : accum_sum_combine(&state1->sumX, &state2->sumX);
5793 :
5794 : MemoryContextSwitchTo(old_context);
5795 : #endif
5796 :
5797 : }
2560 rhaas 5798 CBC 5 : PG_RETURN_POINTER(state1);
5799 : }
2560 rhaas 5800 ECB :
5801 : /*
5802 : * int8_avg_serialize
5803 : * Serialize PolyNumAggState into bytea using the standard
5804 : * recv-function infrastructure.
5805 : */
5806 : Datum
2560 rhaas 5807 GIC 11 : int8_avg_serialize(PG_FUNCTION_ARGS)
2560 rhaas 5808 ECB : {
5809 : PolyNumAggState *state;
2495 5810 : StringInfoData buf;
5811 : bytea *result;
5812 : NumericVar tmp_var;
5813 :
5814 : /* Ensure we disallow calling when not in aggregate context */
2560 rhaas 5815 GIC 11 : if (!AggCheckCallContext(fcinfo, NULL))
2560 rhaas 5816 UIC 0 : elog(ERROR, "aggregate function called in non-aggregate context");
2560 rhaas 5817 ECB :
2560 rhaas 5818 GIC 11 : state = (PolyNumAggState *) PG_GETARG_POINTER(0);
5819 :
5820 : /*
2560 rhaas 5821 ECB : * If the platform supports int128 then sumX will be a 128 integer type.
5822 : * Here we'll convert that into a numeric type so that the combine state
5823 : * is in the same format for both int128 enabled machines and machines
5824 : * which don't support that type. The logic here is that one day we might
5825 : * like to send these over to another server for further processing and we
5826 : * want a standard format to work with.
5827 : */
5828 :
643 dean.a.rasheed 5829 GIC 11 : init_var(&tmp_var);
2560 rhaas 5830 ECB :
2560 rhaas 5831 GIC 11 : pq_begintypsend(&buf);
5832 :
5833 : /* N */
5834 11 : pq_sendint64(&buf, state->N);
5835 :
2560 rhaas 5836 ECB : /* sumX */
5837 : #ifdef HAVE_INT128
643 dean.a.rasheed 5838 GIC 11 : int128_to_numericvar(state->sumX, &tmp_var);
5839 : #else
5840 : accum_sum_final(&state->sumX, &tmp_var);
5841 : #endif
5842 11 : numericvar_serialize(&buf, &tmp_var);
5843 :
2560 rhaas 5844 CBC 11 : result = pq_endtypsend(&buf);
5845 :
643 dean.a.rasheed 5846 GIC 11 : free_var(&tmp_var);
5847 :
2560 rhaas 5848 11 : PG_RETURN_BYTEA_P(result);
5849 : }
5850 :
2560 rhaas 5851 ECB : /*
2560 rhaas 5852 EUB : * int8_avg_deserialize
5853 : * Deserialize bytea back into PolyNumAggState.
2560 rhaas 5854 ECB : */
5855 : Datum
2560 rhaas 5856 GIC 11 : int8_avg_deserialize(PG_FUNCTION_ARGS)
2560 rhaas 5857 ECB : {
2482 tgl 5858 EUB : bytea *sstate;
5859 : PolyNumAggState *result;
5860 : StringInfoData buf;
643 dean.a.rasheed 5861 ECB : NumericVar tmp_var;
5862 :
2560 rhaas 5863 CBC 11 : if (!AggCheckCallContext(fcinfo, NULL))
2560 rhaas 5864 UIC 0 : elog(ERROR, "aggregate function called in non-aggregate context");
2560 rhaas 5865 ECB :
2219 noah 5866 CBC 11 : sstate = PG_GETARG_BYTEA_PP(0);
5867 :
643 dean.a.rasheed 5868 GIC 11 : init_var(&tmp_var);
643 dean.a.rasheed 5869 ECB :
5870 : /*
5871 : * Copy the bytea into a StringInfo so that we can "receive" it using the
5872 : * standard recv-function infrastructure.
2560 rhaas 5873 : */
2560 rhaas 5874 GIC 11 : initStringInfo(&buf);
2219 noah 5875 CBC 22 : appendBinaryStringInfo(&buf,
2219 noah 5876 GIC 22 : VARDATA_ANY(sstate), VARSIZE_ANY_EXHDR(sstate));
5877 :
2481 tgl 5878 CBC 11 : result = makePolyNumAggStateCurrentContext(false);
5879 :
2560 rhaas 5880 ECB : /* N */
2560 rhaas 5881 GIC 11 : result->N = pq_getmsgint64(&buf);
5882 :
2560 rhaas 5883 ECB : /* sumX */
643 dean.a.rasheed 5884 GIC 11 : numericvar_deserialize(&buf, &tmp_var);
5885 : #ifdef HAVE_INT128
5886 11 : numericvar_to_int128(&tmp_var, &result->sumX);
5887 : #else
5888 : accum_sum_add(&result->sumX, &tmp_var);
5889 : #endif
5890 :
2560 rhaas 5891 11 : pq_getmsgend(&buf);
5892 11 : pfree(buf.data);
5893 :
643 dean.a.rasheed 5894 11 : free_var(&tmp_var);
643 dean.a.rasheed 5895 ECB :
2560 rhaas 5896 GIC 11 : PG_RETURN_POINTER(result);
5897 : }
5898 :
5899 : /*
5900 : * Inverse transition functions to go with the above.
5901 : */
5902 :
5903 : Datum
3284 tgl 5904 CBC 81 : int2_accum_inv(PG_FUNCTION_ARGS)
5905 : {
5906 : PolyNumAggState *state;
5907 :
2942 andres 5908 GIC 81 : state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
5909 :
5910 : /* Should not get here with no state */
3284 tgl 5911 81 : if (state == NULL)
3284 tgl 5912 LBC 0 : elog(ERROR, "int2_accum_inv called with NULL state");
3284 tgl 5913 EUB :
3284 tgl 5914 GIC 81 : if (!PG_ARGISNULL(1))
3284 tgl 5915 ECB : {
5916 : #ifdef HAVE_INT128
2942 andres 5917 GIC 72 : do_int128_discard(state, (int128) PG_GETARG_INT16(1));
5918 : #else
5919 : /* Should never fail, all inputs have dscale 0 */
5920 : if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT16(1))))
5921 : elog(ERROR, "do_numeric_discard failed unexpectedly");
5922 : #endif
5923 : }
5924 :
3431 tgl 5925 81 : PG_RETURN_POINTER(state);
5895 bruce 5926 ECB : }
5927 :
3284 tgl 5928 : Datum
3284 tgl 5929 GIC 81 : int4_accum_inv(PG_FUNCTION_ARGS)
5930 : {
2942 andres 5931 ECB : PolyNumAggState *state;
5932 :
2942 andres 5933 GIC 81 : state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
5934 :
3284 tgl 5935 ECB : /* Should not get here with no state */
3284 tgl 5936 GIC 81 : if (state == NULL)
3284 tgl 5937 UIC 0 : elog(ERROR, "int4_accum_inv called with NULL state");
5938 :
3284 tgl 5939 CBC 81 : if (!PG_ARGISNULL(1))
5940 : {
2942 andres 5941 ECB : #ifdef HAVE_INT128
2942 andres 5942 GIC 72 : do_int128_discard(state, (int128) PG_GETARG_INT32(1));
2942 andres 5943 ECB : #else
5944 : /* Should never fail, all inputs have dscale 0 */
942 peter 5945 : if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT32(1))))
5946 : elog(ERROR, "do_numeric_discard failed unexpectedly");
5947 : #endif
5948 : }
5949 :
3284 tgl 5950 GIC 81 : PG_RETURN_POINTER(state);
5951 : }
5952 :
3284 tgl 5953 ECB : Datum
3284 tgl 5954 GIC 81 : int8_accum_inv(PG_FUNCTION_ARGS)
5955 : {
5956 : NumericAggState *state;
5957 :
5958 81 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
5959 :
3284 tgl 5960 ECB : /* Should not get here with no state */
3284 tgl 5961 GBC 81 : if (state == NULL)
3284 tgl 5962 UIC 0 : elog(ERROR, "int8_accum_inv called with NULL state");
3284 tgl 5963 ECB :
3284 tgl 5964 GIC 81 : if (!PG_ARGISNULL(1))
3284 tgl 5965 ECB : {
5966 : /* Should never fail, all inputs have dscale 0 */
942 peter 5967 GIC 72 : if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT64(1))))
3284 tgl 5968 UIC 0 : elog(ERROR, "do_numeric_discard failed unexpectedly");
5969 : }
5970 :
3284 tgl 5971 CBC 81 : PG_RETURN_POINTER(state);
3284 tgl 5972 ECB : }
5895 bruce 5973 :
5974 : Datum
2942 andres 5975 CBC 18 : int8_avg_accum_inv(PG_FUNCTION_ARGS)
5976 : {
5977 : PolyNumAggState *state;
2942 andres 5978 ECB :
2942 andres 5979 GIC 18 : state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
5980 :
2942 andres 5981 ECB : /* Should not get here with no state */
2942 andres 5982 GIC 18 : if (state == NULL)
2942 andres 5983 LBC 0 : elog(ERROR, "int8_avg_accum_inv called with NULL state");
5984 :
2942 andres 5985 GIC 18 : if (!PG_ARGISNULL(1))
5986 : {
5987 : #ifdef HAVE_INT128
2942 andres 5988 CBC 12 : do_int128_discard(state, (int128) PG_GETARG_INT64(1));
2942 andres 5989 ECB : #else
5990 : /* Should never fail, all inputs have dscale 0 */
942 peter 5991 : if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT64(1))))
5992 : elog(ERROR, "do_numeric_discard failed unexpectedly");
2942 andres 5993 : #endif
5994 : }
5995 :
2942 andres 5996 GIC 18 : PG_RETURN_POINTER(state);
5997 : }
5998 :
5999 : Datum
6000 371 : numeric_poly_sum(PG_FUNCTION_ARGS)
2942 andres 6001 ECB : {
6002 : #ifdef HAVE_INT128
6003 : PolyNumAggState *state;
6004 : Numeric res;
2878 bruce 6005 : NumericVar result;
6006 :
2942 andres 6007 GIC 371 : state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
2942 andres 6008 ECB :
2942 andres 6009 EUB : /* If there were no non-null inputs, return NULL */
2942 andres 6010 GIC 371 : if (state == NULL || state->N == 0)
2942 andres 6011 CBC 12 : PG_RETURN_NULL();
6012 :
2942 andres 6013 GIC 359 : init_var(&result);
2942 andres 6014 ECB :
2942 andres 6015 GIC 359 : int128_to_numericvar(state->sumX, &result);
6016 :
6017 359 : res = make_result(&result);
6018 :
6019 359 : free_var(&result);
6020 :
6021 359 : PG_RETURN_NUMERIC(res);
2942 andres 6022 ECB : #else
6023 : return numeric_sum(fcinfo);
6024 : #endif
6025 : }
6026 :
6027 : Datum
2942 andres 6028 GIC 18 : numeric_poly_avg(PG_FUNCTION_ARGS)
6029 : {
2942 andres 6030 ECB : #ifdef HAVE_INT128
6031 : PolyNumAggState *state;
6032 : NumericVar result;
2878 bruce 6033 : Datum countd,
2878 bruce 6034 EUB : sumd;
6035 :
2942 andres 6036 CBC 18 : state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
6037 :
6038 : /* If there were no non-null inputs, return NULL */
6039 18 : if (state == NULL || state->N == 0)
2942 andres 6040 GIC 9 : PG_RETURN_NULL();
6041 :
6042 9 : init_var(&result);
6043 :
6044 9 : int128_to_numericvar(state->sumX, &result);
6045 :
942 peter 6046 9 : countd = NumericGetDatum(int64_to_numeric(state->N));
2942 andres 6047 CBC 9 : sumd = NumericGetDatum(make_result(&result));
6048 :
2942 andres 6049 GIC 9 : free_var(&result);
6050 :
2942 andres 6051 CBC 9 : PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumd, countd));
6052 : #else
6053 : return numeric_avg(fcinfo);
6054 : #endif
2942 andres 6055 ECB : }
6056 :
6057 : Datum
8301 tgl 6058 CBC 39 : numeric_avg(PG_FUNCTION_ARGS)
8301 tgl 6059 EUB : {
6060 : NumericAggState *state;
3431 tgl 6061 ECB : Datum N_datum;
6062 : Datum sumX_datum;
6063 : NumericVar sumX_var;
6064 :
3431 tgl 6065 GBC 39 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
6066 :
6067 : /* If there were no non-null inputs, return NULL */
991 tgl 6068 CBC 39 : if (state == NULL || NA_TOTAL_COUNT(state) == 0)
3431 tgl 6069 GIC 9 : PG_RETURN_NULL();
6070 :
3260 bruce 6071 30 : if (state->NaNcount > 0) /* there was at least one NaN input */
3431 tgl 6072 CBC 3 : PG_RETURN_NUMERIC(make_result(&const_nan));
6073 :
6074 : /* adding plus and minus infinities gives NaN */
991 tgl 6075 GIC 27 : if (state->pInfcount > 0 && state->nInfcount > 0)
991 tgl 6076 CBC 3 : PG_RETURN_NUMERIC(make_result(&const_nan));
991 tgl 6077 GIC 24 : if (state->pInfcount > 0)
6078 9 : PG_RETURN_NUMERIC(make_result(&const_pinf));
991 tgl 6079 CBC 15 : if (state->nInfcount > 0)
991 tgl 6080 GBC 3 : PG_RETURN_NUMERIC(make_result(&const_ninf));
6081 :
942 peter 6082 CBC 12 : N_datum = NumericGetDatum(int64_to_numeric(state->N));
6083 :
2410 heikki.linnakangas 6084 GIC 12 : init_var(&sumX_var);
2410 heikki.linnakangas 6085 CBC 12 : accum_sum_final(&state->sumX, &sumX_var);
2410 heikki.linnakangas 6086 GIC 12 : sumX_datum = NumericGetDatum(make_result(&sumX_var));
6087 12 : free_var(&sumX_var);
6088 :
3431 tgl 6089 12 : PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumX_datum, N_datum));
6090 : }
6091 :
6092 : Datum
3431 tgl 6093 CBC 85453 : numeric_sum(PG_FUNCTION_ARGS)
6094 : {
6095 : NumericAggState *state;
6096 : NumericVar sumX_var;
2410 heikki.linnakangas 6097 ECB : Numeric result;
6098 :
3431 tgl 6099 GIC 85453 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
6100 :
6101 : /* If there were no non-null inputs, return NULL */
991 6102 85453 : if (state == NULL || NA_TOTAL_COUNT(state) == 0)
8301 6103 9 : PG_RETURN_NULL();
8301 tgl 6104 ECB :
3260 bruce 6105 GIC 85444 : if (state->NaNcount > 0) /* there was at least one NaN input */
3431 tgl 6106 9 : PG_RETURN_NUMERIC(make_result(&const_nan));
3431 tgl 6107 ECB :
991 6108 : /* adding plus and minus infinities gives NaN */
991 tgl 6109 GIC 85435 : if (state->pInfcount > 0 && state->nInfcount > 0)
991 tgl 6110 CBC 3 : PG_RETURN_NUMERIC(make_result(&const_nan));
991 tgl 6111 GIC 85432 : if (state->pInfcount > 0)
991 tgl 6112 CBC 9 : PG_RETURN_NUMERIC(make_result(&const_pinf));
991 tgl 6113 GIC 85423 : if (state->nInfcount > 0)
991 tgl 6114 CBC 3 : PG_RETURN_NUMERIC(make_result(&const_ninf));
6115 :
2410 heikki.linnakangas 6116 85420 : init_var(&sumX_var);
2410 heikki.linnakangas 6117 GIC 85420 : accum_sum_final(&state->sumX, &sumX_var);
2410 heikki.linnakangas 6118 CBC 85420 : result = make_result(&sumX_var);
2410 heikki.linnakangas 6119 GIC 85420 : free_var(&sumX_var);
6120 :
6121 85420 : PG_RETURN_NUMERIC(result);
6122 : }
6123 :
6124 : /*
6239 neilc 6125 ECB : * Workhorse routine for the standard deviance and variance
6126 : * aggregates. 'state' is aggregate's transition state.
6127 : * 'variance' specifies whether we should calculate the
6128 : * variance or the standard deviation. 'sample' indicates whether the
6129 : * caller is interested in the sample or the population
6130 : * variance/stddev.
6131 : *
6132 : * If appropriate variance statistic is undefined for the input,
6133 : * *is_null is set to true and NULL is returned.
6134 : */
6135 : static Numeric
3431 tgl 6136 CBC 493 : numeric_stddev_internal(NumericAggState *state,
6239 neilc 6137 ECB : bool variance, bool sample,
6138 : bool *is_null)
8301 tgl 6139 : {
6140 : Numeric res;
6141 : NumericVar vN,
6142 : vsumX,
6143 : vsumX2,
6144 : vNminus1;
6145 : int64 totCount;
7324 6146 : int rscale;
6147 :
1030 6148 : /*
6149 : * Sample stddev and variance are undefined when N <= 1; population stddev
6150 : * is undefined when N == 0. Return NULL in either case (note that NaNs
6151 : * and infinities count as normal inputs for this purpose).
6152 : */
991 tgl 6153 GIC 493 : if (state == NULL || (totCount = NA_TOTAL_COUNT(state)) == 0)
6154 : {
1030 tgl 6155 LBC 0 : *is_null = true;
1030 tgl 6156 UIC 0 : return NULL;
6157 : }
6158 :
1030 tgl 6159 GIC 493 : if (sample && totCount <= 1)
6160 : {
3431 6161 66 : *is_null = true;
3431 tgl 6162 CBC 66 : return NULL;
6163 : }
6164 :
6239 neilc 6165 427 : *is_null = false;
6239 neilc 6166 ECB :
6167 : /*
991 tgl 6168 : * Deal with NaN and infinity cases. By analogy to the behavior of the
6169 : * float8 functions, any infinity input produces NaN output.
6170 : */
991 tgl 6171 GIC 427 : if (state->NaNcount > 0 || state->pInfcount > 0 || state->nInfcount > 0)
6239 neilc 6172 CBC 27 : return make_result(&const_nan);
8301 tgl 6173 ECB :
1030 6174 : /* OK, normal calculation applies */
3431 tgl 6175 CBC 400 : init_var(&vN);
6176 400 : init_var(&vsumX);
6177 400 : init_var(&vsumX2);
6178 :
2942 andres 6179 400 : int64_to_numericvar(state->N, &vN);
2410 heikki.linnakangas 6180 GIC 400 : accum_sum_final(&(state->sumX), &vsumX);
2410 heikki.linnakangas 6181 CBC 400 : accum_sum_final(&(state->sumX2), &vsumX2);
8301 tgl 6182 ECB :
7293 tgl 6183 CBC 400 : init_var(&vNminus1);
6184 400 : sub_var(&vN, &const_one, &vNminus1);
6185 :
7324 tgl 6186 ECB : /* compute rscale for mul_var calls */
7324 tgl 6187 GIC 400 : rscale = vsumX.dscale * 2;
6188 :
6189 400 : mul_var(&vsumX, &vsumX, &vsumX, rscale); /* vsumX = sumX * sumX */
2118 tgl 6190 CBC 400 : mul_var(&vN, &vsumX2, &vsumX2, rscale); /* vsumX2 = N * sumX2 */
6031 bruce 6191 GIC 400 : sub_var(&vsumX2, &vsumX, &vsumX2); /* N * sumX2 - sumX * sumX */
6192 :
7789 tgl 6193 400 : if (cmp_var(&vsumX2, &const_zero) <= 0)
6194 : {
6195 : /* Watch out for roundoff error producing a negative numerator */
7789 tgl 6196 CBC 40 : res = make_result(&const_zero);
6197 : }
6198 : else
7789 tgl 6199 ECB : {
5753 tgl 6200 CBC 360 : if (sample)
2118 tgl 6201 GIC 246 : mul_var(&vN, &vNminus1, &vNminus1, 0); /* N * (N - 1) */
5753 tgl 6202 ECB : else
5624 bruce 6203 CBC 114 : mul_var(&vN, &vN, &vNminus1, 0); /* N * N */
7324 tgl 6204 GIC 360 : rscale = select_div_scale(&vsumX2, &vNminus1);
2118 6205 360 : div_var(&vsumX2, &vNminus1, &vsumX, rscale, true); /* variance */
6239 neilc 6206 CBC 360 : if (!variance)
6031 bruce 6207 189 : sqrt_var(&vsumX, &vsumX, rscale); /* stddev */
7789 tgl 6208 ECB :
7789 tgl 6209 CBC 360 : res = make_result(&vsumX);
7789 tgl 6210 ECB : }
8301 6211 :
8301 tgl 6212 GIC 400 : free_var(&vNminus1);
8301 tgl 6213 CBC 400 : free_var(&vsumX);
6214 400 : free_var(&vsumX2);
8301 tgl 6215 ECB :
6239 neilc 6216 CBC 400 : return res;
6217 : }
8301 tgl 6218 ECB :
6219 : Datum
6239 neilc 6220 GIC 90 : numeric_var_samp(PG_FUNCTION_ARGS)
6221 : {
6222 : NumericAggState *state;
6223 : Numeric res;
6224 : bool is_null;
6225 :
3431 tgl 6226 90 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
6227 :
6228 90 : res = numeric_stddev_internal(state, true, true, &is_null);
6229 :
6239 neilc 6230 90 : if (is_null)
7293 tgl 6231 21 : PG_RETURN_NULL();
6232 : else
6239 neilc 6233 CBC 69 : PG_RETURN_NUMERIC(res);
6234 : }
6235 :
6236 : Datum
6239 neilc 6237 GIC 87 : numeric_stddev_samp(PG_FUNCTION_ARGS)
6238 : {
6239 : NumericAggState *state;
6240 : Numeric res;
6241 : bool is_null;
6242 :
3431 tgl 6243 87 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
6244 :
6245 87 : res = numeric_stddev_internal(state, false, true, &is_null);
6246 :
6239 neilc 6247 87 : if (is_null)
6248 21 : PG_RETURN_NULL();
6249 : else
6239 neilc 6250 CBC 66 : PG_RETURN_NUMERIC(res);
6251 : }
7494 tgl 6252 EUB :
6239 neilc 6253 : Datum
6239 neilc 6254 GIC 57 : numeric_var_pop(PG_FUNCTION_ARGS)
6255 : {
3431 tgl 6256 ECB : NumericAggState *state;
6257 : Numeric res;
6031 bruce 6258 : bool is_null;
8301 tgl 6259 :
3431 tgl 6260 GIC 57 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
6261 :
3431 tgl 6262 CBC 57 : res = numeric_stddev_internal(state, true, false, &is_null);
6263 :
6239 neilc 6264 GIC 57 : if (is_null)
6239 neilc 6265 UIC 0 : PG_RETURN_NULL();
6266 : else
6239 neilc 6267 GIC 57 : PG_RETURN_NUMERIC(res);
6239 neilc 6268 ECB : }
7789 tgl 6269 :
6270 : Datum
6239 neilc 6271 GIC 48 : numeric_stddev_pop(PG_FUNCTION_ARGS)
6239 neilc 6272 ECB : {
3431 tgl 6273 : NumericAggState *state;
6031 bruce 6274 : Numeric res;
6275 : bool is_null;
8301 tgl 6276 :
3431 tgl 6277 CBC 48 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
3431 tgl 6278 ECB :
3431 tgl 6279 GIC 48 : res = numeric_stddev_internal(state, false, false, &is_null);
8301 tgl 6280 ECB :
6239 neilc 6281 CBC 48 : if (is_null)
6239 neilc 6282 UIC 0 : PG_RETURN_NULL();
6283 : else
6239 neilc 6284 CBC 48 : PG_RETURN_NUMERIC(res);
6285 : }
8301 tgl 6286 ECB :
2942 andres 6287 : #ifdef HAVE_INT128
6288 : static Numeric
2942 andres 6289 GIC 211 : numeric_poly_stddev_internal(Int128AggState *state,
2878 bruce 6290 ECB : bool variance, bool sample,
6291 : bool *is_null)
6292 : {
2942 andres 6293 : NumericAggState numstate;
6294 : Numeric res;
6295 :
6296 : /* Initialize an empty agg state */
2410 heikki.linnakangas 6297 CBC 211 : memset(&numstate, 0, sizeof(NumericAggState));
2942 andres 6298 ECB :
2942 andres 6299 GIC 211 : if (state)
2942 andres 6300 ECB : {
2410 heikki.linnakangas 6301 : NumericVar tmp_var;
6302 :
2942 andres 6303 CBC 211 : numstate.N = state->N;
2410 heikki.linnakangas 6304 ECB :
2410 heikki.linnakangas 6305 GIC 211 : init_var(&tmp_var);
2410 heikki.linnakangas 6306 ECB :
2410 heikki.linnakangas 6307 GIC 211 : int128_to_numericvar(state->sumX, &tmp_var);
6308 211 : accum_sum_add(&numstate.sumX, &tmp_var);
2410 heikki.linnakangas 6309 ECB :
2410 heikki.linnakangas 6310 CBC 211 : int128_to_numericvar(state->sumX2, &tmp_var);
6311 211 : accum_sum_add(&numstate.sumX2, &tmp_var);
6312 :
6313 211 : free_var(&tmp_var);
6314 : }
6315 :
2942 andres 6316 GIC 211 : res = numeric_stddev_internal(&numstate, variance, sample, is_null);
2942 andres 6317 ECB :
2410 heikki.linnakangas 6318 GIC 211 : if (numstate.sumX.ndigits > 0)
6319 : {
6320 211 : pfree(numstate.sumX.pos_digits);
6321 211 : pfree(numstate.sumX.neg_digits);
6322 : }
2410 heikki.linnakangas 6323 CBC 211 : if (numstate.sumX2.ndigits > 0)
6324 : {
6325 211 : pfree(numstate.sumX2.pos_digits);
2410 heikki.linnakangas 6326 GIC 211 : pfree(numstate.sumX2.neg_digits);
2410 heikki.linnakangas 6327 ECB : }
2942 andres 6328 :
2942 andres 6329 GIC 211 : return res;
2942 andres 6330 ECB : }
6331 : #endif
6332 :
6333 : Datum
2942 andres 6334 CBC 63 : numeric_poly_var_samp(PG_FUNCTION_ARGS)
6335 : {
6336 : #ifdef HAVE_INT128
6337 : PolyNumAggState *state;
6338 : Numeric res;
6339 : bool is_null;
2942 andres 6340 ECB :
2942 andres 6341 GIC 63 : state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
2942 andres 6342 ECB :
2942 andres 6343 GIC 63 : res = numeric_poly_stddev_internal(state, true, true, &is_null);
2942 andres 6344 ECB :
2942 andres 6345 CBC 63 : if (is_null)
2942 andres 6346 GIC 12 : PG_RETURN_NULL();
2942 andres 6347 ECB : else
2942 andres 6348 GIC 51 : PG_RETURN_NUMERIC(res);
6349 : #else
6350 : return numeric_var_samp(fcinfo);
2942 andres 6351 ECB : #endif
6352 : }
6353 :
6354 : Datum
2942 andres 6355 GIC 82 : numeric_poly_stddev_samp(PG_FUNCTION_ARGS)
6356 : {
2942 andres 6357 ECB : #ifdef HAVE_INT128
6358 : PolyNumAggState *state;
2878 bruce 6359 : Numeric res;
6360 : bool is_null;
2942 andres 6361 :
2942 andres 6362 GBC 82 : state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
6363 :
2942 andres 6364 CBC 82 : res = numeric_poly_stddev_internal(state, false, true, &is_null);
6365 :
2942 andres 6366 GIC 82 : if (is_null)
6367 12 : PG_RETURN_NULL();
2942 andres 6368 ECB : else
2942 andres 6369 GIC 70 : PG_RETURN_NUMERIC(res);
6370 : #else
6371 : return numeric_stddev_samp(fcinfo);
6372 : #endif
6373 : }
2942 andres 6374 ECB :
6375 : Datum
2942 andres 6376 CBC 30 : numeric_poly_var_pop(PG_FUNCTION_ARGS)
6377 : {
2942 andres 6378 ECB : #ifdef HAVE_INT128
2878 bruce 6379 EUB : PolyNumAggState *state;
6380 : Numeric res;
2878 bruce 6381 ECB : bool is_null;
6382 :
2942 andres 6383 GIC 30 : state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
6384 :
6385 30 : res = numeric_poly_stddev_internal(state, true, false, &is_null);
2942 andres 6386 ECB :
2942 andres 6387 GIC 30 : if (is_null)
2942 andres 6388 UIC 0 : PG_RETURN_NULL();
6389 : else
2942 andres 6390 GIC 30 : PG_RETURN_NUMERIC(res);
6391 : #else
6392 : return numeric_var_pop(fcinfo);
6393 : #endif
2942 andres 6394 ECB : }
6395 :
6396 : Datum
2942 andres 6397 GIC 36 : numeric_poly_stddev_pop(PG_FUNCTION_ARGS)
6398 : {
6399 : #ifdef HAVE_INT128
2878 bruce 6400 ECB : PolyNumAggState *state;
6401 : Numeric res;
6402 : bool is_null;
6403 :
2942 andres 6404 CBC 36 : state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
2942 andres 6405 ECB :
2942 andres 6406 GIC 36 : res = numeric_poly_stddev_internal(state, false, false, &is_null);
2942 andres 6407 ECB :
2942 andres 6408 CBC 36 : if (is_null)
2942 andres 6409 UIC 0 : PG_RETURN_NULL();
2942 andres 6410 ECB : else
2942 andres 6411 GIC 36 : PG_RETURN_NUMERIC(res);
6412 : #else
2942 andres 6413 ECB : return numeric_stddev_pop(fcinfo);
6414 : #endif
6415 : }
6416 :
8301 tgl 6417 : /*
6418 : * SUM transition functions for integer datatypes.
6419 : *
7908 6420 : * To avoid overflow, we use accumulators wider than the input datatype.
6421 : * A Numeric accumulator is needed for int8 input; for int4 and int2
6422 : * inputs, we use int8 accumulators which should be sufficient for practical
6423 : * purposes. (The latter two therefore don't really belong in this file,
6424 : * but we keep them here anyway.)
6425 : *
3641 peter_e 6426 : * Because SQL defines the SUM() of no values to be NULL, not zero,
6427 : * the initial condition of the transition data value needs to be NULL. This
6428 : * means we can't rely on ExecAgg to automatically insert the first non-null
6429 : * data value into the transition data: it doesn't know how to do the type
6430 : * conversion. The upshot is that these routines have to be marked non-strict
7908 tgl 6431 : * and handle substitution of the first non-null input themselves.
6432 : *
6433 : * Note: these functions are used only in plain aggregation mode.
6434 : * In moving-aggregate mode, we use intX_avg_accum and intX_avg_accum_inv.
6435 : */
6436 :
6437 : Datum
8301 tgl 6438 CBC 12 : int2_sum(PG_FUNCTION_ARGS)
6439 : {
7908 tgl 6440 ECB : int64 newval;
6441 :
8301 tgl 6442 CBC 12 : if (PG_ARGISNULL(0))
8301 tgl 6443 ECB : {
6444 : /* No non-null input seen so far... */
8301 tgl 6445 CBC 3 : if (PG_ARGISNULL(1))
8301 tgl 6446 UIC 0 : PG_RETURN_NULL(); /* still no non-null */
6447 : /* This is the first non-null input. */
7908 tgl 6448 GIC 3 : newval = (int64) PG_GETARG_INT16(1);
6449 3 : PG_RETURN_INT64(newval);
6450 : }
6451 :
6577 neilc 6452 ECB : /*
6453 : * If we're invoked as an aggregate, we can cheat and modify our first
6454 : * parameter in-place to avoid palloc overhead. If not, we need to return
6455 : * the new value of the transition variable. (If int8 is pass-by-value,
6456 : * then of course this is useless as well as incorrect, so just ifdef it
6457 : * out.)
6458 : */
5466 tgl 6459 : #ifndef USE_FLOAT8_BYVAL /* controls int8 too */
6460 : if (AggCheckCallContext(fcinfo, NULL))
6577 neilc 6461 : {
6462 : int64 *oldsum = (int64 *) PG_GETARG_POINTER(0);
8301 tgl 6463 :
6577 neilc 6464 : /* Leave the running sum unchanged in the new input is null */
6465 : if (!PG_ARGISNULL(1))
6466 : *oldsum = *oldsum + (int64) PG_GETARG_INT16(1);
6467 :
6468 : PG_RETURN_POINTER(oldsum);
6469 : }
6470 : else
6471 : #endif
6472 : {
6577 neilc 6473 CBC 9 : int64 oldsum = PG_GETARG_INT64(0);
6474 :
6475 : /* Leave sum unchanged if new input is null. */
6577 neilc 6476 GIC 9 : if (PG_ARGISNULL(1))
6577 neilc 6477 UIC 0 : PG_RETURN_INT64(oldsum);
6478 :
6479 : /* OK to do the addition. */
6577 neilc 6480 CBC 9 : newval = oldsum + (int64) PG_GETARG_INT16(1);
6481 :
6482 9 : PG_RETURN_INT64(newval);
6483 : }
8301 tgl 6484 ECB : }
8301 tgl 6485 EUB :
6486 : Datum
8301 tgl 6487 CBC 1697126 : int4_sum(PG_FUNCTION_ARGS)
6488 : {
6489 : int64 newval;
6490 :
8301 tgl 6491 GIC 1697126 : if (PG_ARGISNULL(0))
6492 : {
6493 : /* No non-null input seen so far... */
8301 tgl 6494 CBC 43227 : if (PG_ARGISNULL(1))
8301 tgl 6495 GIC 493 : PG_RETURN_NULL(); /* still no non-null */
6496 : /* This is the first non-null input. */
7908 6497 42734 : newval = (int64) PG_GETARG_INT32(1);
6498 42734 : PG_RETURN_INT64(newval);
6499 : }
6500 :
6577 neilc 6501 ECB : /*
6502 : * If we're invoked as an aggregate, we can cheat and modify our first
6385 bruce 6503 : * parameter in-place to avoid palloc overhead. If not, we need to return
6504 : * the new value of the transition variable. (If int8 is pass-by-value,
5050 6505 : * then of course this is useless as well as incorrect, so just ifdef it
5050 bruce 6506 EUB : * out.)
6507 : */
5466 tgl 6508 ECB : #ifndef USE_FLOAT8_BYVAL /* controls int8 too */
6509 : if (AggCheckCallContext(fcinfo, NULL))
6510 : {
6511 : int64 *oldsum = (int64 *) PG_GETARG_POINTER(0);
6512 :
6513 : /* Leave the running sum unchanged in the new input is null */
6514 : if (!PG_ARGISNULL(1))
6515 : *oldsum = *oldsum + (int64) PG_GETARG_INT32(1);
6516 :
6517 : PG_RETURN_POINTER(oldsum);
6518 : }
6519 : else
6520 : #endif
6521 : {
6577 neilc 6522 GIC 1653899 : int64 oldsum = PG_GETARG_INT64(0);
6523 :
6524 : /* Leave sum unchanged if new input is null. */
6525 1653899 : if (PG_ARGISNULL(1))
6526 437 : PG_RETURN_INT64(oldsum);
6527 :
6528 : /* OK to do the addition. */
6529 1653462 : newval = oldsum + (int64) PG_GETARG_INT32(1);
6530 :
6531 1653462 : PG_RETURN_INT64(newval);
6532 : }
6533 : }
6534 :
3431 tgl 6535 ECB : /*
6536 : * Note: this function is obsolete, it's no longer used for SUM(int8).
6537 : */
6538 : Datum
8301 tgl 6539 LBC 0 : int8_sum(PG_FUNCTION_ARGS)
6540 : {
6541 : Numeric oldsum;
8301 tgl 6542 ECB :
8301 tgl 6543 UBC 0 : if (PG_ARGISNULL(0))
6544 : {
8301 tgl 6545 ECB : /* No non-null input seen so far... */
8301 tgl 6546 LBC 0 : if (PG_ARGISNULL(1))
8301 tgl 6547 UIC 0 : PG_RETURN_NULL(); /* still no non-null */
6548 : /* This is the first non-null input. */
942 peter 6549 0 : PG_RETURN_NUMERIC(int64_to_numeric(PG_GETARG_INT64(1)));
6550 : }
6551 :
6552 : /*
6553 : * Note that we cannot special-case the aggregate case here, as we do for
6554 : * int2_sum and int4_sum: numeric is of variable size, so we cannot modify
6555 : * our first parameter in-place.
6556 : */
6557 :
8301 tgl 6558 0 : oldsum = PG_GETARG_NUMERIC(0);
6559 :
6560 : /* Leave sum unchanged if new input is null. */
6561 0 : if (PG_ARGISNULL(1))
6562 0 : PG_RETURN_NUMERIC(oldsum);
6563 :
6564 : /* OK to do the addition. */
8289 6565 0 : PG_RETURN_DATUM(DirectFunctionCall2(numeric_add,
6566 : NumericGetDatum(oldsum),
6567 : NumericGetDatum(int64_to_numeric(PG_GETARG_INT64(1)))));
6568 : }
6569 :
8301 tgl 6570 ECB :
6571 : /*
6572 : * Routines for avg(int2) and avg(int4). The transition datatype
7908 6573 : * is a two-element int8 array, holding count and sum.
3284 tgl 6574 EUB : *
6575 : * These functions are also used for sum(int2) and sum(int4) when
6576 : * operating in moving-aggregate mode, since for correct inverse transitions
3284 tgl 6577 ECB : * we need to count the inputs.
6578 : */
7908 6579 :
6580 : typedef struct Int8TransTypeData
6581 : {
6582 : int64 count;
6583 : int64 sum;
6584 : } Int8TransTypeData;
6585 :
6586 : Datum
7908 tgl 6587 GIC 21 : int2_avg_accum(PG_FUNCTION_ARGS)
7908 tgl 6588 ECB : {
6589 : ArrayType *transarray;
7908 tgl 6590 GIC 21 : int16 newval = PG_GETARG_INT16(1);
7908 tgl 6591 ECB : Int8TransTypeData *transdata;
6592 :
6593 : /*
4808 6594 : * If we're invoked as an aggregate, we can cheat and modify our first
6385 bruce 6595 : * parameter in-place to reduce palloc overhead. Otherwise we need to make
6596 : * a copy of it before scribbling on it.
6597 : */
4808 tgl 6598 GIC 21 : if (AggCheckCallContext(fcinfo, NULL))
6579 neilc 6599 21 : transarray = PG_GETARG_ARRAYTYPE_P(0);
6600 : else
6579 neilc 6601 UIC 0 : transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
6602 :
6352 tgl 6603 GIC 21 : if (ARR_HASNULL(transarray) ||
6604 21 : ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
7196 tgl 6605 UIC 0 : elog(ERROR, "expected 2-element int8 array");
6606 :
6579 neilc 6607 GIC 21 : transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
7908 tgl 6608 21 : transdata->count++;
6609 21 : transdata->sum += newval;
6610 :
6611 21 : PG_RETURN_ARRAYTYPE_P(transarray);
6612 : }
6613 :
6614 : Datum
6615 1326402 : int4_avg_accum(PG_FUNCTION_ARGS)
6616 : {
6617 : ArrayType *transarray;
6618 1326402 : int32 newval = PG_GETARG_INT32(1);
7908 tgl 6619 ECB : Int8TransTypeData *transdata;
6620 :
6621 : /*
4808 6622 : * If we're invoked as an aggregate, we can cheat and modify our first
6385 bruce 6623 : * parameter in-place to reduce palloc overhead. Otherwise we need to make
6624 : * a copy of it before scribbling on it.
6625 : */
4808 tgl 6626 CBC 1326402 : if (AggCheckCallContext(fcinfo, NULL))
6579 neilc 6627 GIC 1326402 : transarray = PG_GETARG_ARRAYTYPE_P(0);
6579 neilc 6628 ECB : else
6579 neilc 6629 UIC 0 : transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
6630 :
6352 tgl 6631 GIC 1326402 : if (ARR_HASNULL(transarray) ||
6632 1326402 : ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
7196 tgl 6633 UIC 0 : elog(ERROR, "expected 2-element int8 array");
6634 :
6579 neilc 6635 GIC 1326402 : transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
7908 tgl 6636 GBC 1326402 : transdata->count++;
7908 tgl 6637 GIC 1326402 : transdata->sum += newval;
6638 :
6639 1326402 : PG_RETURN_ARRAYTYPE_P(transarray);
7908 tgl 6640 EUB : }
6641 :
6642 : Datum
2560 rhaas 6643 GBC 1973 : int4_avg_combine(PG_FUNCTION_ARGS)
2560 rhaas 6644 EUB : {
6645 : ArrayType *transarray1;
6646 : ArrayType *transarray2;
6647 : Int8TransTypeData *state1;
6648 : Int8TransTypeData *state2;
6649 :
2560 rhaas 6650 GIC 1973 : if (!AggCheckCallContext(fcinfo, NULL))
2560 rhaas 6651 UIC 0 : elog(ERROR, "aggregate function called in non-aggregate context");
6652 :
2560 rhaas 6653 GIC 1973 : transarray1 = PG_GETARG_ARRAYTYPE_P(0);
6654 1973 : transarray2 = PG_GETARG_ARRAYTYPE_P(1);
2560 rhaas 6655 EUB :
2560 rhaas 6656 GIC 1973 : if (ARR_HASNULL(transarray1) ||
6657 1973 : ARR_SIZE(transarray1) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
2560 rhaas 6658 UBC 0 : elog(ERROR, "expected 2-element int8 array");
2560 rhaas 6659 EUB :
2560 rhaas 6660 GIC 1973 : if (ARR_HASNULL(transarray2) ||
6661 1973 : ARR_SIZE(transarray2) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
2560 rhaas 6662 UBC 0 : elog(ERROR, "expected 2-element int8 array");
6663 :
2560 rhaas 6664 GIC 1973 : state1 = (Int8TransTypeData *) ARR_DATA_PTR(transarray1);
6665 1973 : state2 = (Int8TransTypeData *) ARR_DATA_PTR(transarray2);
6666 :
6667 1973 : state1->count += state2->count;
6668 1973 : state1->sum += state2->sum;
6669 :
6670 1973 : PG_RETURN_ARRAYTYPE_P(transarray1);
6671 : }
6672 :
6673 : Datum
3284 tgl 6674 6 : int2_avg_accum_inv(PG_FUNCTION_ARGS)
6675 : {
6676 : ArrayType *transarray;
6677 6 : int16 newval = PG_GETARG_INT16(1);
6678 : Int8TransTypeData *transdata;
6679 :
6680 : /*
6681 : * If we're invoked as an aggregate, we can cheat and modify our first
6682 : * parameter in-place to reduce palloc overhead. Otherwise we need to make
6683 : * a copy of it before scribbling on it.
3284 tgl 6684 ECB : */
3284 tgl 6685 GIC 6 : if (AggCheckCallContext(fcinfo, NULL))
6686 6 : transarray = PG_GETARG_ARRAYTYPE_P(0);
3284 tgl 6687 ECB : else
3284 tgl 6688 UIC 0 : transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
6689 :
3284 tgl 6690 GIC 6 : if (ARR_HASNULL(transarray) ||
6691 6 : ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
3284 tgl 6692 UIC 0 : elog(ERROR, "expected 2-element int8 array");
6693 :
3284 tgl 6694 GIC 6 : transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
3284 tgl 6695 CBC 6 : transdata->count--;
6696 6 : transdata->sum -= newval;
6697 :
3284 tgl 6698 GBC 6 : PG_RETURN_ARRAYTYPE_P(transarray);
6699 : }
3284 tgl 6700 ECB :
6701 : Datum
3284 tgl 6702 GBC 726 : int4_avg_accum_inv(PG_FUNCTION_ARGS)
6703 : {
3284 tgl 6704 ECB : ArrayType *transarray;
3284 tgl 6705 CBC 726 : int32 newval = PG_GETARG_INT32(1);
3284 tgl 6706 ECB : Int8TransTypeData *transdata;
6707 :
6708 : /*
6709 : * If we're invoked as an aggregate, we can cheat and modify our first
6710 : * parameter in-place to reduce palloc overhead. Otherwise we need to make
6711 : * a copy of it before scribbling on it.
6712 : */
3284 tgl 6713 GIC 726 : if (AggCheckCallContext(fcinfo, NULL))
6714 726 : transarray = PG_GETARG_ARRAYTYPE_P(0);
3284 tgl 6715 ECB : else
3284 tgl 6716 UIC 0 : transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
6717 :
3284 tgl 6718 GIC 726 : if (ARR_HASNULL(transarray) ||
6719 726 : ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
3284 tgl 6720 UIC 0 : elog(ERROR, "expected 2-element int8 array");
6721 :
3284 tgl 6722 GIC 726 : transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
3284 tgl 6723 CBC 726 : transdata->count--;
6724 726 : transdata->sum -= newval;
6725 :
3284 tgl 6726 GBC 726 : PG_RETURN_ARRAYTYPE_P(transarray);
6727 : }
3284 tgl 6728 ECB :
7908 6729 : Datum
7908 tgl 6730 GBC 5363 : int8_avg(PG_FUNCTION_ARGS)
6731 : {
7908 tgl 6732 CBC 5363 : ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
7908 tgl 6733 ECB : Int8TransTypeData *transdata;
6734 : Datum countd,
6735 : sumd;
6736 :
6352 tgl 6737 GIC 5363 : if (ARR_HASNULL(transarray) ||
6738 5363 : ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
7196 tgl 6739 UIC 0 : elog(ERROR, "expected 2-element int8 array");
7908 tgl 6740 CBC 5363 : transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
6741 :
6742 : /* SQL defines AVG of no values to be NULL */
7908 tgl 6743 GIC 5363 : if (transdata->count == 0)
6744 59 : PG_RETURN_NULL();
6745 :
942 peter 6746 5304 : countd = NumericGetDatum(int64_to_numeric(transdata->count));
942 peter 6747 CBC 5304 : sumd = NumericGetDatum(int64_to_numeric(transdata->sum));
7908 tgl 6748 EUB :
7908 tgl 6749 GIC 5304 : PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumd, countd));
7908 tgl 6750 ECB : }
6751 :
6752 : /*
3284 6753 : * SUM(int2) and SUM(int4) both return int8, so we can use this
6754 : * final function for both.
3284 tgl 6755 EUB : */
6756 : Datum
3284 tgl 6757 CBC 2766 : int2int4_sum(PG_FUNCTION_ARGS)
3284 tgl 6758 ECB : {
3284 tgl 6759 GBC 2766 : ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
6760 : Int8TransTypeData *transdata;
3284 tgl 6761 ECB :
3284 tgl 6762 CBC 2766 : if (ARR_HASNULL(transarray) ||
3284 tgl 6763 GIC 2766 : ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
3284 tgl 6764 LBC 0 : elog(ERROR, "expected 2-element int8 array");
3284 tgl 6765 CBC 2766 : transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
6766 :
3284 tgl 6767 ECB : /* SQL defines SUM of no values to be NULL */
3284 tgl 6768 GIC 2766 : if (transdata->count == 0)
6769 249 : PG_RETURN_NULL();
6770 :
3284 tgl 6771 CBC 2517 : PG_RETURN_DATUM(Int64GetDatumFast(transdata->sum));
6772 : }
6773 :
7908 tgl 6774 ECB :
6775 : /* ----------------------------------------------------------------------
6776 : *
6777 : * Debug support
6778 : *
6779 : * ----------------------------------------------------------------------
6780 : */
6781 :
8866 JanWieck 6782 : #ifdef NUMERIC_DEBUG
6783 :
6784 : /*
8866 JanWieck 6785 EUB : * dump_numeric() - Dump a value in the db storage format for debugging
6786 : */
8866 JanWieck 6787 ECB : static void
7324 tgl 6788 : dump_numeric(const char *str, Numeric num)
8866 JanWieck 6789 EUB : {
6790 : NumericDigit *digits = NUMERIC_DIGITS(num);
7324 tgl 6791 ECB : int ndigits;
8720 bruce 6792 : int i;
8866 JanWieck 6793 :
6794 : ndigits = NUMERIC_NDIGITS(num);
7324 tgl 6795 :
6796 : printf("%s: NUMERIC w=%d d=%d ", str,
6797 : NUMERIC_WEIGHT(num), NUMERIC_DSCALE(num));
6798 : switch (NUMERIC_SIGN(num))
8866 JanWieck 6799 : {
6800 : case NUMERIC_POS:
6801 : printf("POS");
8720 bruce 6802 : break;
6803 : case NUMERIC_NEG:
6804 : printf("NEG");
6805 : break;
6806 : case NUMERIC_NAN:
6807 : printf("NaN");
6808 : break;
6809 : case NUMERIC_PINF:
991 tgl 6810 : printf("Infinity");
6811 : break;
6812 : case NUMERIC_NINF:
991 tgl 6813 EUB : printf("-Infinity");
6814 : break;
8720 bruce 6815 ECB : default:
6816 : printf("SIGN=0x%x", NUMERIC_SIGN(num));
8720 bruce 6817 EUB : break;
6818 : }
8866 JanWieck 6819 ECB :
7324 tgl 6820 : for (i = 0; i < ndigits; i++)
6821 : printf(" %0*d", DEC_DIGITS, digits[i]);
6822 : printf("\n");
8866 JanWieck 6823 : }
6824 :
6825 :
6826 : /*
6827 : * dump_var() - Dump a value in the variable format for debugging
6828 : */
6829 : static void
6830 : dump_var(const char *str, NumericVar *var)
6831 : {
6832 : int i;
6833 :
7324 tgl 6834 : printf("%s: VAR w=%d d=%d ", str, var->weight, var->dscale);
8866 JanWieck 6835 : switch (var->sign)
8866 JanWieck 6836 EUB : {
8720 bruce 6837 ECB : case NUMERIC_POS:
6838 : printf("POS");
6839 : break;
6840 : case NUMERIC_NEG:
6841 : printf("NEG");
6842 : break;
6843 : case NUMERIC_NAN:
6844 : printf("NaN");
6845 : break;
991 tgl 6846 : case NUMERIC_PINF:
6847 : printf("Infinity");
6848 : break;
6849 : case NUMERIC_NINF:
6850 : printf("-Infinity");
6851 : break;
6852 : default:
6853 : printf("SIGN=0x%x", var->sign);
8720 bruce 6854 : break;
6855 : }
8866 JanWieck 6856 :
6857 : for (i = 0; i < var->ndigits; i++)
6858 : printf(" %0*d", DEC_DIGITS, var->digits[i]);
8720 bruce 6859 :
8866 JanWieck 6860 : printf("\n");
8866 JanWieck 6861 EUB : }
2118 tgl 6862 ECB : #endif /* NUMERIC_DEBUG */
6863 :
6864 :
7324 6865 : /* ----------------------------------------------------------------------
6866 : *
6867 : * Local functions follow
6868 : *
6869 : * In general, these do not support "special" (NaN or infinity) inputs;
6870 : * callers should handle those possibilities first.
6871 : * (There are one or two exceptions, noted in their header comments.)
6872 : *
6873 : * ----------------------------------------------------------------------
6874 : */
6875 :
6876 :
6877 : /*
6878 : * alloc_var() -
6879 : *
6880 : * Allocate a digit buffer of ndigits digits (plus a spare digit for rounding)
6881 : */
6882 : static void
8482 tgl 6883 GIC 1409144 : alloc_var(NumericVar *var, int ndigits)
6884 : {
6885 1409144 : digitbuf_free(var->buf);
6886 1409144 : var->buf = digitbuf_alloc(ndigits + 1);
7188 bruce 6887 1409144 : var->buf[0] = 0; /* spare digit for rounding */
8482 tgl 6888 1409144 : var->digits = var->buf + 1;
6889 1409144 : var->ndigits = ndigits;
8866 JanWieck 6890 1409144 : }
6891 :
6892 :
6893 : /*
6894 : * free_var() -
6895 : *
6896 : * Return the digit buffer of a variable to the free pool
6897 : */
6898 : static void
8720 bruce 6899 1610031 : free_var(NumericVar *var)
6900 : {
8482 tgl 6901 1610031 : digitbuf_free(var->buf);
6902 1610031 : var->buf = NULL;
6903 1610031 : var->digits = NULL;
8866 JanWieck 6904 1610031 : var->sign = NUMERIC_NAN;
6905 1610031 : }
6906 :
6907 :
6908 : /*
6909 : * zero_var() -
6910 : *
6911 : * Set a variable to ZERO.
6912 : * Note: its dscale is not touched.
6913 : */
6914 : static void
8482 tgl 6915 20247 : zero_var(NumericVar *var)
6916 : {
6917 20247 : digitbuf_free(var->buf);
6918 20247 : var->buf = NULL;
6919 20247 : var->digits = NULL;
6920 20247 : var->ndigits = 0;
6921 20247 : var->weight = 0; /* by convention; doesn't really matter */
6922 20247 : var->sign = NUMERIC_POS; /* anything but NAN... */
8866 JanWieck 6923 20247 : }
6924 :
6925 :
6926 : /*
6927 : * set_var_from_str()
6928 : *
6929 : * Parse a string and put the number into a variable
6930 : *
6931 : * This function does not handle leading or trailing spaces. It returns
6932 : * the end+1 position parsed into *endptr, so that caller can check for
6933 : * trailing spaces/garbage if deemed necessary.
6934 : *
6935 : * cp is the place to actually start parsing; str is what to use in error
6936 : * reports. (Typically cp would be the same except advanced over spaces.)
6937 : *
6938 : * Returns true on success, false on failure (if escontext points to an
6939 : * ErrorSaveContext; otherwise errors are thrown).
6940 : */
6941 : static bool
121 tgl 6942 GNC 57675 : set_var_from_str(const char *str, const char *cp,
6943 : NumericVar *dest, const char **endptr,
6944 : Node *escontext)
6945 : {
2062 peter_e 6946 GIC 57675 : bool have_dp = false;
6947 : int i;
6948 : unsigned char *decdigits;
7324 tgl 6949 57675 : int sign = NUMERIC_POS;
6950 57675 : int dweight = -1;
6951 : int ddigits;
6952 57675 : int dscale = 0;
6953 : int weight;
6954 : int ndigits;
6955 : int offset;
6956 : NumericDigit *digits;
6957 :
6958 : /*
6959 : * We first parse the string to extract decimal digits and determine the
6960 : * correct decimal weight. Then convert to NBASE representation.
6961 : */
8866 JanWieck 6962 57675 : switch (*cp)
6963 : {
8720 bruce 6964 UIC 0 : case '+':
7324 tgl 6965 0 : sign = NUMERIC_POS;
8720 bruce 6966 0 : cp++;
6967 0 : break;
6968 :
8720 bruce 6969 GIC 150 : case '-':
7324 tgl 6970 150 : sign = NUMERIC_NEG;
8720 bruce 6971 150 : cp++;
6972 150 : break;
6973 : }
6974 :
8866 JanWieck 6975 57675 : if (*cp == '.')
6976 : {
2062 peter_e 6977 188 : have_dp = true;
8866 JanWieck 6978 188 : cp++;
6979 : }
6980 :
8162 tgl 6981 57675 : if (!isdigit((unsigned char) *cp))
64 dean.a.rasheed 6982 UNC 0 : goto invalid_syntax;
6983 :
7188 bruce 6984 CBC 57675 : decdigits = (unsigned char *) palloc(strlen(cp) + DEC_DIGITS * 2);
7324 tgl 6985 ECB :
6986 : /* leading padding for digit alignment later */
7324 tgl 6987 CBC 57675 : memset(decdigits, 0, DEC_DIGITS);
6988 57675 : i = DEC_DIGITS;
7324 tgl 6989 ECB :
8866 JanWieck 6990 GIC 233925 : while (*cp)
6991 : {
8162 tgl 6992 176781 : if (isdigit((unsigned char) *cp))
6993 : {
7324 6994 168613 : decdigits[i++] = *cp++ - '0';
8482 6995 168613 : if (!have_dp)
7324 6996 137325 : dweight++;
6997 : else
7324 tgl 6998 CBC 31288 : dscale++;
6999 : }
8482 7000 8168 : else if (*cp == '.')
8482 tgl 7001 ECB : {
8482 tgl 7002 CBC 7556 : if (have_dp)
64 dean.a.rasheed 7003 UNC 0 : goto invalid_syntax;
2062 peter_e 7004 GIC 7556 : have_dp = true;
8482 tgl 7005 7556 : cp++;
7006 : /* decimal point must not be followed by underscore */
64 dean.a.rasheed 7007 GNC 7556 : if (*cp == '_')
7008 3 : goto invalid_syntax;
7009 : }
7010 612 : else if (*cp == '_')
7011 : {
7012 : /* underscore must be followed by more digits */
7013 93 : cp++;
7014 93 : if (!isdigit((unsigned char) *cp))
7015 9 : goto invalid_syntax;
7016 : }
7017 : else
8482 tgl 7018 GIC 519 : break;
7019 : }
7020 :
7324 tgl 7021 CBC 57663 : ddigits = i - DEC_DIGITS;
7022 : /* trailing padding for digit alignment later */
7188 bruce 7023 57663 : memset(decdigits + i, 0, DEC_DIGITS - 1);
8866 JanWieck 7024 ECB :
8482 tgl 7025 : /* Handle exponent, if any */
8866 JanWieck 7026 CBC 57663 : if (*cp == 'e' || *cp == 'E')
8866 JanWieck 7027 ECB : {
64 dean.a.rasheed 7028 GNC 501 : int64 exponent = 0;
7029 501 : bool neg = false;
7030 :
7031 : /*
7032 : * At this point, dweight and dscale can't be more than about
7033 : * INT_MAX/2 due to the MaxAllocSize limit on string length, so
7034 : * constraining the exponent similarly should be enough to prevent
7035 : * integer overflow in this function. If the value is too large to
7036 : * fit in storage format, make_result() will complain about it later;
7037 : * for consistency use the same ereport errcode/text as make_result().
7038 : */
7039 :
7040 : /* exponent sign */
7041 501 : cp++;
7042 501 : if (*cp == '+')
7043 77 : cp++;
7044 424 : else if (*cp == '-')
7045 : {
7046 190 : neg = true;
7047 190 : cp++;
7048 : }
7049 :
7050 : /* exponent digits */
7051 501 : if (!isdigit((unsigned char) *cp))
7052 3 : goto invalid_syntax;
7053 :
7054 1521 : while (*cp)
7055 : {
7056 1032 : if (isdigit((unsigned char) *cp))
7057 : {
7058 1011 : exponent = exponent * 10 + (*cp++ - '0');
7059 1011 : if (exponent > PG_INT32_MAX / 2)
7060 3 : goto out_of_range;
7061 : }
7062 21 : else if (*cp == '_')
7063 : {
7064 : /* underscore must be followed by more digits */
7065 21 : cp++;
7066 21 : if (!isdigit((unsigned char) *cp))
7067 6 : goto invalid_syntax;
7068 : }
7069 : else
64 dean.a.rasheed 7070 UNC 0 : break;
7071 : }
7072 :
64 dean.a.rasheed 7073 GNC 489 : if (neg)
7074 190 : exponent = -exponent;
7075 :
7324 tgl 7076 CBC 489 : dweight += (int) exponent;
7324 tgl 7077 GIC 489 : dscale -= (int) exponent;
7078 489 : if (dscale < 0)
7324 tgl 7079 CBC 197 : dscale = 0;
8482 tgl 7080 ECB : }
7081 :
7324 7082 : /*
7083 : * Okay, convert pure-decimal representation to base NBASE. First we need
7084 : * to determine the converted weight and ndigits. offset is the number of
7085 : * decimal zeroes to insert before the first given digit to have a
7086 : * correctly aligned first NBASE digit.
7087 : */
7324 tgl 7088 GIC 57651 : if (dweight >= 0)
7188 bruce 7089 57324 : weight = (dweight + 1 + DEC_DIGITS - 1) / DEC_DIGITS - 1;
7090 : else
7091 327 : weight = -((-dweight - 1) / DEC_DIGITS + 1);
7324 tgl 7092 CBC 57651 : offset = (weight + 1) * DEC_DIGITS - (dweight + 1);
7188 bruce 7093 GIC 57651 : ndigits = (ddigits + offset + DEC_DIGITS - 1) / DEC_DIGITS;
7324 tgl 7094 EUB :
7324 tgl 7095 GBC 57651 : alloc_var(dest, ndigits);
7096 57651 : dest->sign = sign;
7097 57651 : dest->weight = weight;
7324 tgl 7098 GIC 57651 : dest->dscale = dscale;
7324 tgl 7099 ECB :
7324 tgl 7100 CBC 57651 : i = DEC_DIGITS - offset;
7101 57651 : digits = dest->digits;
7324 tgl 7102 ECB :
7324 tgl 7103 GIC 135687 : while (ndigits-- > 0)
7104 : {
7324 tgl 7105 ECB : #if DEC_DIGITS == 4
7188 bruce 7106 GIC 78036 : *digits++ = ((decdigits[i] * 10 + decdigits[i + 1]) * 10 +
7188 bruce 7107 CBC 78036 : decdigits[i + 2]) * 10 + decdigits[i + 3];
7324 tgl 7108 ECB : #elif DEC_DIGITS == 2
7109 : *digits++ = decdigits[i] * 10 + decdigits[i + 1];
7110 : #elif DEC_DIGITS == 1
7111 : *digits++ = decdigits[i];
7324 tgl 7112 EUB : #else
7113 : #error unsupported NBASE
7324 tgl 7114 ECB : #endif
7324 tgl 7115 GIC 78036 : i += DEC_DIGITS;
7116 : }
8866 JanWieck 7117 ECB :
7324 tgl 7118 CBC 57651 : pfree(decdigits);
7119 :
7324 tgl 7120 ECB : /* Strip any leading/trailing zeroes, and normalize weight if zero */
7324 tgl 7121 GIC 57651 : strip_var(dest);
5114 tgl 7122 ECB :
7123 : /* Return end+1 position for caller */
121 tgl 7124 GNC 57651 : *endptr = cp;
7125 :
7126 57651 : return true;
7127 :
64 dean.a.rasheed 7128 3 : out_of_range:
7129 3 : ereturn(escontext, false,
7130 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
7131 : errmsg("value overflows numeric format")));
7132 :
7133 21 : invalid_syntax:
7134 21 : ereturn(escontext, false,
7135 : (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
7136 : errmsg("invalid input syntax for type %s: \"%s\"",
7137 : "numeric", str)));
7138 : }
7139 :
7140 :
7141 : /*
7142 : * Return the numeric value of a single hex digit.
7143 : */
7144 : static inline int
76 7145 354 : xdigit_value(char dig)
7146 : {
7147 447 : return dig >= '0' && dig <= '9' ? dig - '0' :
7148 147 : dig >= 'a' && dig <= 'f' ? dig - 'a' + 10 :
7149 54 : dig >= 'A' && dig <= 'F' ? dig - 'A' + 10 : -1;
7150 : }
7151 :
7152 : /*
7153 : * set_var_from_non_decimal_integer_str()
7154 : *
7155 : * Parse a string containing a non-decimal integer
7156 : *
7157 : * This function does not handle leading or trailing spaces. It returns
7158 : * the end+1 position parsed into *endptr, so that caller can check for
7159 : * trailing spaces/garbage if deemed necessary.
7160 : *
7161 : * cp is the place to actually start parsing; str is what to use in error
7162 : * reports. The number's sign and base prefix indicator (e.g., "0x") are
7163 : * assumed to have already been parsed, so cp should point to the number's
7164 : * first digit in the base specified.
7165 : *
7166 : * base is expected to be 2, 8 or 16.
7167 : *
7168 : * Returns true on success, false on failure (if escontext points to an
7169 : * ErrorSaveContext; otherwise errors are thrown).
7170 : */
7171 : static bool
7172 78 : set_var_from_non_decimal_integer_str(const char *str, const char *cp, int sign,
7173 : int base, NumericVar *dest,
7174 : const char **endptr, Node *escontext)
7175 : {
7176 78 : const char *firstdigit = cp;
7177 : int64 tmp;
7178 : int64 mul;
7179 : NumericVar tmp_var;
7180 :
7181 78 : init_var(&tmp_var);
7182 :
7183 78 : zero_var(dest);
7184 :
7185 : /*
7186 : * Process input digits in groups that fit in int64. Here "tmp" is the
7187 : * value of the digits in the group, and "mul" is base^n, where n is the
7188 : * number of digits in the group. Thus tmp < mul, and we must start a new
7189 : * group when mul * base threatens to overflow PG_INT64_MAX.
7190 : */
7191 78 : tmp = 0;
7192 78 : mul = 1;
7193 :
7194 78 : if (base == 16)
7195 : {
7196 414 : while (*cp)
7197 : {
7198 399 : if (isxdigit((unsigned char) *cp))
7199 : {
7200 354 : if (mul > PG_INT64_MAX / 16)
7201 : {
7202 : /* Add the contribution from this group of digits */
7203 15 : int64_to_numericvar(mul, &tmp_var);
7204 15 : mul_var(dest, &tmp_var, dest, 0);
7205 15 : int64_to_numericvar(tmp, &tmp_var);
7206 15 : add_var(dest, &tmp_var, dest);
7207 :
7208 : /* Result will overflow if weight overflows int16 */
7209 15 : if (dest->weight > SHRT_MAX)
76 dean.a.rasheed 7210 UNC 0 : goto out_of_range;
7211 :
7212 : /* Begin a new group */
76 dean.a.rasheed 7213 GNC 15 : tmp = 0;
7214 15 : mul = 1;
7215 : }
7216 :
7217 354 : tmp = tmp * 16 + xdigit_value(*cp++);
7218 354 : mul = mul * 16;
7219 : }
64 7220 45 : else if (*cp == '_')
7221 : {
7222 : /* Underscore must be followed by more digits */
7223 33 : cp++;
7224 33 : if (!isxdigit((unsigned char) *cp))
7225 9 : goto invalid_syntax;
7226 : }
7227 : else
76 7228 12 : break;
7229 : }
7230 : }
7231 42 : else if (base == 8)
7232 : {
7233 318 : while (*cp)
7234 : {
7235 303 : if (*cp >= '0' && *cp <= '7')
7236 : {
7237 279 : if (mul > PG_INT64_MAX / 8)
7238 : {
7239 : /* Add the contribution from this group of digits */
7240 9 : int64_to_numericvar(mul, &tmp_var);
7241 9 : mul_var(dest, &tmp_var, dest, 0);
7242 9 : int64_to_numericvar(tmp, &tmp_var);
7243 9 : add_var(dest, &tmp_var, dest);
7244 :
7245 : /* Result will overflow if weight overflows int16 */
7246 9 : if (dest->weight > SHRT_MAX)
76 dean.a.rasheed 7247 UNC 0 : goto out_of_range;
7248 :
7249 : /* Begin a new group */
76 dean.a.rasheed 7250 GNC 9 : tmp = 0;
7251 9 : mul = 1;
7252 : }
7253 :
7254 279 : tmp = tmp * 8 + (*cp++ - '0');
7255 279 : mul = mul * 8;
7256 : }
64 7257 24 : else if (*cp == '_')
7258 : {
7259 : /* Underscore must be followed by more digits */
7260 18 : cp++;
7261 18 : if (*cp < '0' || *cp > '7')
64 dean.a.rasheed 7262 UNC 0 : goto invalid_syntax;
7263 : }
7264 : else
76 dean.a.rasheed 7265 GNC 6 : break;
7266 : }
7267 : }
7268 21 : else if (base == 2)
7269 : {
7270 780 : while (*cp)
7271 : {
7272 765 : if (*cp >= '0' && *cp <= '1')
7273 : {
7274 708 : if (mul > PG_INT64_MAX / 2)
7275 : {
7276 : /* Add the contribution from this group of digits */
7277 9 : int64_to_numericvar(mul, &tmp_var);
7278 9 : mul_var(dest, &tmp_var, dest, 0);
7279 9 : int64_to_numericvar(tmp, &tmp_var);
7280 9 : add_var(dest, &tmp_var, dest);
7281 :
7282 : /* Result will overflow if weight overflows int16 */
7283 9 : if (dest->weight > SHRT_MAX)
76 dean.a.rasheed 7284 UNC 0 : goto out_of_range;
7285 :
7286 : /* Begin a new group */
76 dean.a.rasheed 7287 GNC 9 : tmp = 0;
7288 9 : mul = 1;
7289 : }
7290 :
7291 708 : tmp = tmp * 2 + (*cp++ - '0');
7292 708 : mul = mul * 2;
7293 : }
64 7294 57 : else if (*cp == '_')
7295 : {
7296 : /* Underscore must be followed by more digits */
7297 51 : cp++;
7298 51 : if (*cp < '0' || *cp > '1')
64 dean.a.rasheed 7299 UNC 0 : goto invalid_syntax;
7300 : }
7301 : else
76 dean.a.rasheed 7302 GNC 6 : break;
7303 : }
7304 : }
7305 : else
7306 : /* Should never happen; treat as invalid input */
76 dean.a.rasheed 7307 UNC 0 : goto invalid_syntax;
7308 :
7309 : /* Check that we got at least one digit */
76 dean.a.rasheed 7310 GNC 69 : if (unlikely(cp == firstdigit))
76 dean.a.rasheed 7311 UNC 0 : goto invalid_syntax;
7312 :
7313 : /* Add the contribution from the final group of digits */
76 dean.a.rasheed 7314 GNC 69 : int64_to_numericvar(mul, &tmp_var);
7315 69 : mul_var(dest, &tmp_var, dest, 0);
7316 69 : int64_to_numericvar(tmp, &tmp_var);
7317 69 : add_var(dest, &tmp_var, dest);
7318 :
7319 69 : if (dest->weight > SHRT_MAX)
76 dean.a.rasheed 7320 UNC 0 : goto out_of_range;
7321 :
76 dean.a.rasheed 7322 GNC 69 : dest->sign = sign;
7323 :
7324 69 : free_var(&tmp_var);
7325 :
7326 : /* Return end+1 position for caller */
7327 69 : *endptr = cp;
7328 :
7329 69 : return true;
7330 :
76 dean.a.rasheed 7331 UNC 0 : out_of_range:
7332 0 : ereturn(escontext, false,
7333 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
7334 : errmsg("value overflows numeric format")));
7335 :
76 dean.a.rasheed 7336 GNC 9 : invalid_syntax:
7337 9 : ereturn(escontext, false,
7338 : (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
7339 : errmsg("invalid input syntax for type %s: \"%s\"",
7340 : "numeric", str)));
76 dean.a.rasheed 7341 ECB : }
7342 :
7343 :
8866 JanWieck 7344 : /*
7345 : * set_var_from_num() -
7346 : *
7347 : * Convert the packed db format into a variable
7348 : */
8866 JanWieck 7349 EUB : static void
8720 bruce 7350 CBC 6184 : set_var_from_num(Numeric num, NumericVar *dest)
8866 JanWieck 7351 ECB : {
7352 : int ndigits;
7353 :
6270 bruce 7354 CBC 6184 : ndigits = NUMERIC_NDIGITS(num);
7355 :
7324 tgl 7356 6184 : alloc_var(dest, ndigits);
7357 :
4632 rhaas 7358 GIC 6184 : dest->weight = NUMERIC_WEIGHT(num);
8720 bruce 7359 CBC 6184 : dest->sign = NUMERIC_SIGN(num);
7324 tgl 7360 6184 : dest->dscale = NUMERIC_DSCALE(num);
8866 JanWieck 7361 ECB :
4632 rhaas 7362 GIC 6184 : memcpy(dest->digits, NUMERIC_DIGITS(num), ndigits * sizeof(NumericDigit));
8866 JanWieck 7363 6184 : }
8866 JanWieck 7364 ECB :
7365 :
7366 : /*
3791 heikki.linnakangas 7367 : * init_var_from_num() -
7368 : *
7369 : * Initialize a variable from packed db format. The digits array is not
7370 : * copied, which saves some cycles when the resulting var is not modified.
7371 : * Also, there's no need to call free_var(), as long as you don't assign any
7372 : * other value to it (with set_var_* functions, or by using the var as the
7373 : * destination of a function like add_var())
7374 : *
7375 : * CAUTION: Do not modify the digits buffer of a var initialized with this
7376 : * function, e.g by calling round_var() or trunc_var(), as the changes will
7377 : * propagate to the original Numeric! It's OK to use it as the destination
7378 : * argument of one of the calculational functions, though.
7379 : */
7380 : static void
3791 heikki.linnakangas 7381 GIC 2426534 : init_var_from_num(Numeric num, NumericVar *dest)
7382 : {
7383 2426534 : dest->ndigits = NUMERIC_NDIGITS(num);
7384 2426534 : dest->weight = NUMERIC_WEIGHT(num);
7385 2426534 : dest->sign = NUMERIC_SIGN(num);
7386 2426534 : dest->dscale = NUMERIC_DSCALE(num);
3791 heikki.linnakangas 7387 CBC 2426534 : dest->digits = NUMERIC_DIGITS(num);
3602 bruce 7388 2426534 : dest->buf = NULL; /* digits array is not palloc'd */
3791 heikki.linnakangas 7389 2426534 : }
3791 heikki.linnakangas 7390 ECB :
7391 :
7324 tgl 7392 : /*
8866 JanWieck 7393 : * set_var_from_var() -
7394 : *
7395 : * Copy one variable into another
7396 : */
7397 : static void
2037 andres 7398 CBC 16592 : set_var_from_var(const NumericVar *value, NumericVar *dest)
7399 : {
8482 tgl 7400 ECB : NumericDigit *newbuf;
7401 :
8482 tgl 7402 CBC 16592 : newbuf = digitbuf_alloc(value->ndigits + 1);
8482 tgl 7403 GIC 16592 : newbuf[0] = 0; /* spare digit for rounding */
2807 tgl 7404 CBC 16592 : if (value->ndigits > 0) /* else value->digits might be null */
7405 16185 : memcpy(newbuf + 1, value->digits,
7406 16185 : value->ndigits * sizeof(NumericDigit));
7407 :
8866 JanWieck 7408 16592 : digitbuf_free(dest->buf);
7409 :
7004 neilc 7410 GIC 16592 : memmove(dest, value, sizeof(NumericVar));
8720 bruce 7411 CBC 16592 : dest->buf = newbuf;
8482 tgl 7412 16592 : dest->digits = newbuf + 1;
7413 16592 : }
7414 :
7415 :
7324 tgl 7416 EUB : /*
7417 : * get_str_from_var() -
7418 : *
8482 tgl 7419 ECB : * Convert a var to text representation (guts of numeric_out).
3791 heikki.linnakangas 7420 : * The var is displayed to the number of digits indicated by its dscale.
7421 : * Returns a palloc'd string.
8482 tgl 7422 : */
7423 : static char *
2037 andres 7424 CBC 394256 : get_str_from_var(const NumericVar *var)
8482 tgl 7425 ECB : {
7426 : int dscale;
7427 : char *str;
7428 : char *cp;
7429 : char *endcp;
7430 : int i;
7431 : int d;
7432 : NumericDigit dig;
7433 :
7324 7434 : #if DEC_DIGITS > 1
7188 bruce 7435 : NumericDigit d1;
7436 : #endif
7324 tgl 7437 :
3791 heikki.linnakangas 7438 CBC 394256 : dscale = var->dscale;
8482 tgl 7439 ECB :
7440 : /*
7324 7441 : * Allocate space for the result.
7442 : *
3994 heikki.linnakangas 7443 : * i is set to the # of decimal digits before decimal point. dscale is the
6347 bruce 7444 : * # of decimal digits we will print after decimal point. We may generate
7445 : * as many as DEC_DIGITS-1 excess digits at the end, and in addition we
7446 : * need room for sign, decimal point, null terminator.
8482 tgl 7447 : */
7324 tgl 7448 GIC 394256 : i = (var->weight + 1) * DEC_DIGITS;
7324 tgl 7449 CBC 394256 : if (i <= 0)
7324 tgl 7450 GIC 69223 : i = 1;
7451 :
7324 tgl 7452 CBC 394256 : str = palloc(i + dscale + DEC_DIGITS + 2);
8482 7453 394256 : cp = str;
7454 :
7455 : /*
7456 : * Output a dash for negative values
7457 : */
8482 tgl 7458 GIC 394256 : if (var->sign == NUMERIC_NEG)
7459 2395 : *cp++ = '-';
7460 :
8053 bruce 7461 ECB : /*
7462 : * Output all digits before the decimal point
7463 : */
7324 tgl 7464 CBC 394256 : if (var->weight < 0)
7465 : {
7324 tgl 7466 GIC 69223 : d = var->weight + 1;
7324 tgl 7467 CBC 69223 : *cp++ = '0';
7468 : }
7469 : else
7324 tgl 7470 ECB : {
7324 tgl 7471 GIC 697166 : for (d = 0; d <= var->weight; d++)
7324 tgl 7472 ECB : {
7324 tgl 7473 GIC 372133 : dig = (d < var->ndigits) ? var->digits[d] : 0;
7324 tgl 7474 ECB : /* In the first digit, suppress extra leading decimal zeroes */
7475 : #if DEC_DIGITS == 4
7476 : {
7188 bruce 7477 GIC 372133 : bool putit = (d > 0);
7478 :
7324 tgl 7479 CBC 372133 : d1 = dig / 1000;
7480 372133 : dig -= d1 * 1000;
7324 tgl 7481 GIC 372133 : putit |= (d1 > 0);
7482 372133 : if (putit)
7483 49883 : *cp++ = d1 + '0';
7484 372133 : d1 = dig / 100;
7485 372133 : dig -= d1 * 100;
7486 372133 : putit |= (d1 > 0);
7487 372133 : if (putit)
7488 252072 : *cp++ = d1 + '0';
7489 372133 : d1 = dig / 10;
7490 372133 : dig -= d1 * 10;
7324 tgl 7491 CBC 372133 : putit |= (d1 > 0);
7324 tgl 7492 GIC 372133 : if (putit)
7324 tgl 7493 CBC 315238 : *cp++ = d1 + '0';
7494 372133 : *cp++ = dig + '0';
7324 tgl 7495 ECB : }
7496 : #elif DEC_DIGITS == 2
7497 : d1 = dig / 10;
7498 : dig -= d1 * 10;
7499 : if (d1 > 0 || d > 0)
7500 : *cp++ = d1 + '0';
7501 : *cp++ = dig + '0';
7502 : #elif DEC_DIGITS == 1
7503 : *cp++ = dig + '0';
7504 : #else
7505 : #error unsupported NBASE
7506 : #endif
7507 : }
7508 : }
7509 :
7510 : /*
7511 : * If requested, output a decimal point and all the digits that follow it.
7512 : * We initially put out a multiple of DEC_DIGITS digits, then truncate if
7513 : * needed.
7514 : */
8482 tgl 7515 GIC 394256 : if (dscale > 0)
7516 : {
7517 320706 : *cp++ = '.';
7324 tgl 7518 CBC 320706 : endcp = cp + dscale;
7324 tgl 7519 GIC 945684 : for (i = 0; i < dscale; d++, i += DEC_DIGITS)
7520 : {
7521 624978 : dig = (d >= 0 && d < var->ndigits) ? var->digits[d] : 0;
7324 tgl 7522 ECB : #if DEC_DIGITS == 4
7324 tgl 7523 GIC 624978 : d1 = dig / 1000;
7524 624978 : dig -= d1 * 1000;
7525 624978 : *cp++ = d1 + '0';
7526 624978 : d1 = dig / 100;
7324 tgl 7527 CBC 624978 : dig -= d1 * 100;
7324 tgl 7528 GIC 624978 : *cp++ = d1 + '0';
7324 tgl 7529 CBC 624978 : d1 = dig / 10;
7324 tgl 7530 GIC 624978 : dig -= d1 * 10;
7531 624978 : *cp++ = d1 + '0';
7532 624978 : *cp++ = dig + '0';
7533 : #elif DEC_DIGITS == 2
7534 : d1 = dig / 10;
7535 : dig -= d1 * 10;
7536 : *cp++ = d1 + '0';
7324 tgl 7537 ECB : *cp++ = dig + '0';
7538 : #elif DEC_DIGITS == 1
7539 : *cp++ = dig + '0';
7540 : #else
7541 : #error unsupported NBASE
7542 : #endif
7543 : }
7324 tgl 7544 CBC 320706 : cp = endcp;
7545 : }
8482 tgl 7546 ECB :
7547 : /*
7548 : * terminate the string and return it
7549 : */
8482 tgl 7550 CBC 394256 : *cp = '\0';
7551 394256 : return str;
8866 JanWieck 7552 ECB : }
7553 :
7554 : /*
4990 tgl 7555 : * get_str_from_var_sci() -
4990 tgl 7556 EUB : *
7557 : * Convert a var to a normalised scientific notation text representation.
7558 : * This function does the heavy lifting for numeric_out_sci().
4990 tgl 7559 ECB : *
7560 : * This notation has the general form a * 10^b, where a is known as the
7561 : * "significand" and b is known as the "exponent".
7562 : *
7563 : * Because we can't do superscript in ASCII (and because we want to copy
7564 : * printf's behaviour) we display the exponent using E notation, with a
7565 : * minimum of two exponent digits.
7566 : *
7567 : * For example, the value 1234 could be output as 1.2e+03.
7568 : *
7569 : * We assume that the exponent can fit into an int32.
7570 : *
7571 : * rscale is the number of decimal digits desired after the decimal point in
7572 : * the output, negative values will be treated as meaning zero.
7573 : *
7574 : * Returns a palloc'd string.
7575 : */
7576 : static char *
2037 andres 7577 CBC 108 : get_str_from_var_sci(const NumericVar *var, int rscale)
7578 : {
4990 tgl 7579 ECB : int32 exponent;
7580 : NumericVar tmp_var;
7581 : size_t len;
7582 : char *str;
7583 : char *sig_out;
7584 :
4990 tgl 7585 GIC 108 : if (rscale < 0)
4990 tgl 7586 LBC 0 : rscale = 0;
4990 tgl 7587 ECB :
7588 : /*
7589 : * Determine the exponent of this number in normalised form.
7590 : *
7591 : * This is the exponent required to represent the number with only one
7592 : * significant digit before the decimal place.
4990 tgl 7593 EUB : */
4990 tgl 7594 GIC 108 : if (var->ndigits > 0)
7595 : {
4990 tgl 7596 CBC 99 : exponent = (var->weight + 1) * DEC_DIGITS;
4990 tgl 7597 ECB :
7598 : /*
7599 : * Compensate for leading decimal zeroes in the first numeric digit by
7600 : * decrementing the exponent.
7601 : */
4990 tgl 7602 GIC 99 : exponent -= DEC_DIGITS - (int) log10(var->digits[0]);
4990 tgl 7603 ECB : }
7604 : else
7605 : {
7606 : /*
7607 : * If var has no digits, then it must be zero.
4990 tgl 7608 EUB : *
7609 : * Zero doesn't technically have a meaningful exponent in normalised
7610 : * notation, but we just display the exponent as zero for consistency
4990 tgl 7611 ECB : * of output.
7612 : */
4990 tgl 7613 GIC 9 : exponent = 0;
4990 tgl 7614 ECB : }
7615 :
7616 : /*
7617 : * Divide var by 10^exponent to get the significand, rounding to rscale
612 dean.a.rasheed 7618 : * decimal digits in the process.
7619 : */
612 dean.a.rasheed 7620 CBC 108 : init_var(&tmp_var);
7621 :
612 dean.a.rasheed 7622 GIC 108 : power_ten_int(exponent, &tmp_var);
612 dean.a.rasheed 7623 CBC 108 : div_var(var, &tmp_var, &tmp_var, rscale, true);
7624 108 : sig_out = get_str_from_var(&tmp_var);
4990 tgl 7625 ECB :
612 dean.a.rasheed 7626 CBC 108 : free_var(&tmp_var);
7627 :
7628 : /*
4990 tgl 7629 ECB : * Allocate space for the result.
4990 tgl 7630 EUB : *
7631 : * In addition to the significand, we need room for the exponent
7632 : * decoration ("e"), the sign of the exponent, up to 10 digits for the
4790 bruce 7633 ECB : * exponent itself, and of course the null terminator.
4990 tgl 7634 : */
4990 tgl 7635 GIC 108 : len = strlen(sig_out) + 13;
7636 108 : str = palloc(len);
4990 tgl 7637 CBC 108 : snprintf(str, len, "%se%+03d", sig_out, exponent);
4990 tgl 7638 ECB :
4990 tgl 7639 GIC 108 : pfree(sig_out);
4990 tgl 7640 ECB :
4990 tgl 7641 GIC 108 : return str;
7642 : }
4990 tgl 7643 ECB :
8866 JanWieck 7644 :
643 dean.a.rasheed 7645 EUB : /*
7646 : * numericvar_serialize - serialize NumericVar to binary format
7647 : *
643 dean.a.rasheed 7648 ECB : * At variable level, no checks are performed on the weight or dscale, allowing
7649 : * us to pass around intermediate values with higher precision than supported
7650 : * by the numeric type. Note: this is incompatible with numeric_send/recv(),
7651 : * which use 16-bit integers for these fields.
7652 : */
643 dean.a.rasheed 7653 EUB : static void
643 dean.a.rasheed 7654 GIC 72 : numericvar_serialize(StringInfo buf, const NumericVar *var)
7655 : {
643 dean.a.rasheed 7656 ECB : int i;
643 dean.a.rasheed 7657 EUB :
643 dean.a.rasheed 7658 GIC 72 : pq_sendint32(buf, var->ndigits);
7659 72 : pq_sendint32(buf, var->weight);
643 dean.a.rasheed 7660 CBC 72 : pq_sendint32(buf, var->sign);
7661 72 : pq_sendint32(buf, var->dscale);
7662 318965 : for (i = 0; i < var->ndigits; i++)
7663 318893 : pq_sendint16(buf, var->digits[i]);
643 dean.a.rasheed 7664 GIC 72 : }
643 dean.a.rasheed 7665 ECB :
643 dean.a.rasheed 7666 EUB : /*
7667 : * numericvar_deserialize - deserialize binary format to NumericVar
643 dean.a.rasheed 7668 ECB : */
7669 : static void
643 dean.a.rasheed 7670 CBC 72 : numericvar_deserialize(StringInfo buf, NumericVar *var)
7671 : {
7672 : int len,
643 dean.a.rasheed 7673 ECB : i;
7674 :
643 dean.a.rasheed 7675 CBC 72 : len = pq_getmsgint(buf, sizeof(int32));
7676 :
643 dean.a.rasheed 7677 GBC 72 : alloc_var(var, len); /* sets var->ndigits */
643 dean.a.rasheed 7678 EUB :
643 dean.a.rasheed 7679 GIC 72 : var->weight = pq_getmsgint(buf, sizeof(int32));
7680 72 : var->sign = pq_getmsgint(buf, sizeof(int32));
7681 72 : var->dscale = pq_getmsgint(buf, sizeof(int32));
643 dean.a.rasheed 7682 CBC 318965 : for (i = 0; i < len; i++)
7683 318893 : var->digits[i] = pq_getmsgint(buf, sizeof(int16));
643 dean.a.rasheed 7684 GIC 72 : }
7685 :
7686 :
7687 : /*
7688 : * duplicate_numeric() - copy a packed-format Numeric
7689 : *
7690 : * This will handle NaN and Infinity cases.
7691 : */
7692 : static Numeric
991 tgl 7693 5102 : duplicate_numeric(Numeric num)
7694 : {
7695 : Numeric res;
991 tgl 7696 ECB :
991 tgl 7697 GIC 5102 : res = (Numeric) palloc(VARSIZE(num));
7698 5102 : memcpy(res, num, VARSIZE(num));
7699 5102 : return res;
991 tgl 7700 ECB : }
7701 :
7324 7702 : /*
7703 : * make_result_opt_error() -
8866 JanWieck 7704 : *
7705 : * Create the packed db numeric format in palloc()'d memory from
991 tgl 7706 : * a variable. This will handle NaN and Infinity cases.
7707 : *
7708 : * If "have_error" isn't NULL, on overflow *have_error is set to true and
7709 : * NULL is returned. This is helpful when caller needs to handle errors.
7710 : */
7711 : static Numeric
1485 akorotkov 7712 GIC 1559439 : make_result_opt_error(const NumericVar *var, bool *have_error)
7713 : {
7714 : Numeric result;
7324 tgl 7715 1559439 : NumericDigit *digits = var->digits;
8720 bruce 7716 1559439 : int weight = var->weight;
7717 1559439 : int sign = var->sign;
7718 : int n;
7719 : Size len;
7720 :
1343 michael 7721 1559439 : if (have_error)
7722 46557 : *have_error = false;
7723 :
991 tgl 7724 1559439 : if ((sign & NUMERIC_SIGN_MASK) == NUMERIC_SPECIAL)
7725 : {
7726 : /*
991 tgl 7727 ECB : * Verify valid special value. This could be just an Assert, perhaps,
7728 : * but it seems worthwhile to expend a few cycles to ensure that we
7729 : * never write any nonzero reserved bits to disk.
7730 : */
991 tgl 7731 CBC 2595 : if (!(sign == NUMERIC_NAN ||
991 tgl 7732 ECB : sign == NUMERIC_PINF ||
7733 : sign == NUMERIC_NINF))
991 tgl 7734 LBC 0 : elog(ERROR, "invalid numeric sign value 0x%x", sign);
991 tgl 7735 ECB :
4632 rhaas 7736 GIC 2595 : result = (Numeric) palloc(NUMERIC_HDRSZ_SHORT);
7737 :
7738 2595 : SET_VARSIZE(result, NUMERIC_HDRSZ_SHORT);
991 tgl 7739 2595 : result->choice.n_header = sign;
7740 : /* the header word is all we need */
7741 :
7742 : dump_numeric("make_result()", result);
8866 JanWieck 7743 2595 : return result;
8866 JanWieck 7744 ECB : }
7745 :
7324 tgl 7746 GIC 1556844 : n = var->ndigits;
7747 :
8485 tgl 7748 ECB : /* truncate leading zeroes */
7324 tgl 7749 CBC 1556856 : while (n > 0 && *digits == 0)
8866 JanWieck 7750 ECB : {
7324 tgl 7751 CBC 12 : digits++;
8866 JanWieck 7752 12 : weight--;
8866 JanWieck 7753 GIC 12 : n--;
8866 JanWieck 7754 ECB : }
7755 : /* truncate trailing zeroes */
7324 tgl 7756 CBC 1599425 : while (n > 0 && digits[n - 1] == 0)
8866 JanWieck 7757 42581 : n--;
8866 JanWieck 7758 ECB :
8485 tgl 7759 : /* If zero result, force to weight=0 and positive sign */
8866 JanWieck 7760 GIC 1556844 : if (n == 0)
7761 : {
7762 46384 : weight = 0;
8720 bruce 7763 46384 : sign = NUMERIC_POS;
7764 : }
7765 :
7766 : /* Build the result */
4632 rhaas 7767 1556844 : if (NUMERIC_CAN_BE_SHORT(var->dscale, weight))
7768 : {
7769 1555977 : len = NUMERIC_HDRSZ_SHORT + n * sizeof(NumericDigit);
4632 rhaas 7770 CBC 1555977 : result = (Numeric) palloc(len);
4632 rhaas 7771 GIC 1555977 : SET_VARSIZE(result, len);
4520 peter_e 7772 1555977 : result->choice.n_short.n_header =
7773 : (sign == NUMERIC_NEG ? (NUMERIC_SHORT | NUMERIC_SHORT_SIGN_MASK)
7774 : : NUMERIC_SHORT)
4632 rhaas 7775 1555977 : | (var->dscale << NUMERIC_SHORT_DSCALE_SHIFT)
7776 1555977 : | (weight < 0 ? NUMERIC_SHORT_WEIGHT_SIGN_MASK : 0)
7777 1555977 : | (weight & NUMERIC_SHORT_WEIGHT_MASK);
7778 : }
7779 : else
7780 : {
7781 867 : len = NUMERIC_HDRSZ + n * sizeof(NumericDigit);
7782 867 : result = (Numeric) palloc(len);
7783 867 : SET_VARSIZE(result, len);
4632 rhaas 7784 CBC 867 : result->choice.n_long.n_sign_dscale =
4632 rhaas 7785 GIC 867 : sign | (var->dscale & NUMERIC_DSCALE_MASK);
7786 867 : result->choice.n_long.n_weight = weight;
7787 : }
7788 :
7789 1556844 : Assert(NUMERIC_NDIGITS(result) == n);
2807 tgl 7790 1556844 : if (n > 0)
7791 1510460 : memcpy(NUMERIC_DIGITS(result), digits, n * sizeof(NumericDigit));
7792 :
7793 : /* Check for overflow of int16 fields */
4632 rhaas 7794 CBC 1556844 : if (NUMERIC_WEIGHT(result) != weight ||
7324 tgl 7795 1556832 : NUMERIC_DSCALE(result) != var->dscale)
1485 akorotkov 7796 ECB : {
1485 akorotkov 7797 GIC 12 : if (have_error)
1485 akorotkov 7798 ECB : {
1485 akorotkov 7799 CBC 9 : *have_error = true;
1485 akorotkov 7800 GIC 9 : return NULL;
7801 : }
7802 : else
7803 : {
1485 akorotkov 7804 CBC 3 : ereport(ERROR,
1485 akorotkov 7805 ECB : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
7806 : errmsg("value overflows numeric format")));
7807 : }
7808 : }
7809 :
8866 JanWieck 7810 : dump_numeric("make_result()", result);
8866 JanWieck 7811 GIC 1556832 : return result;
8866 JanWieck 7812 ECB : }
7813 :
7814 :
7815 : /*
7816 : * make_result() -
1485 akorotkov 7817 : *
7818 : * An interface to make_result_opt_error() without "have_error" argument.
7819 : */
7820 : static Numeric
1485 akorotkov 7821 GIC 1029101 : make_result(const NumericVar *var)
7822 : {
1485 akorotkov 7823 CBC 1029101 : return make_result_opt_error(var, NULL);
7824 : }
1485 akorotkov 7825 ECB :
7826 :
7324 tgl 7827 : /*
8866 JanWieck 7828 : * apply_typmod() -
7829 : *
991 tgl 7830 : * Do bounds checking and rounding according to the specified typmod.
7831 : * Note that this is only applied to normal finite values.
7832 : *
7833 : * Returns true on success, false on failure (if escontext points to an
7834 : * ErrorSaveContext; otherwise errors are thrown).
8866 JanWieck 7835 : */
7836 : static bool
121 tgl 7837 GNC 48764 : apply_typmod(NumericVar *var, int32 typmod, Node *escontext)
8866 JanWieck 7838 ECB : {
7839 : int precision;
7840 : int scale;
7324 tgl 7841 : int maxdigits;
7842 : int ddigits;
8866 JanWieck 7843 : int i;
7844 :
7845 : /* Do nothing if we have an invalid typmod */
622 dean.a.rasheed 7846 GIC 48764 : if (!is_valid_numeric_typmod(typmod))
121 tgl 7847 GNC 46461 : return true;
7848 :
622 dean.a.rasheed 7849 GIC 2303 : precision = numeric_typmod_precision(typmod);
7850 2303 : scale = numeric_typmod_scale(typmod);
7324 tgl 7851 2303 : maxdigits = precision - scale;
7852 :
7853 : /* Round to target scale (and set var->dscale) */
7854 2303 : round_var(var, scale);
7855 :
7856 : /* but don't allow var->dscale to be negative */
622 dean.a.rasheed 7857 2303 : if (var->dscale < 0)
7858 54 : var->dscale = 0;
7859 :
7860 : /*
7861 : * Check for overflow - note we can't do this before rounding, because
7862 : * rounding could raise the weight. Also note that the var's weight could
7863 : * be inflated by leading zeroes, which will be stripped before storage
6385 bruce 7864 ECB : * but perhaps might not have been yet. In any case, we must recognize a
7865 : * true zero, whose weight doesn't mean anything.
8735 JanWieck 7866 : */
7324 tgl 7867 CBC 2303 : ddigits = (var->weight + 1) * DEC_DIGITS;
7868 2303 : if (ddigits > maxdigits)
7869 : {
8485 tgl 7870 ECB : /* Determine true weight; and check for all-zero result */
8485 tgl 7871 GIC 175 : for (i = 0; i < var->ndigits; i++)
8485 tgl 7872 ECB : {
7324 tgl 7873 CBC 168 : NumericDigit dig = var->digits[i];
7324 tgl 7874 ECB :
7324 tgl 7875 CBC 168 : if (dig)
7324 tgl 7876 ECB : {
7877 : /* Adjust for any high-order decimal zero digits */
7878 : #if DEC_DIGITS == 4
7324 tgl 7879 CBC 168 : if (dig < 10)
7880 108 : ddigits -= 3;
7881 60 : else if (dig < 100)
7324 tgl 7882 GIC 30 : ddigits -= 2;
7883 30 : else if (dig < 1000)
7884 21 : ddigits -= 1;
7885 : #elif DEC_DIGITS == 2
7886 : if (dig < 10)
7887 : ddigits -= 1;
7888 : #elif DEC_DIGITS == 1
7889 : /* no adjustment */
7890 : #else
7891 : #error unsupported NBASE
7892 : #endif
7324 tgl 7893 CBC 168 : if (ddigits > maxdigits)
121 tgl 7894 GNC 36 : ereturn(escontext, false,
7895 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
7896 : errmsg("numeric field overflow"),
7897 : errdetail("A field with precision %d, scale %d must round to an absolute value less than %s%d.",
7898 : precision, scale,
6031 bruce 7899 ECB : /* Display 10^0 as 1 */
6283 7900 : maxdigits ? "10^" : "",
7901 : maxdigits ? maxdigits : 1
7902 : )));
8485 tgl 7903 GIC 132 : break;
7904 : }
7324 tgl 7905 UIC 0 : ddigits -= DEC_DIGITS;
7906 : }
7907 : }
7908 :
121 tgl 7909 GNC 2267 : return true;
7910 : }
7911 :
7912 : /*
7913 : * apply_typmod_special() -
7914 : *
7915 : * Do bounds checking according to the specified typmod, for an Inf or NaN.
7916 : * For convenience of most callers, the value is presented in packed form.
7917 : *
7918 : * Returns true on success, false on failure (if escontext points to an
7919 : * ErrorSaveContext; otherwise errors are thrown).
7920 : */
7921 : static bool
7922 796 : apply_typmod_special(Numeric num, int32 typmod, Node *escontext)
7923 : {
7924 : int precision;
7925 : int scale;
7926 :
991 tgl 7927 GIC 796 : Assert(NUMERIC_IS_SPECIAL(num)); /* caller error if not */
7928 :
7929 : /*
7930 : * NaN is allowed regardless of the typmod; that's rather dubious perhaps,
991 tgl 7931 ECB : * but it's a longstanding behavior. Inf is rejected if we have any
7932 : * typmod restriction, since an infinity shouldn't be claimed to fit in
7933 : * any finite number of digits.
7934 : */
991 tgl 7935 GIC 796 : if (NUMERIC_IS_NAN(num))
121 tgl 7936 GNC 367 : return true;
7937 :
7938 : /* Do nothing if we have a default typmod (-1) */
622 dean.a.rasheed 7939 CBC 429 : if (!is_valid_numeric_typmod(typmod))
121 tgl 7940 GNC 420 : return true;
7941 :
622 dean.a.rasheed 7942 GIC 9 : precision = numeric_typmod_precision(typmod);
7943 9 : scale = numeric_typmod_scale(typmod);
7944 :
121 tgl 7945 GNC 9 : ereturn(escontext, false,
7946 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
7947 : errmsg("numeric field overflow"),
991 tgl 7948 ECB : errdetail("A field with precision %d, scale %d cannot hold an infinite value.",
7949 : precision, scale)));
7950 : }
7951 :
7952 :
7953 : /*
7954 : * Convert numeric to int8, rounding if needed.
7955 : *
2062 peter_e 7956 : * If overflow, return false (no error is raised). Return true if okay.
7957 : */
7958 : static bool
2037 andres 7959 GIC 3932 : numericvar_to_int64(const NumericVar *var, int64 *result)
7960 : {
7961 : NumericDigit *digits;
7962 : int ndigits;
7963 : int weight;
7964 : int i;
7965 : int64 val;
7966 : bool neg;
3791 heikki.linnakangas 7967 ECB : NumericVar rounded;
7968 :
7969 : /* Round to nearest integer */
3791 heikki.linnakangas 7970 GIC 3932 : init_var(&rounded);
7971 3932 : set_var_from_var(var, &rounded);
7972 3932 : round_var(&rounded, 0);
7973 :
7324 tgl 7974 ECB : /* Check for zero input */
3791 heikki.linnakangas 7975 GIC 3932 : strip_var(&rounded);
3791 heikki.linnakangas 7976 CBC 3932 : ndigits = rounded.ndigits;
7324 tgl 7977 3932 : if (ndigits == 0)
7324 tgl 7978 ECB : {
7324 tgl 7979 GIC 176 : *result = 0;
3791 heikki.linnakangas 7980 CBC 176 : free_var(&rounded);
7324 tgl 7981 GIC 176 : return true;
7982 : }
7983 :
7984 : /*
7985 : * For input like 10000000000, we must treat stripped digits as real. So
7986 : * the loop assumes there are weight+1 digits before the decimal point.
7987 : */
3791 heikki.linnakangas 7988 3756 : weight = rounded.weight;
7188 bruce 7989 CBC 3756 : Assert(weight >= 0 && ndigits <= weight + 1);
7220 tgl 7990 ECB :
1944 andres 7991 : /*
7992 : * Construct the result. To avoid issues with converting a value
7993 : * corresponding to INT64_MIN (which can't be represented as a positive 64
7994 : * bit two's complement integer), accumulate value as a negative number.
7995 : */
3791 heikki.linnakangas 7996 GIC 3756 : digits = rounded.digits;
7997 3756 : neg = (rounded.sign == NUMERIC_NEG);
1944 andres 7998 3756 : val = -digits[0];
7220 tgl 7999 5336 : for (i = 1; i <= weight; i++)
8000 : {
1944 andres 8001 1595 : if (unlikely(pg_mul_s64_overflow(val, NBASE, &val)))
8002 : {
8003 6 : free_var(&rounded);
8004 6 : return false;
8005 : }
8006 :
8007 1589 : if (i < ndigits)
7324 tgl 8008 ECB : {
1944 andres 8009 GIC 1484 : if (unlikely(pg_sub_s64_overflow(val, digits[i], &val)))
8010 : {
3791 heikki.linnakangas 8011 9 : free_var(&rounded);
7324 tgl 8012 CBC 9 : return false;
3791 heikki.linnakangas 8013 ECB : }
7324 tgl 8014 : }
8015 : }
8016 :
3791 heikki.linnakangas 8017 CBC 3741 : free_var(&rounded);
3791 heikki.linnakangas 8018 ECB :
1944 andres 8019 GIC 3741 : if (!neg)
8020 : {
8021 3438 : if (unlikely(val == PG_INT64_MIN))
8022 12 : return false;
8023 3426 : val = -val;
1944 andres 8024 ECB : }
1944 andres 8025 GIC 3729 : *result = val;
8026 :
7324 tgl 8027 3729 : return true;
8028 : }
8866 JanWieck 8029 ECB :
8030 : /*
7324 tgl 8031 : * Convert int8 value to numeric.
8032 : */
8033 : static void
2942 andres 8034 CBC 922207 : int64_to_numericvar(int64 val, NumericVar *var)
7324 tgl 8035 ECB : {
8036 : uint64 uval,
8037 : newuval;
8038 : NumericDigit *ptr;
8039 : int ndigits;
8040 :
8041 : /* int64 can require at most 19 decimal digits; add one for safety */
7188 bruce 8042 GIC 922207 : alloc_var(var, 20 / DEC_DIGITS);
7324 tgl 8043 922207 : if (val < 0)
8044 : {
8045 733 : var->sign = NUMERIC_NEG;
8046 733 : uval = -val;
7324 tgl 8047 ECB : }
8048 : else
8049 : {
7324 tgl 8050 GIC 921474 : var->sign = NUMERIC_POS;
7324 tgl 8051 CBC 921474 : uval = val;
7324 tgl 8052 ECB : }
7324 tgl 8053 CBC 922207 : var->dscale = 0;
7324 tgl 8054 GIC 922207 : if (val == 0)
8055 : {
8056 17041 : var->ndigits = 0;
8057 17041 : var->weight = 0;
8058 17041 : return;
8059 : }
8060 905166 : ptr = var->digits + var->ndigits;
8061 905166 : ndigits = 0;
8062 : do
8063 : {
8064 1057117 : ptr--;
8065 1057117 : ndigits++;
7324 tgl 8066 CBC 1057117 : newuval = uval / NBASE;
7324 tgl 8067 GIC 1057117 : *ptr = uval - newuval * NBASE;
8068 1057117 : uval = newuval;
7324 tgl 8069 CBC 1057117 : } while (uval);
8070 905166 : var->digits = ptr;
8071 905166 : var->ndigits = ndigits;
7324 tgl 8072 GIC 905166 : var->weight = ndigits - 1;
8073 : }
8074 :
1013 fujii 8075 ECB : /*
8076 : * Convert numeric to uint64, rounding if needed.
8077 : *
8078 : * If overflow, return false (no error is raised). Return true if okay.
8079 : */
8080 : static bool
1013 fujii 8081 GIC 42 : numericvar_to_uint64(const NumericVar *var, uint64 *result)
8082 : {
8083 : NumericDigit *digits;
8084 : int ndigits;
1013 fujii 8085 ECB : int weight;
8086 : int i;
8087 : uint64 val;
1013 fujii 8088 EUB : NumericVar rounded;
8089 :
1013 fujii 8090 ECB : /* Round to nearest integer */
1013 fujii 8091 GIC 42 : init_var(&rounded);
1013 fujii 8092 CBC 42 : set_var_from_var(var, &rounded);
8093 42 : round_var(&rounded, 0);
8094 :
8095 : /* Check for zero input */
1013 fujii 8096 GIC 42 : strip_var(&rounded);
1013 fujii 8097 CBC 42 : ndigits = rounded.ndigits;
1013 fujii 8098 GIC 42 : if (ndigits == 0)
8099 : {
1013 fujii 8100 CBC 9 : *result = 0;
1013 fujii 8101 GIC 9 : free_var(&rounded);
8102 9 : return true;
1013 fujii 8103 ECB : }
8104 :
8105 : /* Check for negative input */
1013 fujii 8106 CBC 33 : if (rounded.sign == NUMERIC_NEG)
1013 fujii 8107 ECB : {
1013 fujii 8108 GIC 6 : free_var(&rounded);
8109 6 : return false;
1013 fujii 8110 ECB : }
8111 :
8112 : /*
8113 : * For input like 10000000000, we must treat stripped digits as real. So
8114 : * the loop assumes there are weight+1 digits before the decimal point.
8115 : */
1013 fujii 8116 CBC 27 : weight = rounded.weight;
8117 27 : Assert(weight >= 0 && ndigits <= weight + 1);
8118 :
8119 : /* Construct the result */
1013 fujii 8120 GIC 27 : digits = rounded.digits;
1013 fujii 8121 CBC 27 : val = digits[0];
1013 fujii 8122 GIC 93 : for (i = 1; i <= weight; i++)
1013 fujii 8123 ECB : {
1013 fujii 8124 CBC 72 : if (unlikely(pg_mul_u64_overflow(val, NBASE, &val)))
1013 fujii 8125 ECB : {
1013 fujii 8126 LBC 0 : free_var(&rounded);
1013 fujii 8127 UIC 0 : return false;
8128 : }
1013 fujii 8129 ECB :
1013 fujii 8130 CBC 72 : if (i < ndigits)
1013 fujii 8131 ECB : {
1013 fujii 8132 GIC 72 : if (unlikely(pg_add_u64_overflow(val, digits[i], &val)))
8133 : {
8134 6 : free_var(&rounded);
1013 fujii 8135 CBC 6 : return false;
1013 fujii 8136 ECB : }
8137 : }
8138 : }
8139 :
1013 fujii 8140 CBC 21 : free_var(&rounded);
8141 :
1013 fujii 8142 GIC 21 : *result = val;
1013 fujii 8143 ECB :
1013 fujii 8144 CBC 21 : return true;
1013 fujii 8145 ECB : }
8146 :
8147 : #ifdef HAVE_INT128
2560 rhaas 8148 : /*
8149 : * Convert numeric to int128, rounding if needed.
8150 : *
2062 peter_e 8151 : * If overflow, return false (no error is raised). Return true if okay.
8152 : */
2560 rhaas 8153 : static bool
2037 andres 8154 CBC 27 : numericvar_to_int128(const NumericVar *var, int128 *result)
8155 : {
8156 : NumericDigit *digits;
8157 : int ndigits;
2560 rhaas 8158 ECB : int weight;
8159 : int i;
8160 : int128 val,
8161 : oldval;
8162 : bool neg;
8163 : NumericVar rounded;
8164 :
8165 : /* Round to nearest integer */
2560 rhaas 8166 GIC 27 : init_var(&rounded);
8167 27 : set_var_from_var(var, &rounded);
8168 27 : round_var(&rounded, 0);
8169 :
8170 : /* Check for zero input */
8171 27 : strip_var(&rounded);
8172 27 : ndigits = rounded.ndigits;
8173 27 : if (ndigits == 0)
8174 : {
2560 rhaas 8175 LBC 0 : *result = 0;
2560 rhaas 8176 UIC 0 : free_var(&rounded);
2560 rhaas 8177 LBC 0 : return true;
8178 : }
8179 :
8180 : /*
8181 : * For input like 10000000000, we must treat stripped digits as real. So
8182 : * the loop assumes there are weight+1 digits before the decimal point.
8183 : */
2560 rhaas 8184 GIC 27 : weight = rounded.weight;
8185 27 : Assert(weight >= 0 && ndigits <= weight + 1);
8186 :
8187 : /* Construct the result */
8188 27 : digits = rounded.digits;
8189 27 : neg = (rounded.sign == NUMERIC_NEG);
8190 27 : val = digits[0];
2560 rhaas 8191 CBC 65 : for (i = 1; i <= weight; i++)
8192 : {
2560 rhaas 8193 GIC 38 : oldval = val;
8194 38 : val *= NBASE;
8195 38 : if (i < ndigits)
8196 35 : val += digits[i];
8197 :
8198 : /*
8199 : * The overflow check is a bit tricky because we want to accept
2560 rhaas 8200 ECB : * INT128_MIN, which will overflow the positive accumulator. We can
8201 : * detect this case easily though because INT128_MIN is the only
8202 : * nonzero value for which -val == val (on a two's complement machine,
8203 : * anyway).
8204 : */
2560 rhaas 8205 CBC 38 : if ((val / NBASE) != oldval) /* possible overflow? */
8206 : {
2560 rhaas 8207 UIC 0 : if (!neg || (-val) != val || val == 0 || oldval < 0)
2560 rhaas 8208 ECB : {
2560 rhaas 8209 UIC 0 : free_var(&rounded);
8210 0 : return false;
2560 rhaas 8211 ECB : }
8212 : }
8213 : }
8214 :
2560 rhaas 8215 GIC 27 : free_var(&rounded);
8216 :
8217 27 : *result = neg ? -val : val;
8218 27 : return true;
8219 : }
8220 :
2942 andres 8221 ECB : /*
8222 : * Convert 128 bit integer to numeric.
8223 : */
8224 : static void
2942 andres 8225 CBC 4270 : int128_to_numericvar(int128 val, NumericVar *var)
8226 : {
2878 bruce 8227 ECB : uint128 uval,
8228 : newuval;
8229 : NumericDigit *ptr;
8230 : int ndigits;
8231 :
8232 : /* int128 can require at most 39 decimal digits; add one for safety */
2942 andres 8233 CBC 4270 : alloc_var(var, 40 / DEC_DIGITS);
8234 4270 : if (val < 0)
2942 andres 8235 ECB : {
2942 andres 8236 LBC 0 : var->sign = NUMERIC_NEG;
8237 0 : uval = -val;
2942 andres 8238 ECB : }
8239 : else
8240 : {
2942 andres 8241 GIC 4270 : var->sign = NUMERIC_POS;
8242 4270 : uval = val;
8243 : }
8244 4270 : var->dscale = 0;
8245 4270 : if (val == 0)
8246 : {
2942 andres 8247 CBC 55 : var->ndigits = 0;
8248 55 : var->weight = 0;
2942 andres 8249 GIC 55 : return;
8250 : }
8251 4215 : ptr = var->digits + var->ndigits;
8252 4215 : ndigits = 0;
8253 : do
8254 : {
8255 22460 : ptr--;
8256 22460 : ndigits++;
2942 andres 8257 CBC 22460 : newuval = uval / NBASE;
2942 andres 8258 GIC 22460 : *ptr = uval - newuval * NBASE;
2942 andres 8259 GBC 22460 : uval = newuval;
2942 andres 8260 GIC 22460 : } while (uval);
8261 4215 : var->digits = ptr;
8262 4215 : var->ndigits = ndigits;
2942 andres 8263 CBC 4215 : var->weight = ndigits - 1;
8264 : }
8265 : #endif
8266 :
8267 : /*
8268 : * Convert a NumericVar to float8; if out of range, return +/- HUGE_VAL
8269 : */
8270 : static double
2037 andres 8271 GIC 1616 : numericvar_to_double_no_overflow(const NumericVar *var)
8272 : {
8273 : char *tmp;
8274 : double val;
8275 : char *endptr;
7494 tgl 8276 ECB :
3791 heikki.linnakangas 8277 GIC 1616 : tmp = get_str_from_var(var);
8278 :
8279 : /* unlike float8in, we ignore ERANGE from strtod */
7494 tgl 8280 1616 : val = strtod(tmp, &endptr);
7494 tgl 8281 CBC 1616 : if (*endptr != '\0')
8282 : {
8283 : /* shouldn't happen ... */
7196 tgl 8284 UIC 0 : ereport(ERROR,
8285 : (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
8286 : errmsg("invalid input syntax for type %s: \"%s\"",
8287 : "double precision", tmp)));
8288 : }
7494 tgl 8289 ECB :
7494 tgl 8290 CBC 1616 : pfree(tmp);
8291 :
7494 tgl 8292 GIC 1616 : return val;
7494 tgl 8293 ECB : }
8294 :
8295 :
7324 8296 : /*
8866 JanWieck 8297 : * cmp_var() -
8298 : *
7324 tgl 8299 : * Compare two values on variable level. We assume zeroes have been
8300 : * truncated to no digits.
8301 : */
8302 : static int
2037 andres 8303 GIC 8383 : cmp_var(const NumericVar *var1, const NumericVar *var2)
8304 : {
6270 bruce 8305 16766 : return cmp_var_common(var1->digits, var1->ndigits,
8306 8383 : var1->weight, var1->sign,
8307 8383 : var2->digits, var2->ndigits,
8308 8383 : var2->weight, var2->sign);
8309 : }
8310 :
8311 : /*
8312 : * cmp_var_common() -
6270 bruce 8313 ECB : *
8314 : * Main routine of cmp_var(). This function can be used by both
8315 : * NumericVar and Numeric.
8316 : */
8317 : static int
6270 bruce 8318 GIC 3222052 : cmp_var_common(const NumericDigit *var1digits, int var1ndigits,
8319 : int var1weight, int var1sign,
8320 : const NumericDigit *var2digits, int var2ndigits,
8321 : int var2weight, int var2sign)
8322 : {
8323 3222052 : if (var1ndigits == 0)
8866 JanWieck 8324 ECB : {
6270 bruce 8325 CBC 97023 : if (var2ndigits == 0)
8866 JanWieck 8326 82991 : return 0;
6270 bruce 8327 GIC 14032 : if (var2sign == NUMERIC_NEG)
8866 JanWieck 8328 2131 : return 1;
8866 JanWieck 8329 CBC 11901 : return -1;
8866 JanWieck 8330 ECB : }
6270 bruce 8331 CBC 3125029 : if (var2ndigits == 0)
8332 : {
8333 15929 : if (var1sign == NUMERIC_POS)
8866 JanWieck 8334 12455 : return 1;
8335 3474 : return -1;
8336 : }
8337 :
6270 bruce 8338 GIC 3109100 : if (var1sign == NUMERIC_POS)
8339 : {
8340 3082035 : if (var2sign == NUMERIC_NEG)
8866 JanWieck 8341 5575 : return 1;
6270 bruce 8342 CBC 3076460 : return cmp_abs_common(var1digits, var1ndigits, var1weight,
6270 bruce 8343 ECB : var2digits, var2ndigits, var2weight);
8344 : }
8345 :
6270 bruce 8346 GIC 27065 : if (var2sign == NUMERIC_POS)
8866 JanWieck 8347 6281 : return -1;
8348 :
6270 bruce 8349 20784 : return cmp_abs_common(var2digits, var2ndigits, var2weight,
6270 bruce 8350 ECB : var1digits, var1ndigits, var1weight);
8866 JanWieck 8351 : }
8352 :
8353 :
8354 : /*
8355 : * add_var() -
8356 : *
8357 : * Full version of add functionality on variable level (handling signs).
8358 : * result might point to one of the operands too without danger.
8359 : */
8360 : static void
2037 andres 8361 CBC 231922 : add_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
8362 : {
8053 bruce 8363 ECB : /*
8364 : * Decide on the signs of the two variables what to do
8866 JanWieck 8365 : */
8866 JanWieck 8366 CBC 231922 : if (var1->sign == NUMERIC_POS)
8367 : {
8866 JanWieck 8368 GIC 231139 : if (var2->sign == NUMERIC_POS)
8369 : {
8370 : /*
8053 bruce 8371 ECB : * Both are positive result = +(ABS(var1) + ABS(var2))
8372 : */
8866 JanWieck 8373 CBC 144592 : add_abs(var1, var2, result);
8866 JanWieck 8374 GIC 144592 : result->sign = NUMERIC_POS;
8866 JanWieck 8375 ECB : }
8376 : else
8377 : {
8378 : /*
6385 bruce 8379 : * var1 is positive, var2 is negative Must compare absolute values
8380 : */
8866 JanWieck 8381 CBC 86547 : switch (cmp_abs(var1, var2))
8382 : {
8301 tgl 8383 GIC 16 : case 0:
8384 : /* ----------
8385 : * ABS(var1) == ABS(var2)
8386 : * result = ZERO
8387 : * ----------
8301 tgl 8388 ECB : */
8482 tgl 8389 GIC 16 : zero_var(result);
7720 bruce 8390 16 : result->dscale = Max(var1->dscale, var2->dscale);
8720 8391 16 : break;
8392 :
8301 tgl 8393 86387 : case 1:
8394 : /* ----------
8395 : * ABS(var1) > ABS(var2)
8301 tgl 8396 ECB : * result = +(ABS(var1) - ABS(var2))
8397 : * ----------
8398 : */
8720 bruce 8399 CBC 86387 : sub_abs(var1, var2, result);
8400 86387 : result->sign = NUMERIC_POS;
8720 bruce 8401 GIC 86387 : break;
8402 :
8301 tgl 8403 144 : case -1:
8301 tgl 8404 ECB : /* ----------
8405 : * ABS(var1) < ABS(var2)
8406 : * result = -(ABS(var2) - ABS(var1))
8407 : * ----------
8408 : */
8720 bruce 8409 GIC 144 : sub_abs(var2, var1, result);
8720 bruce 8410 CBC 144 : result->sign = NUMERIC_NEG;
8411 144 : break;
8866 JanWieck 8412 ECB : }
8413 : }
8414 : }
8415 : else
8416 : {
8866 JanWieck 8417 GIC 783 : if (var2->sign == NUMERIC_POS)
8866 JanWieck 8418 ECB : {
8419 : /* ----------
8420 : * var1 is negative, var2 is positive
8421 : * Must compare absolute values
8422 : * ----------
8423 : */
8866 JanWieck 8424 CBC 234 : switch (cmp_abs(var1, var2))
8866 JanWieck 8425 ECB : {
8301 tgl 8426 CBC 15 : case 0:
8427 : /* ----------
8428 : * ABS(var1) == ABS(var2)
8429 : * result = ZERO
8430 : * ----------
8431 : */
8482 tgl 8432 GIC 15 : zero_var(result);
7720 bruce 8433 15 : result->dscale = Max(var1->dscale, var2->dscale);
8720 8434 15 : break;
8720 bruce 8435 ECB :
8301 tgl 8436 GIC 147 : case 1:
8437 : /* ----------
8438 : * ABS(var1) > ABS(var2)
8439 : * result = -(ABS(var1) - ABS(var2))
8440 : * ----------
8441 : */
8720 bruce 8442 147 : sub_abs(var1, var2, result);
8443 147 : result->sign = NUMERIC_NEG;
8444 147 : break;
8720 bruce 8445 ECB :
8301 tgl 8446 CBC 72 : case -1:
8301 tgl 8447 ECB : /* ----------
8448 : * ABS(var1) < ABS(var2)
8449 : * result = +(ABS(var2) - ABS(var1))
8450 : * ----------
8451 : */
8720 bruce 8452 CBC 72 : sub_abs(var2, var1, result);
8720 bruce 8453 GIC 72 : result->sign = NUMERIC_POS;
8720 bruce 8454 CBC 72 : break;
8866 JanWieck 8455 ECB : }
8456 : }
8457 : else
8458 : {
8459 : /* ----------
8460 : * Both are negative
8461 : * result = -(ABS(var1) + ABS(var2))
8462 : * ----------
8463 : */
8866 JanWieck 8464 GIC 549 : add_abs(var1, var2, result);
8465 549 : result->sign = NUMERIC_NEG;
8466 : }
8467 : }
8468 231922 : }
8469 :
8866 JanWieck 8470 ECB :
7324 tgl 8471 : /*
8472 : * sub_var() -
8473 : *
8866 JanWieck 8474 : * Full version of sub functionality on variable level (handling signs).
8475 : * result might point to one of the operands too without danger.
8476 : */
8477 : static void
2037 andres 8478 CBC 57346 : sub_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
8479 : {
8053 bruce 8480 EUB : /*
8866 JanWieck 8481 : * Decide on the signs of the two variables what to do
8482 : */
8866 JanWieck 8483 GIC 57346 : if (var1->sign == NUMERIC_POS)
8866 JanWieck 8484 ECB : {
8866 JanWieck 8485 GIC 55961 : if (var2->sign == NUMERIC_NEG)
8866 JanWieck 8486 ECB : {
8487 : /* ----------
8488 : * var1 is positive, var2 is negative
8489 : * result = +(ABS(var1) + ABS(var2))
8490 : * ----------
8491 : */
8866 JanWieck 8492 GIC 3026 : add_abs(var1, var2, result);
8493 3026 : result->sign = NUMERIC_POS;
8866 JanWieck 8494 ECB : }
8495 : else
8496 : {
8497 : /* ----------
8498 : * Both are positive
8499 : * Must compare absolute values
8500 : * ----------
8501 : */
8866 JanWieck 8502 GIC 52935 : switch (cmp_abs(var1, var2))
8503 : {
8301 tgl 8504 14959 : case 0:
8505 : /* ----------
8506 : * ABS(var1) == ABS(var2)
8507 : * result = ZERO
8301 tgl 8508 ECB : * ----------
8509 : */
8482 tgl 8510 GIC 14959 : zero_var(result);
7720 bruce 8511 14959 : result->dscale = Max(var1->dscale, var2->dscale);
8720 8512 14959 : break;
8513 :
8301 tgl 8514 37713 : case 1:
8515 : /* ----------
8516 : * ABS(var1) > ABS(var2)
8517 : * result = +(ABS(var1) - ABS(var2))
8518 : * ----------
8519 : */
8720 bruce 8520 CBC 37713 : sub_abs(var1, var2, result);
8521 37713 : result->sign = NUMERIC_POS;
8522 37713 : break;
8523 :
8301 tgl 8524 GIC 263 : case -1:
8301 tgl 8525 ECB : /* ----------
8526 : * ABS(var1) < ABS(var2)
8527 : * result = -(ABS(var2) - ABS(var1))
8528 : * ----------
8301 tgl 8529 EUB : */
8720 bruce 8530 GBC 263 : sub_abs(var2, var1, result);
8531 263 : result->sign = NUMERIC_NEG;
8720 bruce 8532 GIC 263 : break;
8533 : }
8534 : }
8535 : }
8536 : else
8537 : {
8866 JanWieck 8538 CBC 1385 : if (var2->sign == NUMERIC_NEG)
8866 JanWieck 8539 ECB : {
8540 : /* ----------
8541 : * Both are negative
8542 : * Must compare absolute values
8543 : * ----------
8544 : */
8866 JanWieck 8545 CBC 1160 : switch (cmp_abs(var1, var2))
8546 : {
8301 tgl 8547 83 : case 0:
8301 tgl 8548 ECB : /* ----------
8549 : * ABS(var1) == ABS(var2)
8550 : * result = ZERO
8551 : * ----------
8552 : */
8482 tgl 8553 GIC 83 : zero_var(result);
7720 bruce 8554 83 : result->dscale = Max(var1->dscale, var2->dscale);
8720 8555 83 : break;
8556 :
8301 tgl 8557 117 : case 1:
8558 : /* ----------
8301 tgl 8559 ECB : * ABS(var1) > ABS(var2)
8560 : * result = -(ABS(var1) - ABS(var2))
8301 tgl 8561 EUB : * ----------
8562 : */
8720 bruce 8563 GBC 117 : sub_abs(var1, var2, result);
8564 117 : result->sign = NUMERIC_NEG;
8720 bruce 8565 GIC 117 : break;
8566 :
8301 tgl 8567 960 : case -1:
8568 : /* ----------
8301 tgl 8569 ECB : * ABS(var1) < ABS(var2)
8570 : * result = +(ABS(var2) - ABS(var1))
8571 : * ----------
8572 : */
8720 bruce 8573 GIC 960 : sub_abs(var2, var1, result);
8574 960 : result->sign = NUMERIC_POS;
8575 960 : break;
8576 : }
8577 : }
8578 : else
8866 JanWieck 8579 ECB : {
8580 : /* ----------
8581 : * var1 is negative, var2 is positive
8582 : * result = -(ABS(var1) + ABS(var2))
8583 : * ----------
8584 : */
8866 JanWieck 8585 GIC 225 : add_abs(var1, var2, result);
8586 225 : result->sign = NUMERIC_NEG;
8866 JanWieck 8587 ECB : }
8588 : }
8866 JanWieck 8589 GIC 57346 : }
8866 JanWieck 8590 EUB :
8591 :
8592 : /*
8593 : * mul_var() -
8594 : *
8866 JanWieck 8595 ECB : * Multiplication on variable level. Product of var1 * var2 is stored
3260 bruce 8596 : * in result. Result is rounded to no more than rscale fractional digits.
8597 : */
8866 JanWieck 8598 : static void
2037 andres 8599 CBC 413936 : mul_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result,
8600 : int rscale)
8866 JanWieck 8601 ECB : {
8720 bruce 8602 : int res_ndigits;
8603 : int res_sign;
8604 : int res_weight;
7324 tgl 8605 : int maxdigits;
8606 : int *dig;
8607 : int carry;
8608 : int maxdig;
8609 : int newdig;
2703 8610 : int var1ndigits;
8611 : int var2ndigits;
8612 : NumericDigit *var1digits;
8613 : NumericDigit *var2digits;
7324 8614 : NumericDigit *res_digits;
8720 bruce 8615 : int i,
8616 : i1,
8617 : i2;
8618 :
8619 : /*
8620 : * Arrange for var1 to be the shorter of the two numbers. This improves
8621 : * performance because the inner multiplication loop is much simpler than
8622 : * the outer loop, so it's better to have a smaller number of iterations
8623 : * of the outer loop. This also reduces the number of times that the
8624 : * accumulator array needs to be normalized.
2703 tgl 8625 : */
2703 tgl 8626 GIC 413936 : if (var1->ndigits > var2->ndigits)
8627 : {
2037 andres 8628 6599 : const NumericVar *tmp = var1;
8629 :
2703 tgl 8630 6599 : var1 = var2;
2703 tgl 8631 CBC 6599 : var2 = tmp;
8632 : }
8633 :
7324 tgl 8634 ECB : /* copy these values into local vars for speed in inner loop */
2703 tgl 8635 CBC 413936 : var1ndigits = var1->ndigits;
2703 tgl 8636 GIC 413936 : var2ndigits = var2->ndigits;
8637 413936 : var1digits = var1->digits;
2703 tgl 8638 GBC 413936 : var2digits = var2->digits;
8639 :
7324 tgl 8640 GIC 413936 : if (var1ndigits == 0 || var2ndigits == 0)
8641 : {
8642 : /* one or both inputs is zero; so is result */
8643 856 : zero_var(result);
7324 tgl 8644 CBC 856 : result->dscale = rscale;
7324 tgl 8645 GIC 856 : return;
7324 tgl 8646 ECB : }
8647 :
8648 : /* Determine result sign and (maximum possible) weight */
8866 JanWieck 8649 GIC 413080 : if (var1->sign == var2->sign)
8650 411815 : res_sign = NUMERIC_POS;
8651 : else
8652 1265 : res_sign = NUMERIC_NEG;
7324 tgl 8653 413080 : res_weight = var1->weight + var2->weight + 2;
8654 :
8655 : /*
8656 : * Determine the number of result digits to compute. If the exact result
6385 bruce 8657 ECB : * would have more than rscale fractional digits, truncate the computation
8658 : * with MUL_GUARD_DIGITS guard digits, i.e., ignore input digits that
2703 tgl 8659 : * would only contribute to the right of that. (This will give the exact
8660 : * rounded-to-rscale answer unless carries out of the ignored positions
8661 : * would have propagated through more than MUL_GUARD_DIGITS digits.)
8662 : *
8663 : * Note: an exact computation could not produce more than var1ndigits +
8664 : * var2ndigits digits, but we allocate one extra output digit in case
8665 : * rscale-driven rounding produces a carry out of the highest exact digit.
8666 : */
7324 tgl 8667 GIC 413080 : res_ndigits = var1ndigits + var2ndigits + 1;
2703 8668 413080 : maxdigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS +
8669 : MUL_GUARD_DIGITS;
8670 413080 : res_ndigits = Min(res_ndigits, maxdigits);
8671 :
2703 tgl 8672 CBC 413080 : if (res_ndigits < 3)
8673 : {
8674 : /* All input digits will be ignored; so result is zero */
2703 tgl 8675 GIC 6 : zero_var(result);
8676 6 : result->dscale = rscale;
2703 tgl 8677 CBC 6 : return;
8678 : }
8866 JanWieck 8679 ECB :
7324 tgl 8680 : /*
8681 : * We do the arithmetic in an array "dig[]" of signed int's. Since
6385 bruce 8682 : * INT_MAX is noticeably larger than NBASE*NBASE, this gives us headroom
8683 : * to avoid normalizing carries immediately.
8684 : *
7188 8685 : * maxdig tracks the maximum possible value of any dig[] entry; when this
8686 : * threatens to exceed INT_MAX, we take the time to propagate carries.
2757 tgl 8687 : * Furthermore, we need to ensure that overflow doesn't occur during the
8688 : * carry propagation passes either. The carry values could be as much as
8689 : * INT_MAX/NBASE, so really we must normalize when digits threaten to
8690 : * exceed INT_MAX - INT_MAX/NBASE.
8691 : *
8692 : * To avoid overflow in maxdig itself, it actually represents the max
8693 : * possible value divided by NBASE-1, ie, at the top of the loop it is
8694 : * known that no dig[] entry exceeds maxdig * (NBASE-1).
7324 8695 : */
7324 tgl 8696 CBC 413074 : dig = (int *) palloc0(res_ndigits * sizeof(int));
7324 tgl 8697 GIC 413074 : maxdig = 0;
8698 :
8699 : /*
2703 tgl 8700 ECB : * The least significant digits of var1 should be ignored if they don't
8701 : * contribute directly to the first res_ndigits digits of the result that
8702 : * we are computing.
8703 : *
8704 : * Digit i1 of var1 and digit i2 of var2 are multiplied and added to digit
8705 : * i1+i2+2 of the accumulator array, so we need only consider digits of
8706 : * var1 for which i1 <= res_ndigits - 3.
8707 : */
2703 tgl 8708 GIC 2314082 : for (i1 = Min(var1ndigits - 1, res_ndigits - 3); i1 >= 0; i1--)
8709 : {
406 dean.a.rasheed 8710 1901008 : NumericDigit var1digit = var1digits[i1];
8711 :
7324 tgl 8712 1901008 : if (var1digit == 0)
8713 1179720 : continue;
8714 :
7324 tgl 8715 ECB : /* Time to normalize? */
7324 tgl 8716 GIC 721288 : maxdig += var1digit;
2757 8717 721288 : if (maxdig > (INT_MAX - INT_MAX / NBASE) / (NBASE - 1))
8718 : {
8719 : /* Yes, do it */
7324 tgl 8720 CBC 4572 : carry = 0;
7188 bruce 8721 GIC 22905348 : for (i = res_ndigits - 1; i >= 0; i--)
7324 tgl 8722 ECB : {
7324 tgl 8723 GIC 22900776 : newdig = dig[i] + carry;
8724 22900776 : if (newdig >= NBASE)
8725 : {
7188 bruce 8726 11532801 : carry = newdig / NBASE;
7188 bruce 8727 CBC 11532801 : newdig -= carry * NBASE;
7324 tgl 8728 ECB : }
8729 : else
7324 tgl 8730 GIC 11367975 : carry = 0;
8731 22900776 : dig[i] = newdig;
8732 : }
8733 4572 : Assert(carry == 0);
8734 : /* Reset maxdig to indicate new worst-case */
7324 tgl 8735 CBC 4572 : maxdig = 1 + var1digit;
8736 : }
7324 tgl 8737 ECB :
8738 : /*
8739 : * Add the appropriate multiple of var2 into the accumulator.
8740 : *
8741 : * As above, digits of var2 can be ignored if they don't contribute,
8742 : * so we only include digits for which i1+i2+2 < res_ndigits.
945 8743 : *
8744 : * This inner loop is the performance bottleneck for multiplication,
8745 : * so we want to keep it simple enough so that it can be
8746 : * auto-vectorized. Accordingly, process the digits left-to-right
8747 : * even though schoolbook multiplication would suggest right-to-left.
8748 : * Since we aren't propagating carries in this loop, the order does
8749 : * not matter.
8750 : */
8751 : {
944 tgl 8752 GIC 721288 : int i2limit = Min(var2ndigits, res_ndigits - i1 - 2);
944 tgl 8753 CBC 721288 : int *dig_i1_2 = &dig[i1 + 2];
944 tgl 8754 ECB :
944 tgl 8755 CBC 249555590 : for (i2 = 0; i2 < i2limit; i2++)
944 tgl 8756 GIC 248834302 : dig_i1_2[i2] += var1digit * var2digits[i2];
944 tgl 8757 ECB : }
8758 : }
8759 :
8760 : /*
8761 : * Now we do a final carry propagation pass to normalize the result, which
8762 : * we combine with storing the result digits into the output. Note that
6385 bruce 8763 : * this is still done at full precision w/guard digits.
7324 tgl 8764 : */
7324 tgl 8765 CBC 413074 : alloc_var(result, res_ndigits);
7324 tgl 8766 GIC 413074 : res_digits = result->digits;
8767 413074 : carry = 0;
7188 bruce 8768 5114614 : for (i = res_ndigits - 1; i >= 0; i--)
8769 : {
7324 tgl 8770 4701540 : newdig = dig[i] + carry;
7324 tgl 8771 CBC 4701540 : if (newdig >= NBASE)
8772 : {
7188 bruce 8773 GIC 991510 : carry = newdig / NBASE;
8774 991510 : newdig -= carry * NBASE;
8775 : }
8776 : else
7324 tgl 8777 3710030 : carry = 0;
7324 tgl 8778 CBC 4701540 : res_digits[i] = newdig;
8779 : }
8780 413074 : Assert(carry == 0);
8781 :
7324 tgl 8782 GIC 413074 : pfree(dig);
8783 :
8784 : /*
8785 : * Finally, round the result to the requested precision.
7324 tgl 8786 ECB : */
8720 bruce 8787 CBC 413074 : result->weight = res_weight;
8788 413074 : result->sign = res_sign;
8789 :
7324 tgl 8790 ECB : /* Round to target rscale (and set result->dscale) */
7324 tgl 8791 GIC 413074 : round_var(result, rscale);
8792 :
8793 : /* Strip leading and trailing zeroes */
8794 413074 : strip_var(result);
8795 : }
8866 JanWieck 8796 ECB :
8797 :
7324 tgl 8798 : /*
8799 : * div_var() -
8866 JanWieck 8800 : *
8801 : * Division on variable level. Quotient of var1 / var2 is stored in result.
8802 : * The quotient is figured to exactly rscale fractional digits.
8803 : * If round is true, it is rounded at the rscale'th digit; if false, it
8804 : * is truncated (towards zero) at that digit.
8805 : */
8806 : static void
2037 andres 8807 CBC 88565 : div_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result,
6518 bruce 8808 ECB : int rscale, bool round)
8809 : {
8810 : int div_ndigits;
8811 : int res_ndigits;
8812 : int res_sign;
8813 : int res_weight;
8814 : int carry;
8815 : int borrow;
8816 : int divisor1;
8817 : int divisor2;
5483 tgl 8818 : NumericDigit *dividend;
8819 : NumericDigit *divisor;
8820 : NumericDigit *res_digits;
8821 : int i;
8822 : int j;
8823 :
8824 : /* copy these values into local vars for speed in inner loop */
5483 tgl 8825 GIC 88565 : int var1ndigits = var1->ndigits;
8826 88565 : int var2ndigits = var2->ndigits;
8827 :
8828 : /*
8829 : * First of all division by zero check; we must not be handed an
8830 : * unnormalized divisor.
8831 : */
5483 tgl 8832 CBC 88565 : if (var2ndigits == 0 || var2->digits[0] == 0)
5483 tgl 8833 GIC 28 : ereport(ERROR,
8834 : (errcode(ERRCODE_DIVISION_BY_ZERO),
8835 : errmsg("division by zero")));
8836 :
5483 tgl 8837 ECB : /*
8838 : * If the divisor has just one or two digits, delegate to div_var_int(),
406 dean.a.rasheed 8839 : * which uses fast short division.
8840 : *
8841 : * Similarly, on platforms with 128-bit integer support, delegate to
8842 : * div_var_int64() for divisors with three or four digits.
8843 : */
406 dean.a.rasheed 8844 GIC 88537 : if (var2ndigits <= 2)
8845 : {
8846 : int idivisor;
8847 : int idivisor_weight;
8848 :
406 dean.a.rasheed 8849 CBC 86823 : idivisor = var2->digits[0];
8850 86823 : idivisor_weight = var2->weight;
406 dean.a.rasheed 8851 GIC 86823 : if (var2ndigits == 2)
8852 : {
8853 1545 : idivisor = idivisor * NBASE + var2->digits[1];
8854 1545 : idivisor_weight--;
8855 : }
8856 86823 : if (var2->sign == NUMERIC_NEG)
8857 243 : idivisor = -idivisor;
8858 :
406 dean.a.rasheed 8859 CBC 86823 : div_var_int(var1, idivisor, idivisor_weight, result, rscale, round);
406 dean.a.rasheed 8860 GIC 86823 : return;
406 dean.a.rasheed 8861 ECB : }
8862 : #ifdef HAVE_INT128
76 dean.a.rasheed 8863 GNC 1714 : if (var2ndigits <= 4)
8864 : {
8865 : int64 idivisor;
8866 : int idivisor_weight;
8867 :
8868 243 : idivisor = var2->digits[0];
8869 243 : idivisor_weight = var2->weight;
8870 912 : for (i = 1; i < var2ndigits; i++)
8871 : {
8872 669 : idivisor = idivisor * NBASE + var2->digits[i];
8873 669 : idivisor_weight--;
8874 : }
8875 243 : if (var2->sign == NUMERIC_NEG)
8876 60 : idivisor = -idivisor;
8877 :
8878 243 : div_var_int64(var1, idivisor, idivisor_weight, result, rscale, round);
8879 243 : return;
8880 : }
8881 : #endif
8882 :
8883 : /*
8884 : * Otherwise, perform full long division.
8885 : */
8886 :
406 dean.a.rasheed 8887 ECB : /* Result zero check */
5483 tgl 8888 CBC 1471 : if (var1ndigits == 0)
5483 tgl 8889 ECB : {
5483 tgl 8890 GIC 12 : zero_var(result);
5483 tgl 8891 CBC 12 : result->dscale = rscale;
5483 tgl 8892 GIC 12 : return;
8893 : }
8894 :
8895 : /*
8896 : * Determine the result sign, weight and number of digits to calculate.
5483 tgl 8897 ECB : * The weight figured here is correct if the emitted quotient has no
8898 : * leading zero digits; otherwise strip_var() will fix things up.
8899 : */
5483 tgl 8900 GIC 1459 : if (var1->sign == var2->sign)
5483 tgl 8901 CBC 1429 : res_sign = NUMERIC_POS;
8902 : else
5483 tgl 8903 GIC 30 : res_sign = NUMERIC_NEG;
8904 1459 : res_weight = var1->weight - var2->weight;
8905 : /* The number of accurate result digits we need to produce: */
8906 1459 : res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
5483 tgl 8907 ECB : /* ... but always at least 1 */
5483 tgl 8908 CBC 1459 : res_ndigits = Max(res_ndigits, 1);
5483 tgl 8909 ECB : /* If rounding needed, figure one more digit to ensure correct result */
5483 tgl 8910 GIC 1459 : if (round)
8911 1459 : res_ndigits++;
8912 :
8913 : /*
8914 : * The working dividend normally requires res_ndigits + var2ndigits
5483 tgl 8915 ECB : * digits, but make it at least var1ndigits so we can load all of var1
8916 : * into it. (There will be an additional digit dividend[0] in the
8917 : * dividend space, but for consistency with Knuth's notation we don't
8918 : * count that in div_ndigits.)
8919 : */
5483 tgl 8920 GIC 1459 : div_ndigits = res_ndigits + var2ndigits;
8921 1459 : div_ndigits = Max(div_ndigits, var1ndigits);
5483 tgl 8922 ECB :
8923 : /*
8924 : * We need a workspace with room for the working dividend (div_ndigits+1
8925 : * digits) plus room for the possibly-normalized divisor (var2ndigits
8926 : * digits). It is convenient also to have a zero at divisor[0] with the
8927 : * actual divisor data in divisor[1 .. var2ndigits]. Transferring the
8928 : * digits into the workspace also allows us to realloc the result (which
8929 : * might be the same as either input var) before we begin the main loop.
8930 : * Note that we use palloc0 to ensure that divisor[0], dividend[0], and
8931 : * any additional dividend positions beyond var1ndigits, start out 0.
8932 : */
8933 : dividend = (NumericDigit *)
5483 tgl 8934 CBC 1459 : palloc0((div_ndigits + var2ndigits + 2) * sizeof(NumericDigit));
5483 tgl 8935 GIC 1459 : divisor = dividend + (div_ndigits + 1);
8936 1459 : memcpy(dividend + 1, var1->digits, var1ndigits * sizeof(NumericDigit));
8937 1459 : memcpy(divisor + 1, var2->digits, var2ndigits * sizeof(NumericDigit));
8938 :
8939 : /*
5483 tgl 8940 ECB : * Now we can realloc the result to hold the generated quotient digits.
8941 : */
5483 tgl 8942 CBC 1459 : alloc_var(result, res_ndigits);
5483 tgl 8943 GIC 1459 : res_digits = result->digits;
5483 tgl 8944 ECB :
8945 : /*
8946 : * The full multiple-place algorithm is taken from Knuth volume 2,
8947 : * Algorithm 4.3.1D.
8948 : *
8949 : * We need the first divisor digit to be >= NBASE/2. If it isn't, make it
332 8950 : * so by scaling up both the divisor and dividend by the factor "d". (The
8951 : * reason for allocating dividend[0] above is to leave room for possible
8952 : * carry here.)
8953 : */
332 tgl 8954 GIC 1459 : if (divisor[1] < HALF_NBASE)
8955 : {
8956 1459 : int d = NBASE / (divisor[1] + 1);
8957 :
8958 1459 : carry = 0;
8959 12548 : for (i = var2ndigits; i > 0; i--)
8960 : {
8961 11089 : carry += divisor[i] * d;
332 tgl 8962 CBC 11089 : divisor[i] = carry % NBASE;
8963 11089 : carry = carry / NBASE;
8964 : }
332 tgl 8965 GIC 1459 : Assert(carry == 0);
332 tgl 8966 CBC 1459 : carry = 0;
8967 : /* at this point only var1ndigits of dividend can be nonzero */
332 tgl 8968 GIC 12994 : for (i = var1ndigits; i >= 0; i--)
8969 : {
8970 11535 : carry += dividend[i] * d;
8971 11535 : dividend[i] = carry % NBASE;
8972 11535 : carry = carry / NBASE;
8973 : }
8974 1459 : Assert(carry == 0);
8975 1459 : Assert(divisor[1] >= HALF_NBASE);
332 tgl 8976 ECB : }
8977 : /* First 2 divisor digits are used repeatedly in main loop */
332 tgl 8978 GIC 1459 : divisor1 = divisor[1];
8979 1459 : divisor2 = divisor[2];
8980 :
8981 : /*
8982 : * Begin the main loop. Each iteration of this loop produces the j'th
8983 : * quotient digit by dividing dividend[j .. j + var2ndigits] by the
8984 : * divisor; this is essentially the same as the common manual procedure
8985 : * for long division.
8986 : */
8987 11521 : for (j = 0; j < res_ndigits; j++)
8988 : {
8989 : /* Estimate quotient digit from the first two dividend digits */
8990 10062 : int next2digits = dividend[j] * NBASE + dividend[j + 1];
8991 : int qhat;
8992 :
8993 : /*
8994 : * If next2digits are 0, then quotient digit must be 0 and there's no
8995 : * need to adjust the working dividend. It's worth testing here to
8996 : * fall out ASAP when processing trailing zeroes in a dividend.
8997 : */
8998 10062 : if (next2digits == 0)
8999 : {
9000 36 : res_digits[j] = 0;
9001 36 : continue;
9002 : }
332 tgl 9003 ECB :
332 tgl 9004 GIC 10026 : if (dividend[j] == divisor1)
332 tgl 9005 CBC 60 : qhat = NBASE - 1;
9006 : else
9007 9966 : qhat = next2digits / divisor1;
5483 tgl 9008 ECB :
9009 : /*
9010 : * Adjust quotient digit if it's too large. Knuth proves that after
9011 : * this step, the quotient digit will be either correct or just one
332 9012 : * too large. (Note: it's OK to use dividend[j+2] here because we
9013 : * know the divisor length is at least 2.)
5483 9014 : */
332 tgl 9015 CBC 10026 : while (divisor2 * qhat >
332 tgl 9016 GIC 11672 : (next2digits - qhat * divisor1) * NBASE + dividend[j + 2])
332 tgl 9017 CBC 1646 : qhat--;
9018 :
9019 : /* As above, need do nothing more when quotient digit is 0 */
9020 10026 : if (qhat > 0)
5483 tgl 9021 ECB : {
332 tgl 9022 CBC 8818 : NumericDigit *dividend_j = ÷nd[j];
9023 :
9024 : /*
9025 : * Multiply the divisor by qhat, and subtract that from the
332 tgl 9026 ECB : * working dividend. The multiplication and subtraction are
9027 : * folded together here, noting that qhat <= NBASE (since it might
9028 : * be one too large), and so the intermediate result "tmp_result"
9029 : * is in the range [-NBASE^2, NBASE - 1], and "borrow" is in the
9030 : * range [0, NBASE].
9031 : */
332 tgl 9032 GIC 8818 : borrow = 0;
9033 87086 : for (i = var2ndigits; i >= 0; i--)
9034 : {
9035 : int tmp_result;
9036 :
9037 78268 : tmp_result = dividend_j[i] - borrow - divisor[i] * qhat;
9038 78268 : borrow = (NBASE - 1 - tmp_result) / NBASE;
9039 78268 : dividend_j[i] = tmp_result + borrow * NBASE;
9040 : }
9041 :
9042 : /*
9043 : * If we got a borrow out of the top dividend digit, then indeed
332 tgl 9044 ECB : * qhat was one too large. Fix it, and add back the divisor to
9045 : * correct the working dividend. (Knuth proves that this will
9046 : * occur only about 3/NBASE of the time; hence, it's a good idea
9047 : * to test this code with small NBASE to be sure this section gets
9048 : * exercised.)
5483 9049 : */
332 tgl 9050 GIC 8818 : if (borrow)
9051 : {
332 tgl 9052 CBC 13 : qhat--;
9053 13 : carry = 0;
5483 9054 1154 : for (i = var2ndigits; i >= 0; i--)
9055 : {
332 tgl 9056 GIC 1141 : carry += dividend_j[i] + divisor[i];
9057 1141 : if (carry >= NBASE)
9058 : {
9059 1047 : dividend_j[i] = carry - NBASE;
9060 1047 : carry = 1;
9061 : }
9062 : else
9063 : {
9064 94 : dividend_j[i] = carry;
9065 94 : carry = 0;
9066 : }
9067 : }
9068 : /* A carry should occur here to cancel the borrow above */
9069 13 : Assert(carry == 1);
9070 : }
9071 : }
9072 :
332 tgl 9073 ECB : /* And we're done with this quotient digit */
332 tgl 9074 CBC 10026 : res_digits[j] = qhat;
9075 : }
9076 :
5483 tgl 9077 GIC 1459 : pfree(dividend);
9078 :
9079 : /*
9080 : * Finally, round or truncate the result to the requested precision.
9081 : */
9082 1459 : result->weight = res_weight;
9083 1459 : result->sign = res_sign;
9084 :
5483 tgl 9085 ECB : /* Round or truncate to target rscale (and set result->dscale) */
5483 tgl 9086 GIC 1459 : if (round)
5483 tgl 9087 CBC 1459 : round_var(result, rscale);
9088 : else
5483 tgl 9089 LBC 0 : trunc_var(result, rscale);
5483 tgl 9090 ECB :
9091 : /* Strip leading and trailing zeroes */
5483 tgl 9092 GIC 1459 : strip_var(result);
5483 tgl 9093 ECB : }
9094 :
9095 :
9096 : /*
9097 : * div_var_fast() -
9098 : *
9099 : * This has the same API as div_var, but is implemented using the division
9100 : * algorithm from the "FM" library, rather than Knuth's schoolbook-division
9101 : * approach. This is significantly faster but can produce inaccurate
9102 : * results, because it sometimes has to propagate rounding to the left,
9103 : * and so we can never be entirely sure that we know the requested digits
9104 : * exactly. We compute DIV_GUARD_DIGITS extra digits, but there is
9105 : * no certainty that that's enough. We use this only in the transcendental
9106 : * function calculation routines, where everything is approximate anyway.
2692 9107 : *
9108 : * Although we provide a "round" argument for consistency with div_var,
9109 : * it is unwise to use this function with round=false. In truncation mode
9110 : * it is possible to get a result with no significant digits, for example
9111 : * with rscale=0 we might compute 0.99999... and truncate that to 0 when
9112 : * the correct answer is 1.
9113 : */
9114 : static void
2037 andres 9115 GIC 2901 : div_var_fast(const NumericVar *var1, const NumericVar *var2,
9116 : NumericVar *result, int rscale, bool round)
9117 : {
9118 : int div_ndigits;
9119 : int load_ndigits;
9120 : int res_sign;
9121 : int res_weight;
9122 : int *div;
9123 : int qdigit;
9124 : int carry;
9125 : int maxdiv;
9126 : int newdig;
9127 : NumericDigit *res_digits;
9128 : double fdividend,
7324 tgl 9129 ECB : fdivisor,
9130 : fdivisorinverse,
9131 : fquotient;
9132 : int qi;
8720 bruce 9133 : int i;
9134 :
9135 : /* copy these values into local vars for speed in inner loop */
7324 tgl 9136 GIC 2901 : int var1ndigits = var1->ndigits;
9137 2901 : int var2ndigits = var2->ndigits;
9138 2901 : NumericDigit *var1digits = var1->digits;
9139 2901 : NumericDigit *var2digits = var2->digits;
9140 :
9141 : /*
7324 tgl 9142 ECB : * First of all division by zero check; we must not be handed an
9143 : * unnormalized divisor.
8866 JanWieck 9144 : */
7324 tgl 9145 CBC 2901 : if (var2ndigits == 0 || var2digits[0] == 0)
7196 tgl 9146 GIC 3 : ereport(ERROR,
7196 tgl 9147 ECB : (errcode(ERRCODE_DIVISION_BY_ZERO),
9148 : errmsg("division by zero")));
9149 :
8053 bruce 9150 : /*
406 dean.a.rasheed 9151 : * If the divisor has just one or two digits, delegate to div_var_int(),
9152 : * which uses fast short division.
9153 : *
9154 : * Similarly, on platforms with 128-bit integer support, delegate to
9155 : * div_var_int64() for divisors with three or four digits.
9156 : */
406 dean.a.rasheed 9157 CBC 2898 : if (var2ndigits <= 2)
406 dean.a.rasheed 9158 ECB : {
9159 : int idivisor;
9160 : int idivisor_weight;
9161 :
406 dean.a.rasheed 9162 CBC 207 : idivisor = var2->digits[0];
406 dean.a.rasheed 9163 GIC 207 : idivisor_weight = var2->weight;
9164 207 : if (var2ndigits == 2)
9165 : {
406 dean.a.rasheed 9166 UIC 0 : idivisor = idivisor * NBASE + var2->digits[1];
406 dean.a.rasheed 9167 LBC 0 : idivisor_weight--;
406 dean.a.rasheed 9168 ECB : }
406 dean.a.rasheed 9169 GIC 207 : if (var2->sign == NUMERIC_NEG)
406 dean.a.rasheed 9170 UIC 0 : idivisor = -idivisor;
406 dean.a.rasheed 9171 ECB :
406 dean.a.rasheed 9172 GIC 207 : div_var_int(var1, idivisor, idivisor_weight, result, rscale, round);
9173 207 : return;
406 dean.a.rasheed 9174 ECB : }
9175 : #ifdef HAVE_INT128
76 dean.a.rasheed 9176 GNC 2691 : if (var2ndigits <= 4)
9177 : {
9178 : int64 idivisor;
9179 : int idivisor_weight;
9180 :
9181 21 : idivisor = var2->digits[0];
9182 21 : idivisor_weight = var2->weight;
9183 75 : for (i = 1; i < var2ndigits; i++)
9184 : {
9185 54 : idivisor = idivisor * NBASE + var2->digits[i];
9186 54 : idivisor_weight--;
9187 : }
9188 21 : if (var2->sign == NUMERIC_NEG)
76 dean.a.rasheed 9189 UNC 0 : idivisor = -idivisor;
9190 :
76 dean.a.rasheed 9191 GNC 21 : div_var_int64(var1, idivisor, idivisor_weight, result, rscale, round);
9192 21 : return;
9193 : }
9194 : #endif
9195 :
9196 : /*
9197 : * Otherwise, perform full long division.
9198 : */
9199 :
9200 : /* Result zero check */
7324 tgl 9201 GIC 2670 : if (var1ndigits == 0)
9202 : {
8482 9203 6 : zero_var(result);
7324 9204 6 : result->dscale = rscale;
8866 JanWieck 9205 6 : return;
9206 : }
8866 JanWieck 9207 ECB :
9208 : /*
9209 : * Determine the result sign, weight and number of digits to calculate
9210 : */
7324 tgl 9211 GIC 2664 : if (var1->sign == var2->sign)
9212 2628 : res_sign = NUMERIC_POS;
9213 : else
9214 36 : res_sign = NUMERIC_NEG;
9215 2664 : res_weight = var1->weight - var2->weight + 1;
9216 : /* The number of accurate result digits we need to produce: */
7188 bruce 9217 2664 : div_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
9218 : /* Add guard digits for roundoff error */
7324 tgl 9219 2664 : div_ndigits += DIV_GUARD_DIGITS;
9220 2664 : if (div_ndigits < DIV_GUARD_DIGITS)
7324 tgl 9221 UIC 0 : div_ndigits = DIV_GUARD_DIGITS;
9222 :
9223 : /*
9224 : * We do the arithmetic in an array "div[]" of signed int's. Since
6385 bruce 9225 ECB : * INT_MAX is noticeably larger than NBASE*NBASE, this gives us headroom
9226 : * to avoid normalizing carries immediately.
9227 : *
9228 : * We start with div[] containing one zero digit followed by the
9229 : * dividend's digits (plus appended zeroes to reach the desired precision
9230 : * including guard digits). Each step of the main loop computes an
9231 : * (approximate) quotient digit and stores it into div[], removing one
3260 9232 : * position of dividend space. A final pass of carry propagation takes
6347 9233 : * care of any mistaken quotient digits.
9234 : *
9235 : * Note that div[] doesn't necessarily contain all of the digits from the
9236 : * dividend --- the desired precision plus guard digits might be less than
9237 : * the dividend's precision. This happens, for example, in the square
9238 : * root algorithm, where we typically divide a 2N-digit number by an
9239 : * N-digit number, and only require a result with N digits of precision.
9240 : */
7324 tgl 9241 GIC 2664 : div = (int *) palloc0((div_ndigits + 1) * sizeof(int));
1107 dean.a.rasheed 9242 2664 : load_ndigits = Min(div_ndigits, var1ndigits);
9243 36354 : for (i = 0; i < load_ndigits; i++)
7188 bruce 9244 CBC 33690 : div[i + 1] = var1digits[i];
9245 :
9246 : /*
9247 : * We estimate each quotient digit using floating-point arithmetic, taking
9248 : * the first four digits of the (current) dividend and divisor. This must
2692 tgl 9249 ECB : * be float to avoid overflow. The quotient digits will generally be off
9250 : * by no more than one from the exact answer.
8866 JanWieck 9251 : */
7324 tgl 9252 GIC 2664 : fdivisor = (double) var2digits[0];
7324 tgl 9253 CBC 10656 : for (i = 1; i < 4; i++)
7324 tgl 9254 ECB : {
7324 tgl 9255 GIC 7992 : fdivisor *= NBASE;
7324 tgl 9256 CBC 7992 : if (i < var2ndigits)
9257 7992 : fdivisor += (double) var2digits[i];
9258 : }
9259 2664 : fdivisorinverse = 1.0 / fdivisor;
8866 JanWieck 9260 ECB :
9261 : /*
9262 : * maxdiv tracks the maximum possible absolute value of any div[] entry;
6385 bruce 9263 : * when this threatens to exceed INT_MAX, we take the time to propagate
9264 : * carries. Furthermore, we need to ensure that overflow doesn't occur
9265 : * during the carry propagation passes either. The carry values may have
9266 : * an absolute value as high as INT_MAX/NBASE + 1, so really we must
9267 : * normalize when digits threaten to exceed INT_MAX - INT_MAX/NBASE - 1.
2700 tgl 9268 : *
9269 : * To avoid overflow in maxdiv itself, it represents the max absolute
9270 : * value divided by NBASE-1, ie, at the top of the loop it is known that
9271 : * no div[] entry has an absolute value exceeding maxdiv * (NBASE-1).
2692 9272 : *
9273 : * Actually, though, that holds good only for div[] entries after div[qi];
9274 : * the adjustment done at the bottom of the loop may cause div[qi + 1] to
9275 : * exceed the maxdiv limit, so that div[qi] in the next iteration is
9276 : * beyond the limit. This does not cause problems, as explained below.
9277 : */
7324 tgl 9278 CBC 2664 : maxdiv = 1;
8720 bruce 9279 ECB :
9280 : /*
9281 : * Outer loop computes next quotient digit, which will go into div[qi]
9282 : */
7324 tgl 9283 GIC 45144 : for (qi = 0; qi < div_ndigits; qi++)
9284 : {
9285 : /* Approximate the current dividend value */
9286 42480 : fdividend = (double) div[qi];
9287 169920 : for (i = 1; i < 4; i++)
7324 tgl 9288 ECB : {
7324 tgl 9289 GIC 127440 : fdividend *= NBASE;
7188 bruce 9290 CBC 127440 : if (qi + i <= div_ndigits)
9291 119448 : fdividend += (double) div[qi + i];
7324 tgl 9292 ECB : }
9293 : /* Compute the (approximate) quotient digit */
7324 tgl 9294 GIC 42480 : fquotient = fdividend * fdivisorinverse;
9295 42480 : qdigit = (fquotient >= 0.0) ? ((int) fquotient) :
7188 bruce 9296 3 : (((int) fquotient) - 1); /* truncate towards -infinity */
9297 :
7324 tgl 9298 42480 : if (qdigit != 0)
9299 : {
7324 tgl 9300 ECB : /* Do we need to normalize now? */
184 peter 9301 GNC 37983 : maxdiv += abs(qdigit);
2700 tgl 9302 GIC 37983 : if (maxdiv > (INT_MAX - INT_MAX / NBASE - 1) / (NBASE - 1))
8866 JanWieck 9303 ECB : {
1107 dean.a.rasheed 9304 : /*
9305 : * Yes, do it. Note that if var2ndigits is much smaller than
9306 : * div_ndigits, we can save a significant amount of effort
9307 : * here by noting that we only need to normalise those div[]
9308 : * entries touched where prior iterations subtracted multiples
9309 : * of the divisor.
9310 : */
7324 tgl 9311 CBC 48 : carry = 0;
1107 dean.a.rasheed 9312 GIC 948 : for (i = Min(qi + var2ndigits - 2, div_ndigits); i > qi; i--)
9313 : {
7324 tgl 9314 900 : newdig = div[i] + carry;
9315 900 : if (newdig < 0)
9316 : {
7188 bruce 9317 900 : carry = -((-newdig - 1) / NBASE) - 1;
9318 900 : newdig -= carry * NBASE;
9319 : }
7324 tgl 9320 LBC 0 : else if (newdig >= NBASE)
7324 tgl 9321 ECB : {
7188 bruce 9322 UIC 0 : carry = newdig / NBASE;
9323 0 : newdig -= carry * NBASE;
9324 : }
9325 : else
7324 tgl 9326 0 : carry = 0;
7324 tgl 9327 GIC 900 : div[i] = newdig;
9328 : }
9329 48 : newdig = div[qi] + carry;
9330 48 : div[qi] = newdig;
9331 :
9332 : /*
9333 : * All the div[] digits except possibly div[qi] are now in the
2692 tgl 9334 ECB : * range 0..NBASE-1. We do not need to consider div[qi] in
9335 : * the maxdiv value anymore, so we can reset maxdiv to 1.
7324 9336 : */
2692 tgl 9337 CBC 48 : maxdiv = 1;
9338 :
9339 : /*
9340 : * Recompute the quotient digit since new info may have
9341 : * propagated into the top four dividend digits
7324 tgl 9342 ECB : */
7324 tgl 9343 CBC 48 : fdividend = (double) div[qi];
7324 tgl 9344 GIC 192 : for (i = 1; i < 4; i++)
9345 : {
9346 144 : fdividend *= NBASE;
7188 bruce 9347 144 : if (qi + i <= div_ndigits)
9348 144 : fdividend += (double) div[qi + i];
9349 : }
9350 : /* Compute the (approximate) quotient digit */
7324 tgl 9351 48 : fquotient = fdividend * fdivisorinverse;
9352 48 : qdigit = (fquotient >= 0.0) ? ((int) fquotient) :
6385 bruce 9353 UIC 0 : (((int) fquotient) - 1); /* truncate towards -infinity */
184 peter 9354 GNC 48 : maxdiv += abs(qdigit);
9355 : }
8866 JanWieck 9356 ECB :
9357 : /*
2692 tgl 9358 : * Subtract off the appropriate multiple of the divisor.
9359 : *
9360 : * The digits beyond div[qi] cannot overflow, because we know they
9361 : * will fall within the maxdiv limit. As for div[qi] itself, note
9362 : * that qdigit is approximately trunc(div[qi] / vardigits[0]),
9363 : * which would make the new value simply div[qi] mod vardigits[0].
9364 : * The lower-order terms in qdigit can change this result by not
9365 : * more than about twice INT_MAX/NBASE, so overflow is impossible.
406 dean.a.rasheed 9366 : *
9367 : * This inner loop is the performance bottleneck for division, so
9368 : * code it in the same way as the inner loop of mul_var() so that
9369 : * it can be auto-vectorized. We cast qdigit to NumericDigit
9370 : * before multiplying to allow the compiler to generate more
9371 : * efficient code (using 16-bit multiplication), which is safe
9372 : * since we know that the quotient digit is off by at most one, so
9373 : * there is no overflow risk.
2692 tgl 9374 : */
7324 tgl 9375 CBC 37983 : if (qdigit != 0)
9376 : {
7188 bruce 9377 GIC 37983 : int istop = Min(var2ndigits, div_ndigits - qi + 1);
406 dean.a.rasheed 9378 CBC 37983 : int *div_qi = &div[qi];
8866 JanWieck 9379 ECB :
7324 tgl 9380 GIC 465018 : for (i = 0; i < istop; i++)
406 dean.a.rasheed 9381 427035 : div_qi[i] -= ((NumericDigit) qdigit) * var2digits[i];
9382 : }
9383 : }
9384 :
9385 : /*
9386 : * The dividend digit we are about to replace might still be nonzero.
2692 tgl 9387 ECB : * Fold it into the next digit position.
9388 : *
9389 : * There is no risk of overflow here, although proving that requires
9390 : * some care. Much as with the argument for div[qi] not overflowing,
9391 : * if we consider the first two terms in the numerator and denominator
9392 : * of qdigit, we can see that the final value of div[qi + 1] will be
9393 : * approximately a remainder mod (vardigits[0]*NBASE + vardigits[1]).
9394 : * Accounting for the lower-order terms is a bit complicated but ends
9395 : * up adding not much more than INT_MAX/NBASE to the possible range.
9396 : * Thus, div[qi + 1] cannot overflow here, and in its role as div[qi]
9397 : * in the next loop iteration, it can't be large enough to cause
9398 : * overflow in the carry propagation step (if any), either.
9399 : *
9400 : * But having said that: div[qi] can be more than INT_MAX/NBASE, as
9401 : * noted above, which means that the product div[qi] * NBASE *can*
9402 : * overflow. When that happens, adding it to div[qi + 1] will always
9403 : * cause a canceling overflow so that the end result is correct. We
9404 : * could avoid the intermediate overflow by doing the multiplication
9405 : * and addition in int64 arithmetic, but so far there appears no need.
9406 : */
7188 bruce 9407 CBC 42480 : div[qi + 1] += div[qi] * NBASE;
9408 :
7324 tgl 9409 GIC 42480 : div[qi] = qdigit;
9410 : }
9411 :
9412 : /*
9413 : * Approximate and store the last quotient digit (div[div_ndigits])
9414 : */
7324 tgl 9415 CBC 2664 : fdividend = (double) div[qi];
9416 10656 : for (i = 1; i < 4; i++)
9417 7992 : fdividend *= NBASE;
7324 tgl 9418 GIC 2664 : fquotient = fdividend * fdivisorinverse;
9419 2664 : qdigit = (fquotient >= 0.0) ? ((int) fquotient) :
7188 bruce 9420 LBC 0 : (((int) fquotient) - 1); /* truncate towards -infinity */
7324 tgl 9421 GIC 2664 : div[qi] = qdigit;
8866 JanWieck 9422 ECB :
9423 : /*
9424 : * Because the quotient digits might be off by one, some of them might be
9425 : * -1 or NBASE at this point. The represented value is correct in a
9426 : * mathematical sense, but it doesn't look right. We do a final carry
9427 : * propagation pass to normalize the digits, which we combine with storing
9428 : * the result digits into the output. Note that this is still done at
9429 : * full precision w/guard digits.
9430 : */
7188 bruce 9431 GIC 2664 : alloc_var(result, div_ndigits + 1);
7324 tgl 9432 CBC 2664 : res_digits = result->digits;
9433 2664 : carry = 0;
7324 tgl 9434 GIC 47808 : for (i = div_ndigits; i >= 0; i--)
9435 : {
9436 45144 : newdig = div[i] + carry;
7324 tgl 9437 CBC 45144 : if (newdig < 0)
8866 JanWieck 9438 ECB : {
7188 bruce 9439 CBC 6 : carry = -((-newdig - 1) / NBASE) - 1;
7188 bruce 9440 GIC 6 : newdig -= carry * NBASE;
9441 : }
7324 tgl 9442 45138 : else if (newdig >= NBASE)
9443 : {
7188 bruce 9444 174 : carry = newdig / NBASE;
9445 174 : newdig -= carry * NBASE;
9446 : }
9447 : else
7324 tgl 9448 44964 : carry = 0;
9449 45144 : res_digits[i] = newdig;
8866 JanWieck 9450 ECB : }
7324 tgl 9451 GIC 2664 : Assert(carry == 0);
8866 JanWieck 9452 ECB :
7324 tgl 9453 CBC 2664 : pfree(div);
8866 JanWieck 9454 ECB :
9455 : /*
7324 tgl 9456 : * Finally, round the result to the requested precision.
8866 JanWieck 9457 : */
7324 tgl 9458 GIC 2664 : result->weight = res_weight;
7324 tgl 9459 CBC 2664 : result->sign = res_sign;
7324 tgl 9460 ECB :
9461 : /* Round to target rscale (and set result->dscale) */
6518 bruce 9462 GIC 2664 : if (round)
9463 405 : round_var(result, rscale);
6518 bruce 9464 ECB : else
6518 bruce 9465 CBC 2259 : trunc_var(result, rscale);
9466 :
9467 : /* Strip leading and trailing zeroes */
7324 tgl 9468 GIC 2664 : strip_var(result);
8866 JanWieck 9469 ECB : }
9470 :
9471 :
9472 : /*
9473 : * div_var_int() -
406 dean.a.rasheed 9474 : *
9475 : * Divide a numeric variable by a 32-bit integer with the specified weight.
9476 : * The quotient var / (ival * NBASE^ival_weight) is stored in result.
9477 : */
9478 : static void
406 dean.a.rasheed 9479 GIC 96609 : div_var_int(const NumericVar *var, int ival, int ival_weight,
9480 : NumericVar *result, int rscale, bool round)
9481 : {
406 dean.a.rasheed 9482 CBC 96609 : NumericDigit *var_digits = var->digits;
9483 96609 : int var_ndigits = var->ndigits;
9484 : int res_sign;
9485 : int res_weight;
406 dean.a.rasheed 9486 ECB : int res_ndigits;
9487 : NumericDigit *res_buf;
9488 : NumericDigit *res_digits;
406 dean.a.rasheed 9489 EUB : uint32 divisor;
9490 : int i;
9491 :
406 dean.a.rasheed 9492 ECB : /* Guard against division by zero */
406 dean.a.rasheed 9493 GIC 96609 : if (ival == 0)
406 dean.a.rasheed 9494 UIC 0 : ereport(ERROR,
9495 : errcode(ERRCODE_DIVISION_BY_ZERO),
9496 : errmsg("division by zero"));
9497 :
9498 : /* Result zero check */
406 dean.a.rasheed 9499 GIC 96609 : if (var_ndigits == 0)
9500 : {
9501 1141 : zero_var(result);
9502 1141 : result->dscale = rscale;
9503 1141 : return;
9504 : }
9505 :
9506 : /*
9507 : * Determine the result sign, weight and number of digits to calculate.
9508 : * The weight figured here is correct if the emitted quotient has no
9509 : * leading zero digits; otherwise strip_var() will fix things up.
9510 : */
9511 95468 : if (var->sign == NUMERIC_POS)
9512 94055 : res_sign = ival > 0 ? NUMERIC_POS : NUMERIC_NEG;
9513 : else
9514 1413 : res_sign = ival > 0 ? NUMERIC_NEG : NUMERIC_POS;
406 dean.a.rasheed 9515 CBC 95468 : res_weight = var->weight - ival_weight;
9516 : /* The number of accurate result digits we need to produce: */
406 dean.a.rasheed 9517 GIC 95468 : res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
9518 : /* ... but always at least 1 */
9519 95468 : res_ndigits = Max(res_ndigits, 1);
9520 : /* If rounding needed, figure one more digit to ensure correct result */
9521 95468 : if (round)
9522 68459 : res_ndigits++;
9523 :
9524 95468 : res_buf = digitbuf_alloc(res_ndigits + 1);
9525 95468 : res_buf[0] = 0; /* spare digit for later rounding */
9526 95468 : res_digits = res_buf + 1;
9527 :
9528 : /*
9529 : * Now compute the quotient digits. This is the short division algorithm
9530 : * described in Knuth volume 2, section 4.3.1 exercise 16, except that we
9531 : * allow the divisor to exceed the internal base.
9532 : *
9533 : * In this algorithm, the carry from one digit to the next is at most
9534 : * divisor - 1. Therefore, while processing the next digit, carry may
9535 : * become as large as divisor * NBASE - 1, and so it requires a 64-bit
406 dean.a.rasheed 9536 ECB : * integer if this exceeds UINT_MAX.
9537 : */
184 peter 9538 GNC 95468 : divisor = abs(ival);
406 dean.a.rasheed 9539 ECB :
406 dean.a.rasheed 9540 GIC 95468 : if (divisor <= UINT_MAX / NBASE)
9541 : {
9542 : /* carry cannot overflow 32 bits */
9543 94217 : uint32 carry = 0;
9544 :
406 dean.a.rasheed 9545 CBC 945778 : for (i = 0; i < res_ndigits; i++)
406 dean.a.rasheed 9546 ECB : {
406 dean.a.rasheed 9547 GIC 851561 : carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
9548 851561 : res_digits[i] = (NumericDigit) (carry / divisor);
9549 851561 : carry = carry % divisor;
9550 : }
9551 : }
9552 : else
9553 : {
9554 : /* carry may exceed 32 bits */
9555 1251 : uint64 carry = 0;
9556 :
406 dean.a.rasheed 9557 CBC 4086 : for (i = 0; i < res_ndigits; i++)
9558 : {
406 dean.a.rasheed 9559 GIC 2835 : carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
9560 2835 : res_digits[i] = (NumericDigit) (carry / divisor);
9561 2835 : carry = carry % divisor;
406 dean.a.rasheed 9562 ECB : }
9563 : }
9564 :
9565 : /* Store the quotient in result */
406 dean.a.rasheed 9566 GBC 95468 : digitbuf_free(result->buf);
9567 95468 : result->ndigits = res_ndigits;
406 dean.a.rasheed 9568 GIC 95468 : result->buf = res_buf;
406 dean.a.rasheed 9569 CBC 95468 : result->digits = res_digits;
406 dean.a.rasheed 9570 GBC 95468 : result->weight = res_weight;
406 dean.a.rasheed 9571 GIC 95468 : result->sign = res_sign;
406 dean.a.rasheed 9572 ECB :
9573 : /* Round or truncate to target rscale (and set result->dscale) */
406 dean.a.rasheed 9574 GIC 95468 : if (round)
9575 68459 : round_var(result, rscale);
406 dean.a.rasheed 9576 ECB : else
406 dean.a.rasheed 9577 GIC 27009 : trunc_var(result, rscale);
9578 :
9579 : /* Strip leading/trailing zeroes */
9580 95468 : strip_var(result);
406 dean.a.rasheed 9581 ECB : }
9582 :
9583 :
9584 : #ifdef HAVE_INT128
9585 : /*
9586 : * div_var_int64() -
9587 : *
9588 : * Divide a numeric variable by a 64-bit integer with the specified weight.
9589 : * The quotient var / (ival * NBASE^ival_weight) is stored in result.
9590 : *
9591 : * This duplicates the logic in div_var_int(), so any changes made there
9592 : * should be made here too.
9593 : */
9594 : static void
76 dean.a.rasheed 9595 GNC 264 : div_var_int64(const NumericVar *var, int64 ival, int ival_weight,
9596 : NumericVar *result, int rscale, bool round)
9597 : {
9598 264 : NumericDigit *var_digits = var->digits;
9599 264 : int var_ndigits = var->ndigits;
9600 : int res_sign;
9601 : int res_weight;
9602 : int res_ndigits;
9603 : NumericDigit *res_buf;
9604 : NumericDigit *res_digits;
9605 : uint64 divisor;
9606 : int i;
9607 :
9608 : /* Guard against division by zero */
9609 264 : if (ival == 0)
76 dean.a.rasheed 9610 UNC 0 : ereport(ERROR,
9611 : errcode(ERRCODE_DIVISION_BY_ZERO),
9612 : errmsg("division by zero"));
9613 :
9614 : /* Result zero check */
76 dean.a.rasheed 9615 GNC 264 : if (var_ndigits == 0)
9616 : {
9617 48 : zero_var(result);
9618 48 : result->dscale = rscale;
9619 48 : return;
9620 : }
9621 :
9622 : /*
9623 : * Determine the result sign, weight and number of digits to calculate.
9624 : * The weight figured here is correct if the emitted quotient has no
9625 : * leading zero digits; otherwise strip_var() will fix things up.
9626 : */
9627 216 : if (var->sign == NUMERIC_POS)
9628 129 : res_sign = ival > 0 ? NUMERIC_POS : NUMERIC_NEG;
9629 : else
9630 87 : res_sign = ival > 0 ? NUMERIC_NEG : NUMERIC_POS;
9631 216 : res_weight = var->weight - ival_weight;
9632 : /* The number of accurate result digits we need to produce: */
9633 216 : res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
9634 : /* ... but always at least 1 */
9635 216 : res_ndigits = Max(res_ndigits, 1);
9636 : /* If rounding needed, figure one more digit to ensure correct result */
9637 216 : if (round)
9638 216 : res_ndigits++;
9639 :
9640 216 : res_buf = digitbuf_alloc(res_ndigits + 1);
9641 216 : res_buf[0] = 0; /* spare digit for later rounding */
9642 216 : res_digits = res_buf + 1;
9643 :
9644 : /*
9645 : * Now compute the quotient digits. This is the short division algorithm
9646 : * described in Knuth volume 2, section 4.3.1 exercise 16, except that we
9647 : * allow the divisor to exceed the internal base.
9648 : *
9649 : * In this algorithm, the carry from one digit to the next is at most
9650 : * divisor - 1. Therefore, while processing the next digit, carry may
9651 : * become as large as divisor * NBASE - 1, and so it requires a 128-bit
9652 : * integer if this exceeds PG_UINT64_MAX.
9653 : */
9654 216 : divisor = i64abs(ival);
9655 :
9656 216 : if (divisor <= PG_UINT64_MAX / NBASE)
9657 : {
9658 : /* carry cannot overflow 64 bits */
9659 168 : uint64 carry = 0;
9660 :
9661 1721 : for (i = 0; i < res_ndigits; i++)
9662 : {
9663 1553 : carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
9664 1553 : res_digits[i] = (NumericDigit) (carry / divisor);
9665 1553 : carry = carry % divisor;
9666 : }
9667 : }
9668 : else
9669 : {
9670 : /* carry may exceed 64 bits */
9671 48 : uint128 carry = 0;
9672 :
9673 516 : for (i = 0; i < res_ndigits; i++)
9674 : {
9675 468 : carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
9676 468 : res_digits[i] = (NumericDigit) (carry / divisor);
9677 468 : carry = carry % divisor;
9678 : }
9679 : }
9680 :
9681 : /* Store the quotient in result */
9682 216 : digitbuf_free(result->buf);
9683 216 : result->ndigits = res_ndigits;
9684 216 : result->buf = res_buf;
9685 216 : result->digits = res_digits;
9686 216 : result->weight = res_weight;
9687 216 : result->sign = res_sign;
9688 :
9689 : /* Round or truncate to target rscale (and set result->dscale) */
9690 216 : if (round)
9691 216 : round_var(result, rscale);
9692 : else
76 dean.a.rasheed 9693 UNC 0 : trunc_var(result, rscale);
9694 :
9695 : /* Strip leading/trailing zeroes */
76 dean.a.rasheed 9696 GNC 216 : strip_var(result);
9697 : }
9698 : #endif
9699 :
9700 :
9701 : /*
7789 tgl 9702 ECB : * Default scale selection for division
9703 : *
9704 : * Returns the appropriate result scale for the division result.
9705 : */
7789 tgl 9706 EUB : static int
2037 andres 9707 GIC 61415 : select_div_scale(const NumericVar *var1, const NumericVar *var2)
7789 tgl 9708 ECB : {
7494 9709 : int weight1,
9710 : weight2,
9711 : qweight,
9712 : i;
9713 : NumericDigit firstdigit1,
9714 : firstdigit2;
9715 : int rscale;
9716 :
9717 : /*
6385 bruce 9718 : * The result scale of a division isn't specified in any SQL standard. For
9719 : * PostgreSQL we select a result scale that will give at least
7494 tgl 9720 : * NUMERIC_MIN_SIG_DIGITS significant digits, so that numeric gives a
9721 : * result no less accurate than float8; but use a scale not less than
9722 : * either input's display scale.
9723 : */
9724 :
9725 : /* Get the actual (normalized) weight and first digit of each input */
9726 :
7494 tgl 9727 GIC 61415 : weight1 = 0; /* values to use if var1 is zero */
7494 tgl 9728 CBC 61415 : firstdigit1 = 0;
9729 61415 : for (i = 0; i < var1->ndigits; i++)
9730 : {
9731 60559 : firstdigit1 = var1->digits[i];
9732 60559 : if (firstdigit1 != 0)
9733 : {
9734 60559 : weight1 = var1->weight - i;
7494 tgl 9735 GIC 60559 : break;
7494 tgl 9736 ECB : }
9737 : }
7494 tgl 9738 EUB :
7494 tgl 9739 GIC 61415 : weight2 = 0; /* values to use if var2 is zero */
9740 61415 : firstdigit2 = 0;
9741 61415 : for (i = 0; i < var2->ndigits; i++)
9742 : {
9743 61390 : firstdigit2 = var2->digits[i];
9744 61390 : if (firstdigit2 != 0)
9745 : {
9746 61390 : weight2 = var2->weight - i;
9747 61390 : break;
9748 : }
9749 : }
9750 :
9751 : /*
9752 : * Estimate weight of quotient. If the two first digits are equal, we
9753 : * can't be sure, but assume that var1 is less than var2.
9754 : */
9755 61415 : qweight = weight1 - weight2;
9756 61415 : if (firstdigit1 <= firstdigit2)
9757 55625 : qweight--;
7494 tgl 9758 ECB :
9759 : /* Select result scale */
7324 tgl 9760 CBC 61415 : rscale = NUMERIC_MIN_SIG_DIGITS - qweight * DEC_DIGITS;
9761 61415 : rscale = Max(rscale, var1->dscale);
7324 tgl 9762 GIC 61415 : rscale = Max(rscale, var2->dscale);
9763 61415 : rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
9764 61415 : rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
9765 :
9766 61415 : return rscale;
9767 : }
9768 :
7789 tgl 9769 ECB :
7324 9770 : /*
9771 : * mod_var() -
8866 JanWieck 9772 : *
9773 : * Calculate the modulo of two numerics at variable level
9774 : */
9775 : static void
2037 andres 9776 CBC 26484 : mod_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
9777 : {
9778 : NumericVar tmp;
9779 :
8866 JanWieck 9780 GIC 26484 : init_var(&tmp);
9781 :
9782 : /* ---------
9783 : * We do this using the equation
9784 : * mod(x,y) = x - trunc(x/y)*y
9785 : * div_var can be persuaded to give us trunc(x/y) directly.
9786 : * ----------
9787 : */
5483 tgl 9788 26484 : div_var(var1, var2, &tmp, 0, false);
9789 :
9790 26478 : mul_var(var2, &tmp, &tmp, var2->dscale);
9791 :
8866 JanWieck 9792 26478 : sub_var(var1, &tmp, result);
9793 :
9794 26478 : free_var(&tmp);
8866 JanWieck 9795 CBC 26478 : }
9796 :
9797 :
9798 : /*
9799 : * div_mod_var() -
1107 dean.a.rasheed 9800 ECB : *
9801 : * Calculate the truncated integer quotient and numeric remainder of two
9802 : * numeric variables. The remainder is precise to var2's dscale.
9803 : */
9804 : static void
1107 dean.a.rasheed 9805 GIC 2259 : div_mod_var(const NumericVar *var1, const NumericVar *var2,
1107 dean.a.rasheed 9806 ECB : NumericVar *quot, NumericVar *rem)
9807 : {
9808 : NumericVar q;
9809 : NumericVar r;
9810 :
1107 dean.a.rasheed 9811 CBC 2259 : init_var(&q);
9812 2259 : init_var(&r);
1107 dean.a.rasheed 9813 ECB :
9814 : /*
9815 : * Use div_var_fast() to get an initial estimate for the integer quotient.
9816 : * This might be inaccurate (per the warning in div_var_fast's comments),
9817 : * but we can correct it below.
9818 : */
1107 dean.a.rasheed 9819 CBC 2259 : div_var_fast(var1, var2, &q, 0, false);
9820 :
9821 : /* Compute initial estimate of remainder using the quotient estimate. */
1107 dean.a.rasheed 9822 GIC 2259 : mul_var(var2, &q, &r, var2->dscale);
9823 2259 : sub_var(var1, &r, &r);
9824 :
9825 : /*
9826 : * Adjust the results if necessary --- the remainder should have the same
9827 : * sign as var1, and its absolute value should be less than the absolute
1107 dean.a.rasheed 9828 ECB : * value of var2.
9829 : */
1107 dean.a.rasheed 9830 GIC 2259 : while (r.ndigits != 0 && r.sign != var1->sign)
1107 dean.a.rasheed 9831 ECB : {
9832 : /* The absolute value of the quotient is too large */
1107 dean.a.rasheed 9833 UIC 0 : if (var1->sign == var2->sign)
1107 dean.a.rasheed 9834 ECB : {
1107 dean.a.rasheed 9835 LBC 0 : sub_var(&q, &const_one, &q);
1107 dean.a.rasheed 9836 UIC 0 : add_var(&r, var2, &r);
1107 dean.a.rasheed 9837 EUB : }
9838 : else
9839 : {
1107 dean.a.rasheed 9840 UBC 0 : add_var(&q, &const_one, &q);
1107 dean.a.rasheed 9841 UIC 0 : sub_var(&r, var2, &r);
9842 : }
1107 dean.a.rasheed 9843 EUB : }
1107 dean.a.rasheed 9844 ECB :
1107 dean.a.rasheed 9845 GIC 2259 : while (cmp_abs(&r, var2) >= 0)
1107 dean.a.rasheed 9846 ECB : {
9847 : /* The absolute value of the quotient is too small */
1107 dean.a.rasheed 9848 UIC 0 : if (var1->sign == var2->sign)
9849 : {
9850 0 : add_var(&q, &const_one, &q);
9851 0 : sub_var(&r, var2, &r);
9852 : }
9853 : else
1107 dean.a.rasheed 9854 ECB : {
1107 dean.a.rasheed 9855 UIC 0 : sub_var(&q, &const_one, &q);
9856 0 : add_var(&r, var2, &r);
9857 : }
9858 : }
9859 :
1107 dean.a.rasheed 9860 CBC 2259 : set_var_from_var(&q, quot);
9861 2259 : set_var_from_var(&r, rem);
9862 :
9863 2259 : free_var(&q);
9864 2259 : free_var(&r);
9865 2259 : }
9866 :
9867 :
7324 tgl 9868 ECB : /*
8866 JanWieck 9869 : * ceil_var() -
8866 JanWieck 9870 EUB : *
8866 JanWieck 9871 ECB : * Return the smallest integer greater than or equal to the argument
9872 : * on variable level
9873 : */
9874 : static void
2037 andres 9875 GIC 102 : ceil_var(const NumericVar *var, NumericVar *result)
9876 : {
9877 : NumericVar tmp;
9878 :
8866 JanWieck 9879 102 : init_var(&tmp);
9880 102 : set_var_from_var(var, &tmp);
9881 :
7324 tgl 9882 102 : trunc_var(&tmp, 0);
9883 :
9884 102 : if (var->sign == NUMERIC_POS && cmp_var(var, &tmp) != 0)
8866 JanWieck 9885 30 : add_var(&tmp, &const_one, &tmp);
9886 :
9887 102 : set_var_from_var(&tmp, result);
9888 102 : free_var(&tmp);
9889 102 : }
9890 :
9891 :
7324 tgl 9892 ECB : /*
9893 : * floor_var() -
8866 JanWieck 9894 : *
9895 : * Return the largest integer equal to or less than the argument
9896 : * on variable level
9897 : */
9898 : static void
2037 andres 9899 GIC 288 : floor_var(const NumericVar *var, NumericVar *result)
9900 : {
9901 : NumericVar tmp;
9902 :
8866 JanWieck 9903 288 : init_var(&tmp);
9904 288 : set_var_from_var(var, &tmp);
9905 :
7324 tgl 9906 288 : trunc_var(&tmp, 0);
9907 :
9908 288 : if (var->sign == NUMERIC_NEG && cmp_var(var, &tmp) != 0)
8866 JanWieck 9909 15 : sub_var(&tmp, &const_one, &tmp);
9910 :
9911 288 : set_var_from_var(&tmp, result);
9912 288 : free_var(&tmp);
9913 288 : }
9914 :
9915 :
9916 : /*
9917 : * gcd_var() -
9918 : *
9919 : * Calculate the greatest common divisor of two numerics at variable level
9920 : */
9921 : static void
1170 dean.a.rasheed 9922 111 : gcd_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
9923 : {
1170 dean.a.rasheed 9924 ECB : int res_dscale;
9925 : int cmp;
9926 : NumericVar tmp_arg;
9927 : NumericVar mod;
9928 :
1170 dean.a.rasheed 9929 GIC 111 : res_dscale = Max(var1->dscale, var2->dscale);
9930 :
9931 : /*
1170 dean.a.rasheed 9932 ECB : * Arrange for var1 to be the number with the greater absolute value.
9933 : *
9934 : * This would happen automatically in the loop below, but avoids an
9935 : * expensive modulo operation.
9936 : */
1170 dean.a.rasheed 9937 GBC 111 : cmp = cmp_abs(var1, var2);
1170 dean.a.rasheed 9938 CBC 111 : if (cmp < 0)
9939 : {
1170 dean.a.rasheed 9940 GIC 42 : const NumericVar *tmp = var1;
9941 :
9942 42 : var1 = var2;
9943 42 : var2 = tmp;
9944 : }
9945 :
9946 : /*
9947 : * Also avoid the taking the modulo if the inputs have the same absolute
1170 dean.a.rasheed 9948 ECB : * value, or if the smaller input is zero.
9949 : */
1170 dean.a.rasheed 9950 CBC 111 : if (cmp == 0 || var2->ndigits == 0)
1170 dean.a.rasheed 9951 ECB : {
1170 dean.a.rasheed 9952 GIC 36 : set_var_from_var(var1, result);
1170 dean.a.rasheed 9953 CBC 36 : result->sign = NUMERIC_POS;
9954 36 : result->dscale = res_dscale;
1170 dean.a.rasheed 9955 GIC 36 : return;
1170 dean.a.rasheed 9956 ECB : }
9957 :
1170 dean.a.rasheed 9958 GIC 75 : init_var(&tmp_arg);
1170 dean.a.rasheed 9959 CBC 75 : init_var(&mod);
9960 :
1170 dean.a.rasheed 9961 ECB : /* Use the Euclidean algorithm to find the GCD */
1170 dean.a.rasheed 9962 CBC 75 : set_var_from_var(var1, &tmp_arg);
1170 dean.a.rasheed 9963 GIC 75 : set_var_from_var(var2, result);
9964 :
1170 dean.a.rasheed 9965 ECB : for (;;)
9966 : {
9967 : /* this loop can take a while, so allow it to be interrupted */
1170 dean.a.rasheed 9968 CBC 294 : CHECK_FOR_INTERRUPTS();
9969 :
9970 294 : mod_var(&tmp_arg, result, &mod);
1170 dean.a.rasheed 9971 GIC 294 : if (mod.ndigits == 0)
9972 75 : break;
9973 219 : set_var_from_var(result, &tmp_arg);
9974 219 : set_var_from_var(&mod, result);
1170 dean.a.rasheed 9975 ECB : }
1170 dean.a.rasheed 9976 CBC 75 : result->sign = NUMERIC_POS;
1170 dean.a.rasheed 9977 GIC 75 : result->dscale = res_dscale;
9978 :
1170 dean.a.rasheed 9979 CBC 75 : free_var(&tmp_arg);
9980 75 : free_var(&mod);
9981 : }
1170 dean.a.rasheed 9982 ECB :
9983 :
9984 : /*
8866 JanWieck 9985 : * sqrt_var() -
9986 : *
9987 : * Compute the square root of x using the Karatsuba Square Root algorithm.
9988 : * NOTE: we allow rscale < 0 here, implying rounding before the decimal
9989 : * point.
9990 : */
9991 : static void
2037 andres 9992 GIC 2097 : sqrt_var(const NumericVar *arg, NumericVar *result, int rscale)
9993 : {
9994 : int stat;
9995 : int res_weight;
1107 dean.a.rasheed 9996 ECB : int res_ndigits;
9997 : int src_ndigits;
9998 : int step;
9999 : int ndigits[32];
10000 : int blen;
10001 : int64 arg_int64;
10002 : int src_idx;
10003 : int64 s_int64;
10004 : int64 r_int64;
10005 : NumericVar s_var;
10006 : NumericVar r_var;
10007 : NumericVar a0_var;
10008 : NumericVar a1_var;
10009 : NumericVar q_var;
10010 : NumericVar u_var;
8866 JanWieck 10011 EUB :
8866 JanWieck 10012 GIC 2097 : stat = cmp_var(arg, &const_zero);
10013 2097 : if (stat == 0)
10014 : {
7324 tgl 10015 9 : zero_var(result);
7324 tgl 10016 CBC 9 : result->dscale = rscale;
8866 JanWieck 10017 GIC 9 : return;
8866 JanWieck 10018 ECB : }
10019 :
6899 neilc 10020 : /*
10021 : * SQL2003 defines sqrt() in terms of power, so we need to emit the right
10022 : * SQLSTATE error code if the operand is negative.
10023 : */
8866 JanWieck 10024 GIC 2088 : if (stat < 0)
7196 tgl 10025 3 : ereport(ERROR,
10026 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
10027 : errmsg("cannot take square root of a negative number")));
8866 JanWieck 10028 ECB :
1107 dean.a.rasheed 10029 CBC 2085 : init_var(&s_var);
1107 dean.a.rasheed 10030 GIC 2085 : init_var(&r_var);
1107 dean.a.rasheed 10031 CBC 2085 : init_var(&a0_var);
10032 2085 : init_var(&a1_var);
1107 dean.a.rasheed 10033 GIC 2085 : init_var(&q_var);
1107 dean.a.rasheed 10034 CBC 2085 : init_var(&u_var);
10035 :
1107 dean.a.rasheed 10036 ECB : /*
10037 : * The result weight is half the input weight, rounded towards minus
10038 : * infinity --- res_weight = floor(arg->weight / 2).
10039 : */
1107 dean.a.rasheed 10040 GIC 2085 : if (arg->weight >= 0)
1107 dean.a.rasheed 10041 CBC 1929 : res_weight = arg->weight / 2;
1107 dean.a.rasheed 10042 ECB : else
1107 dean.a.rasheed 10043 CBC 156 : res_weight = -((-arg->weight - 1) / 2 + 1);
10044 :
10045 : /*
10046 : * Number of NBASE digits to compute. To ensure correct rounding, compute
10047 : * at least 1 extra decimal digit. We explicitly allow rscale to be
10048 : * negative here, but must always compute at least 1 NBASE digit. Thus
10049 : * res_ndigits = res_weight + 1 + ceil((rscale + 1) / DEC_DIGITS) or 1.
10050 : */
1107 dean.a.rasheed 10051 GIC 2085 : if (rscale + 1 >= 0)
10052 2085 : res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS) / DEC_DIGITS;
10053 : else
1107 dean.a.rasheed 10054 UIC 0 : res_ndigits = res_weight + 1 - (-rscale - 1) / DEC_DIGITS;
1107 dean.a.rasheed 10055 CBC 2085 : res_ndigits = Max(res_ndigits, 1);
10056 :
1107 dean.a.rasheed 10057 ECB : /*
10058 : * Number of source NBASE digits logically required to produce a result
10059 : * with this precision --- every digit before the decimal point, plus 2
10060 : * for each result digit after the decimal point (or minus 2 for each
10061 : * result digit we round before the decimal point).
10062 : */
1107 dean.a.rasheed 10063 GIC 2085 : src_ndigits = arg->weight + 1 + (res_ndigits - res_weight - 1) * 2;
1107 dean.a.rasheed 10064 CBC 2085 : src_ndigits = Max(src_ndigits, 1);
7494 tgl 10065 ECB :
1107 dean.a.rasheed 10066 : /* ----------
10067 : * From this point on, we treat the input and the result as integers and
10068 : * compute the integer square root and remainder using the Karatsuba
10069 : * Square Root algorithm, which may be written recursively as follows:
10070 : *
10071 : * SqrtRem(n = a3*b^3 + a2*b^2 + a1*b + a0):
10072 : * [ for some base b, and coefficients a0,a1,a2,a3 chosen so that
10073 : * 0 <= a0,a1,a2 < b and a3 >= b/4 ]
10074 : * Let (s,r) = SqrtRem(a3*b + a2)
10075 : * Let (q,u) = DivRem(r*b + a1, 2*s)
10076 : * Let s = s*b + q
10077 : * Let r = u*b + a0 - q^2
10078 : * If r < 0 Then
10079 : * Let r = r + s
10080 : * Let s = s - 1
10081 : * Let r = r + s
10082 : * Return (s,r)
10083 : *
10084 : * See "Karatsuba Square Root", Paul Zimmermann, INRIA Research Report
10085 : * RR-3805, November 1999. At the time of writing this was available
10086 : * on the net at <https://hal.inria.fr/inria-00072854>.
10087 : *
10088 : * The way to read the assumption "n = a3*b^3 + a2*b^2 + a1*b + a0" is
10089 : * "choose a base b such that n requires at least four base-b digits to
10090 : * express; then those digits are a3,a2,a1,a0, with a3 possibly larger
10091 : * than b". For optimal performance, b should have approximately a
10092 : * quarter the number of digits in the input, so that the outer square
10093 : * root computes roughly twice as many digits as the inner one. For
10094 : * simplicity, we choose b = NBASE^blen, an integer power of NBASE.
10095 : *
10096 : * We implement the algorithm iteratively rather than recursively, to
10097 : * allow the working variables to be reused. With this approach, each
10098 : * digit of the input is read precisely once --- src_idx tracks the number
10099 : * of input digits used so far.
10100 : *
10101 : * The array ndigits[] holds the number of NBASE digits of the input that
10102 : * will have been used at the end of each iteration, which roughly doubles
10103 : * each time. Note that the array elements are stored in reverse order,
10104 : * so if the final iteration requires src_ndigits = 37 input digits, the
10105 : * array will contain [37,19,11,7,5,3], and we would start by computing
10106 : * the square root of the 3 most significant NBASE digits.
10107 : *
10108 : * In each iteration, we choose blen to be the largest integer for which
10109 : * the input number has a3 >= b/4, when written in the form above. In
10110 : * general, this means blen = src_ndigits / 4 (truncated), but if
10111 : * src_ndigits is a multiple of 4, that might lead to the coefficient a3
10112 : * being less than b/4 (if the first input digit is less than NBASE/4), in
10113 : * which case we choose blen = src_ndigits / 4 - 1. The number of digits
10114 : * in the inner square root is then src_ndigits - 2*blen. So, for
10115 : * example, if we have src_ndigits = 26 initially, the array ndigits[]
10116 : * will be either [26,14,8,4] or [26,14,8,6,4], depending on the size of
10117 : * the first input digit.
10118 : *
10119 : * Additionally, we can put an upper bound on the number of steps required
10120 : * as follows --- suppose that the number of source digits is an n-bit
10121 : * number in the range [2^(n-1), 2^n-1], then blen will be in the range
10122 : * [2^(n-3)-1, 2^(n-2)-1] and the number of digits in the inner square
10123 : * root will be in the range [2^(n-2), 2^(n-1)+1]. In the next step, blen
10124 : * will be in the range [2^(n-4)-1, 2^(n-3)] and the number of digits in
10125 : * the next inner square root will be in the range [2^(n-3), 2^(n-2)+1].
10126 : * This pattern repeats, and in the worst case the array ndigits[] will
1107 dean.a.rasheed 10127 EUB : * contain [2^n-1, 2^(n-1)+1, 2^(n-2)+1, ... 9, 5, 3], and the computation
10128 : * will require n steps. Therefore, since all digit array sizes are
10129 : * signed 32-bit integers, the number of steps required is guaranteed to
10130 : * be less than 32.
10131 : * ----------
1107 dean.a.rasheed 10132 ECB : */
1107 dean.a.rasheed 10133 GIC 2085 : step = 0;
1107 dean.a.rasheed 10134 CBC 9981 : while ((ndigits[step] = src_ndigits) > 4)
8866 JanWieck 10135 ECB : {
1107 dean.a.rasheed 10136 : /* Choose b so that a3 >= b/4, as described above */
1107 dean.a.rasheed 10137 GIC 7896 : blen = src_ndigits / 4;
10138 7896 : if (blen * 4 == src_ndigits && arg->digits[0] < NBASE / 4)
10139 162 : blen--;
10140 :
10141 : /* Number of digits in the next step (inner square root) */
10142 7896 : src_ndigits -= 2 * blen;
10143 7896 : step++;
1107 dean.a.rasheed 10144 ECB : }
8866 JanWieck 10145 :
10146 : /*
1107 dean.a.rasheed 10147 : * First iteration (innermost square root and remainder):
10148 : *
10149 : * Here src_ndigits <= 4, and the input fits in an int64. Its square root
10150 : * has at most 9 decimal digits, so estimate it using double precision
10151 : * arithmetic, which will in fact almost certainly return the correct
10152 : * result with no further correction required.
10153 : */
1107 dean.a.rasheed 10154 CBC 2085 : arg_int64 = arg->digits[0];
10155 6657 : for (src_idx = 1; src_idx < src_ndigits; src_idx++)
10156 : {
10157 4572 : arg_int64 *= NBASE;
10158 4572 : if (src_idx < arg->ndigits)
10159 3843 : arg_int64 += arg->digits[src_idx];
10160 : }
10161 :
1107 dean.a.rasheed 10162 GIC 2085 : s_int64 = (int64) sqrt((double) arg_int64);
10163 2085 : r_int64 = arg_int64 - s_int64 * s_int64;
10164 :
10165 : /*
10166 : * Use Newton's method to correct the result, if necessary.
10167 : *
10168 : * This uses integer division with truncation to compute the truncated
10169 : * integer square root by iterating using the formula x -> (x + n/x) / 2.
10170 : * This is known to converge to isqrt(n), unless n+1 is a perfect square.
1107 dean.a.rasheed 10171 ECB : * If n+1 is a perfect square, the sequence will oscillate between the two
10172 : * values isqrt(n) and isqrt(n)+1, so we can be assured of convergence by
10173 : * checking the remainder.
10174 : */
1107 dean.a.rasheed 10175 GIC 2085 : while (r_int64 < 0 || r_int64 > 2 * s_int64)
1107 dean.a.rasheed 10176 ECB : {
1107 dean.a.rasheed 10177 UIC 0 : s_int64 = (s_int64 + arg_int64 / s_int64) / 2;
1107 dean.a.rasheed 10178 LBC 0 : r_int64 = arg_int64 - s_int64 * s_int64;
10179 : }
1107 dean.a.rasheed 10180 ECB :
10181 : /*
10182 : * Iterations with src_ndigits <= 8:
10183 : *
10184 : * The next 1 or 2 iterations compute larger (outer) square roots with
10185 : * src_ndigits <= 8, so the result still fits in an int64 (even though the
10186 : * input no longer does) and we can continue to compute using int64
10187 : * variables to avoid more expensive numeric computations.
10188 : *
10189 : * It is fairly easy to see that there is no risk of the intermediate
10190 : * values below overflowing 64-bit integers. In the worst case, the
10191 : * previous iteration will have computed a 3-digit square root (of a
10192 : * 6-digit input less than NBASE^6 / 4), so at the start of this
10193 : * iteration, s will be less than NBASE^3 / 2 = 10^12 / 2, and r will be
10194 : * less than 10^12. In this case, blen will be 1, so numer will be less
10195 : * than 10^17, and denom will be less than 10^12 (and hence u will also be
10196 : * less than 10^12). Finally, since q^2 = u*b + a0 - r, we can also be
10197 : * sure that q^2 < 10^17. Therefore all these quantities fit comfortably
10198 : * in 64-bit integers.
10199 : */
1107 dean.a.rasheed 10200 CBC 2085 : step--;
10201 5283 : while (step >= 0 && (src_ndigits = ndigits[step]) <= 8)
1107 dean.a.rasheed 10202 ECB : {
10203 : int b;
10204 : int a0;
10205 : int a1;
10206 : int i;
10207 : int64 numer;
10208 : int64 denom;
10209 : int64 q;
1107 dean.a.rasheed 10210 EUB : int64 u;
10211 :
1107 dean.a.rasheed 10212 GIC 3198 : blen = (src_ndigits - src_idx) / 2;
1107 dean.a.rasheed 10213 ECB :
10214 : /* Extract a1 and a0, and compute b */
1107 dean.a.rasheed 10215 GIC 3198 : a0 = 0;
10216 3198 : a1 = 0;
10217 3198 : b = 1;
10218 :
10219 6468 : for (i = 0; i < blen; i++, src_idx++)
10220 : {
10221 3270 : b *= NBASE;
10222 3270 : a1 *= NBASE;
10223 3270 : if (src_idx < arg->ndigits)
1107 dean.a.rasheed 10224 CBC 2400 : a1 += arg->digits[src_idx];
10225 : }
10226 :
1107 dean.a.rasheed 10227 GIC 6468 : for (i = 0; i < blen; i++, src_idx++)
10228 : {
10229 3270 : a0 *= NBASE;
10230 3270 : if (src_idx < arg->ndigits)
10231 2322 : a0 += arg->digits[src_idx];
10232 : }
10233 :
10234 : /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
10235 3198 : numer = r_int64 * b + a1;
10236 3198 : denom = 2 * s_int64;
10237 3198 : q = numer / denom;
10238 3198 : u = numer - q * denom;
10239 :
10240 : /* Compute s = s*b + q and r = u*b + a0 - q^2 */
10241 3198 : s_int64 = s_int64 * b + q;
10242 3198 : r_int64 = u * b + a0 - q * q;
10243 :
1107 dean.a.rasheed 10244 CBC 3198 : if (r_int64 < 0)
1107 dean.a.rasheed 10245 ECB : {
10246 : /* s is too large by 1; set r += s, s--, r += s */
1107 dean.a.rasheed 10247 GIC 105 : r_int64 += s_int64;
1107 dean.a.rasheed 10248 CBC 105 : s_int64--;
10249 105 : r_int64 += s_int64;
10250 : }
1107 dean.a.rasheed 10251 ECB :
1107 dean.a.rasheed 10252 CBC 3198 : Assert(src_idx == src_ndigits); /* All input digits consumed */
1107 dean.a.rasheed 10253 GIC 3198 : step--;
10254 : }
10255 :
1107 dean.a.rasheed 10256 ECB : /*
10257 : * On platforms with 128-bit integer support, we can further delay the
10258 : * need to use numeric variables.
10259 : */
10260 : #ifdef HAVE_INT128
1107 dean.a.rasheed 10261 CBC 2085 : if (step >= 0)
10262 : {
1107 dean.a.rasheed 10263 ECB : int128 s_int128;
10264 : int128 r_int128;
10265 :
1107 dean.a.rasheed 10266 GIC 2085 : s_int128 = s_int64;
10267 2085 : r_int128 = r_int64;
10268 :
10269 : /*
10270 : * Iterations with src_ndigits <= 16:
10271 : *
1107 dean.a.rasheed 10272 ECB : * The result fits in an int128 (even though the input doesn't) so we
10273 : * use int128 variables to avoid more expensive numeric computations.
10274 : */
1107 dean.a.rasheed 10275 GIC 4524 : while (step >= 0 && (src_ndigits = ndigits[step]) <= 16)
10276 : {
1107 dean.a.rasheed 10277 ECB : int64 b;
10278 : int64 a0;
10279 : int64 a1;
10280 : int64 i;
10281 : int128 numer;
10282 : int128 denom;
10283 : int128 q;
10284 : int128 u;
10285 :
1107 dean.a.rasheed 10286 GIC 2439 : blen = (src_ndigits - src_idx) / 2;
10287 :
10288 : /* Extract a1 and a0, and compute b */
10289 2439 : a0 = 0;
10290 2439 : a1 = 0;
10291 2439 : b = 1;
10292 :
1107 dean.a.rasheed 10293 CBC 8040 : for (i = 0; i < blen; i++, src_idx++)
10294 : {
1107 dean.a.rasheed 10295 GIC 5601 : b *= NBASE;
10296 5601 : a1 *= NBASE;
1107 dean.a.rasheed 10297 CBC 5601 : if (src_idx < arg->ndigits)
1107 dean.a.rasheed 10298 GIC 3303 : a1 += arg->digits[src_idx];
10299 : }
10300 :
10301 8040 : for (i = 0; i < blen; i++, src_idx++)
10302 : {
10303 5601 : a0 *= NBASE;
10304 5601 : if (src_idx < arg->ndigits)
1107 dean.a.rasheed 10305 CBC 2235 : a0 += arg->digits[src_idx];
10306 : }
1107 dean.a.rasheed 10307 ECB :
10308 : /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
1107 dean.a.rasheed 10309 CBC 2439 : numer = r_int128 * b + a1;
1107 dean.a.rasheed 10310 GIC 2439 : denom = 2 * s_int128;
1107 dean.a.rasheed 10311 CBC 2439 : q = numer / denom;
10312 2439 : u = numer - q * denom;
10313 :
10314 : /* Compute s = s*b + q and r = u*b + a0 - q^2 */
1107 dean.a.rasheed 10315 GIC 2439 : s_int128 = s_int128 * b + q;
10316 2439 : r_int128 = u * b + a0 - q * q;
10317 :
10318 2439 : if (r_int128 < 0)
10319 : {
10320 : /* s is too large by 1; set r += s, s--, r += s */
10321 96 : r_int128 += s_int128;
1107 dean.a.rasheed 10322 CBC 96 : s_int128--;
1107 dean.a.rasheed 10323 GIC 96 : r_int128 += s_int128;
10324 : }
10325 :
10326 2439 : Assert(src_idx == src_ndigits); /* All input digits consumed */
10327 2439 : step--;
1107 dean.a.rasheed 10328 ECB : }
10329 :
10330 : /*
10331 : * All remaining iterations require numeric variables. Convert the
10332 : * integer values to NumericVar and continue. Note that in the final
10333 : * iteration we don't need the remainder, so we can save a few cycles
10334 : * there by not fully computing it.
10335 : */
1107 dean.a.rasheed 10336 CBC 2085 : int128_to_numericvar(s_int128, &s_var);
1107 dean.a.rasheed 10337 GIC 2085 : if (step >= 0)
10338 1362 : int128_to_numericvar(r_int128, &r_var);
1107 dean.a.rasheed 10339 ECB : }
10340 : else
10341 : {
1107 dean.a.rasheed 10342 UIC 0 : int64_to_numericvar(s_int64, &s_var);
10343 : /* step < 0, so we certainly don't need r */
10344 : }
10345 : #else /* !HAVE_INT128 */
10346 : int64_to_numericvar(s_int64, &s_var);
1107 dean.a.rasheed 10347 ECB : if (step >= 0)
10348 : int64_to_numericvar(r_int64, &r_var);
10349 : #endif /* HAVE_INT128 */
1107 dean.a.rasheed 10350 EUB :
10351 : /*
10352 : * The remaining iterations with src_ndigits > 8 (or 16, if have int128)
10353 : * use numeric variables.
10354 : */
1107 dean.a.rasheed 10355 GIC 4344 : while (step >= 0)
10356 : {
1107 dean.a.rasheed 10357 EUB : int tmp_len;
8866 JanWieck 10358 :
1107 dean.a.rasheed 10359 GIC 2259 : src_ndigits = ndigits[step];
10360 2259 : blen = (src_ndigits - src_idx) / 2;
10361 :
1107 dean.a.rasheed 10362 ECB : /* Extract a1 and a0 */
1107 dean.a.rasheed 10363 GIC 2259 : if (src_idx < arg->ndigits)
10364 : {
1107 dean.a.rasheed 10365 GBC 756 : tmp_len = Min(blen, arg->ndigits - src_idx);
1107 dean.a.rasheed 10366 GIC 756 : alloc_var(&a1_var, tmp_len);
1107 dean.a.rasheed 10367 GBC 756 : memcpy(a1_var.digits, arg->digits + src_idx,
1107 dean.a.rasheed 10368 EUB : tmp_len * sizeof(NumericDigit));
1107 dean.a.rasheed 10369 GIC 756 : a1_var.weight = blen - 1;
10370 756 : a1_var.sign = NUMERIC_POS;
10371 756 : a1_var.dscale = 0;
1107 dean.a.rasheed 10372 GBC 756 : strip_var(&a1_var);
1107 dean.a.rasheed 10373 EUB : }
10374 : else
10375 : {
1107 dean.a.rasheed 10376 GIC 1503 : zero_var(&a1_var);
1107 dean.a.rasheed 10377 CBC 1503 : a1_var.dscale = 0;
1107 dean.a.rasheed 10378 ECB : }
1107 dean.a.rasheed 10379 GIC 2259 : src_idx += blen;
1107 dean.a.rasheed 10380 ECB :
1107 dean.a.rasheed 10381 CBC 2259 : if (src_idx < arg->ndigits)
1107 dean.a.rasheed 10382 ECB : {
1107 dean.a.rasheed 10383 GIC 756 : tmp_len = Min(blen, arg->ndigits - src_idx);
10384 756 : alloc_var(&a0_var, tmp_len);
10385 756 : memcpy(a0_var.digits, arg->digits + src_idx,
10386 : tmp_len * sizeof(NumericDigit));
10387 756 : a0_var.weight = blen - 1;
10388 756 : a0_var.sign = NUMERIC_POS;
10389 756 : a0_var.dscale = 0;
10390 756 : strip_var(&a0_var);
10391 : }
1107 dean.a.rasheed 10392 ECB : else
10393 : {
1107 dean.a.rasheed 10394 GIC 1503 : zero_var(&a0_var);
10395 1503 : a0_var.dscale = 0;
1107 dean.a.rasheed 10396 ECB : }
1107 dean.a.rasheed 10397 CBC 2259 : src_idx += blen;
10398 :
1107 dean.a.rasheed 10399 ECB : /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
1107 dean.a.rasheed 10400 GIC 2259 : set_var_from_var(&r_var, &q_var);
1107 dean.a.rasheed 10401 CBC 2259 : q_var.weight += blen;
10402 2259 : add_var(&q_var, &a1_var, &q_var);
1107 dean.a.rasheed 10403 GIC 2259 : add_var(&s_var, &s_var, &u_var);
1107 dean.a.rasheed 10404 CBC 2259 : div_mod_var(&q_var, &u_var, &q_var, &u_var);
1107 dean.a.rasheed 10405 ECB :
10406 : /* Compute s = s*b + q */
1107 dean.a.rasheed 10407 GIC 2259 : s_var.weight += blen;
10408 2259 : add_var(&s_var, &q_var, &s_var);
10409 :
10410 : /*
10411 : * Compute r = u*b + a0 - q^2.
10412 : *
10413 : * In the final iteration, we don't actually need r; we just need to
10414 : * know whether it is negative, so that we know whether to adjust s.
10415 : * So instead of the final subtraction we can just compare.
1107 dean.a.rasheed 10416 ECB : */
1107 dean.a.rasheed 10417 GIC 2259 : u_var.weight += blen;
10418 2259 : add_var(&u_var, &a0_var, &u_var);
10419 2259 : mul_var(&q_var, &q_var, &q_var, 0);
1107 dean.a.rasheed 10420 ECB :
1107 dean.a.rasheed 10421 CBC 2259 : if (step > 0)
10422 : {
1107 dean.a.rasheed 10423 ECB : /* Need r for later iterations */
1107 dean.a.rasheed 10424 GIC 897 : sub_var(&u_var, &q_var, &r_var);
1107 dean.a.rasheed 10425 CBC 897 : if (r_var.sign == NUMERIC_NEG)
1107 dean.a.rasheed 10426 ECB : {
10427 : /* s is too large by 1; set r += s, s--, r += s */
1107 dean.a.rasheed 10428 CBC 60 : add_var(&r_var, &s_var, &r_var);
10429 60 : sub_var(&s_var, &const_one, &s_var);
10430 60 : add_var(&r_var, &s_var, &r_var);
10431 : }
10432 : }
10433 : else
10434 : {
10435 : /* Don't need r anymore, except to test if s is too large by 1 */
1107 dean.a.rasheed 10436 GIC 1362 : if (cmp_var(&u_var, &q_var) < 0)
10437 18 : sub_var(&s_var, &const_one, &s_var);
10438 : }
1107 dean.a.rasheed 10439 ECB :
1107 dean.a.rasheed 10440 GIC 2259 : Assert(src_idx == src_ndigits); /* All input digits consumed */
10441 2259 : step--;
10442 : }
10443 :
10444 : /*
10445 : * Construct the final result, rounding it to the requested precision.
1107 dean.a.rasheed 10446 ECB : */
1107 dean.a.rasheed 10447 GIC 2085 : set_var_from_var(&s_var, result);
10448 2085 : result->weight = res_weight;
10449 2085 : result->sign = NUMERIC_POS;
10450 :
10451 : /* Round to target rscale (and set result->dscale) */
7324 tgl 10452 2085 : round_var(result, rscale);
10453 :
1107 dean.a.rasheed 10454 ECB : /* Strip leading and trailing zeroes */
1107 dean.a.rasheed 10455 CBC 2085 : strip_var(result);
10456 :
10457 2085 : free_var(&s_var);
1107 dean.a.rasheed 10458 GIC 2085 : free_var(&r_var);
1107 dean.a.rasheed 10459 CBC 2085 : free_var(&a0_var);
10460 2085 : free_var(&a1_var);
1107 dean.a.rasheed 10461 GIC 2085 : free_var(&q_var);
10462 2085 : free_var(&u_var);
10463 : }
10464 :
10465 :
10466 : /*
8866 JanWieck 10467 ECB : * exp_var() -
10468 : *
2703 tgl 10469 : * Raise e to the power of x, computed to rscale fractional digits
8866 JanWieck 10470 : */
10471 : static void
2037 andres 10472 CBC 90 : exp_var(const NumericVar *arg, NumericVar *result, int rscale)
10473 : {
10474 : NumericVar x;
2703 tgl 10475 ECB : NumericVar elem;
406 dean.a.rasheed 10476 : int ni;
10477 : double val;
10478 : int dweight;
2703 tgl 10479 : int ndiv2;
10480 : int sig_digits;
10481 : int local_rscale;
10482 :
8866 JanWieck 10483 GIC 90 : init_var(&x);
2703 tgl 10484 90 : init_var(&elem);
8866 JanWieck 10485 ECB :
8866 JanWieck 10486 GIC 90 : set_var_from_var(arg, &x);
8866 JanWieck 10487 ECB :
2703 tgl 10488 : /*
10489 : * Estimate the dweight of the result using floating point arithmetic, so
10490 : * that we can choose an appropriate local rscale for the calculation.
10491 : */
2703 tgl 10492 GIC 90 : val = numericvar_to_double_no_overflow(&x);
8866 JanWieck 10493 ECB :
617 dean.a.rasheed 10494 : /* Guard against overflow/underflow */
10495 : /* If you change this limit, see also power_var()'s limit */
184 peter 10496 GNC 90 : if (fabs(val) >= NUMERIC_MAX_RESULT_SCALE * 3)
617 dean.a.rasheed 10497 ECB : {
617 dean.a.rasheed 10498 GIC 3 : if (val > 0)
617 dean.a.rasheed 10499 UIC 0 : ereport(ERROR,
10500 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
10501 : errmsg("value overflows numeric format")));
617 dean.a.rasheed 10502 GIC 3 : zero_var(result);
10503 3 : result->dscale = rscale;
10504 3 : return;
10505 : }
10506 :
10507 : /* decimal weight = log10(e^x) = x * log10(e) */
2703 tgl 10508 87 : dweight = (int) (val * 0.434294481903252);
8866 JanWieck 10509 ECB :
10510 : /*
10511 : * Reduce x to the range -0.01 <= x <= 0.01 (approximately) by dividing by
10512 : * 2^ndiv2, to improve the convergence rate of the Taylor series.
10513 : *
10514 : * Note that the overflow check above ensures that fabs(x) < 6000, which
10515 : * means that ndiv2 <= 20 here.
10516 : */
184 peter 10517 GNC 87 : if (fabs(val) > 0.01)
10518 : {
2703 tgl 10519 GIC 72 : ndiv2 = 1;
10520 72 : val /= 2;
10521 :
184 peter 10522 GNC 909 : while (fabs(val) > 0.01)
10523 : {
2703 tgl 10524 GIC 837 : ndiv2++;
10525 837 : val /= 2;
10526 : }
10527 :
10528 72 : local_rscale = x.dscale + ndiv2;
406 dean.a.rasheed 10529 CBC 72 : div_var_int(&x, 1 << ndiv2, 0, &x, local_rscale, true);
2703 tgl 10530 ECB : }
10531 : else
2703 tgl 10532 CBC 15 : ndiv2 = 0;
7324 tgl 10533 ECB :
2703 10534 : /*
10535 : * Set the scale for the Taylor series expansion. The final result has
10536 : * (dweight + rscale + 1) significant digits. In addition, we have to
10537 : * raise the Taylor series result to the power 2^ndiv2, which introduces
10538 : * an error of up to around log10(2^ndiv2) digits, so work with this many
10539 : * extra digits of precision (plus a few more for good measure).
10540 : */
2703 tgl 10541 CBC 87 : sig_digits = 1 + dweight + rscale + (int) (ndiv2 * 0.301029995663981);
10542 87 : sig_digits = Max(sig_digits, 0) + 8;
10543 :
2703 tgl 10544 GIC 87 : local_rscale = sig_digits - 1;
10545 :
7494 tgl 10546 ECB : /*
10547 : * Use the Taylor series
10548 : *
7188 bruce 10549 : * exp(x) = 1 + x + x^2/2! + x^3/3! + ...
7494 tgl 10550 : *
6347 bruce 10551 : * Given the limited range of x, this should converge reasonably quickly.
10552 : * We run the series until the terms fall below the local_rscale limit.
10553 : */
8866 JanWieck 10554 GIC 87 : add_var(&const_one, &x, result);
10555 :
2703 tgl 10556 87 : mul_var(&x, &x, &elem, local_rscale);
406 dean.a.rasheed 10557 CBC 87 : ni = 2;
10558 87 : div_var_int(&elem, ni, 0, &elem, local_rscale, true);
10559 :
2703 tgl 10560 2496 : while (elem.ndigits != 0)
10561 : {
8866 JanWieck 10562 GIC 2409 : add_var(result, &elem, result);
10563 :
2703 tgl 10564 2409 : mul_var(&elem, &x, &elem, local_rscale);
406 dean.a.rasheed 10565 2409 : ni++;
10566 2409 : div_var_int(&elem, ni, 0, &elem, local_rscale, true);
10567 : }
8866 JanWieck 10568 ECB :
2703 tgl 10569 : /*
10570 : * Compensate for the argument range reduction. Since the weight of the
2703 tgl 10571 EUB : * result doubles with each multiplication, we can reduce the local rscale
2703 tgl 10572 ECB : * as we proceed.
10573 : */
8866 JanWieck 10574 GIC 996 : while (ndiv2-- > 0)
10575 : {
2703 tgl 10576 909 : local_rscale = sig_digits - result->weight * 2 * DEC_DIGITS;
10577 909 : local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
7324 10578 909 : mul_var(result, result, result, local_rscale);
10579 : }
2703 tgl 10580 ECB :
10581 : /* Round to requested rscale */
2703 tgl 10582 GIC 87 : round_var(result, rscale);
10583 :
8866 JanWieck 10584 87 : free_var(&x);
10585 87 : free_var(&elem);
10586 : }
10587 :
10588 :
10589 : /*
10590 : * Estimate the dweight of the most significant decimal digit of the natural
10591 : * logarithm of a number.
10592 : *
10593 : * Essentially, we're approximating log10(abs(ln(var))). This is used to
10594 : * determine the appropriate rscale when computing natural logarithms.
10595 : *
10596 : * Note: many callers call this before range-checking the input. Therefore,
10597 : * we must be robust against values that are invalid to apply ln() to.
10598 : * We don't wish to throw an error here, so just return zero in such cases.
10599 : */
10600 : static int
2037 andres 10601 369 : estimate_ln_dweight(const NumericVar *var)
10602 : {
10603 : int ln_dweight;
10604 :
10605 : /* Caller should fail on ln(negative), but for the moment return zero */
402 tgl 10606 369 : if (var->sign != NUMERIC_POS)
10607 21 : return 0;
10608 :
2703 10609 657 : if (cmp_var(var, &const_zero_point_nine) >= 0 &&
10610 309 : cmp_var(var, &const_one_point_one) <= 0)
10611 45 : {
10612 : /*
10613 : * 0.9 <= var <= 1.1
10614 : *
10615 : * ln(var) has a negative weight (possibly very large). To get a
10616 : * reasonably accurate result, estimate it using ln(1+x) ~= x.
10617 : */
10618 : NumericVar x;
10619 :
10620 45 : init_var(&x);
10621 45 : sub_var(var, &const_one, &x);
10622 :
10623 45 : if (x.ndigits > 0)
10624 : {
10625 : /* Use weight of most significant decimal digit of x */
10626 21 : ln_dweight = x.weight * DEC_DIGITS + (int) log10(x.digits[0]);
10627 : }
10628 : else
10629 : {
10630 : /* x = 0. Since ln(1) = 0 exactly, we don't need extra digits */
10631 24 : ln_dweight = 0;
10632 : }
10633 :
10634 45 : free_var(&x);
10635 : }
10636 : else
10637 : {
10638 : /*
10639 : * Estimate the logarithm using the first couple of digits from the
10640 : * input number. This will give an accurate result whenever the input
10641 : * is not too close to 1.
10642 : */
10643 303 : if (var->ndigits > 0)
10644 : {
10645 : int digits;
10646 : int dweight;
10647 : double ln_var;
10648 :
10649 282 : digits = var->digits[0];
2703 tgl 10650 CBC 282 : dweight = var->weight * DEC_DIGITS;
2703 tgl 10651 ECB :
2703 tgl 10652 GIC 282 : if (var->ndigits > 1)
10653 : {
2703 tgl 10654 CBC 171 : digits = digits * NBASE + var->digits[1];
10655 171 : dweight -= DEC_DIGITS;
2703 tgl 10656 ECB : }
10657 :
10658 : /*----------
10659 : * We have var ~= digits * 10^dweight
10660 : * so ln(var) ~= ln(digits) + dweight * ln(10)
10661 : *----------
10662 : */
2703 tgl 10663 GIC 282 : ln_var = log((double) digits) + dweight * 2.302585092994046;
184 peter 10664 GNC 282 : ln_dweight = (int) log10(fabs(ln_var));
10665 : }
10666 : else
10667 : {
10668 : /* Caller should fail on ln(0), but for the moment return zero */
2703 tgl 10669 GIC 21 : ln_dweight = 0;
10670 : }
2703 tgl 10671 ECB : }
10672 :
2703 tgl 10673 GIC 348 : return ln_dweight;
2703 tgl 10674 ECB : }
10675 :
10676 :
10677 : /*
10678 : * ln_var() -
8866 JanWieck 10679 : *
10680 : * Compute the natural log of x
10681 : */
10682 : static void
2037 andres 10683 GIC 417 : ln_var(const NumericVar *arg, NumericVar *result, int rscale)
10684 : {
10685 : NumericVar x;
10686 : NumericVar xx;
10687 : int ni;
10688 : NumericVar elem;
10689 : NumericVar fact;
10690 : int nsqrt;
10691 : int local_rscale;
6902 neilc 10692 ECB : int cmp;
10693 :
6902 neilc 10694 GBC 417 : cmp = cmp_var(arg, &const_zero);
10695 417 : if (cmp == 0)
7196 tgl 10696 GIC 21 : ereport(ERROR,
10697 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
10698 : errmsg("cannot take logarithm of zero")));
6902 neilc 10699 396 : else if (cmp < 0)
10700 18 : ereport(ERROR,
10701 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
10702 : errmsg("cannot take logarithm of a negative number")));
10703 :
8866 JanWieck 10704 378 : init_var(&x);
10705 378 : init_var(&xx);
10706 378 : init_var(&elem);
10707 378 : init_var(&fact);
10708 :
10709 378 : set_var_from_var(arg, &x);
7324 tgl 10710 378 : set_var_from_var(&const_two, &fact);
10711 :
10712 : /*
10713 : * Reduce input into range 0.9 < x < 1.1 with repeated sqrt() operations.
10714 : *
10715 : * The final logarithm will have up to around rscale+6 significant digits.
10716 : * Each sqrt() will roughly halve the weight of x, so adjust the local
2703 tgl 10717 ECB : * rscale as we work so that we keep this many significant digits at each
10718 : * step (plus a few more for good measure).
10719 : *
10720 : * Note that we allow local_rscale < 0 during this input reduction
10721 : * process, which implies rounding before the decimal point. sqrt_var()
10722 : * explicitly supports this, and it significantly reduces the work
10723 : * required to reduce very large inputs to the required range. Once the
10724 : * input reduction is complete, x.weight will be 0 and its display scale
10725 : * will be non-negative again.
10726 : */
1134 dean.a.rasheed 10727 GIC 378 : nsqrt = 0;
7494 tgl 10728 534 : while (cmp_var(&x, &const_zero_point_nine) <= 0)
8866 JanWieck 10729 ECB : {
2703 tgl 10730 GIC 156 : local_rscale = rscale - x.weight * DEC_DIGITS / 2 + 8;
7324 10731 156 : sqrt_var(&x, &x, local_rscale);
7324 tgl 10732 CBC 156 : mul_var(&fact, &const_two, &fact, 0);
1134 dean.a.rasheed 10733 156 : nsqrt++;
8866 JanWieck 10734 ECB : }
7494 tgl 10735 GIC 2064 : while (cmp_var(&x, &const_one_point_one) >= 0)
8866 JanWieck 10736 ECB : {
2703 tgl 10737 GIC 1686 : local_rscale = rscale - x.weight * DEC_DIGITS / 2 + 8;
7324 tgl 10738 CBC 1686 : sqrt_var(&x, &x, local_rscale);
10739 1686 : mul_var(&fact, &const_two, &fact, 0);
1134 dean.a.rasheed 10740 1686 : nsqrt++;
8866 JanWieck 10741 ECB : }
10742 :
10743 : /*
7494 tgl 10744 : * We use the Taylor series for 0.5 * ln((1+z)/(1-z)),
10745 : *
7188 bruce 10746 : * z + z^3/3 + z^5/5 + ...
7494 tgl 10747 : *
6347 bruce 10748 : * where z = (x-1)/(x+1) is in the range (approximately) -0.053 .. 0.048
10749 : * due to the above range-reduction of x.
10750 : *
10751 : * The convergence of this is not as fast as one would like, but is
10752 : * tolerable given that z is small.
1134 dean.a.rasheed 10753 : *
10754 : * The Taylor series result will be multiplied by 2^(nsqrt+1), which has a
10755 : * decimal weight of (nsqrt+1) * log10(2), so work with this many extra
10756 : * digits of precision (plus a few more for good measure).
10757 : */
1134 dean.a.rasheed 10758 CBC 378 : local_rscale = rscale + (int) ((nsqrt + 1) * 0.301029995663981) + 8;
2703 tgl 10759 ECB :
8866 JanWieck 10760 GIC 378 : sub_var(&x, &const_one, result);
8866 JanWieck 10761 CBC 378 : add_var(&x, &const_one, &elem);
5483 tgl 10762 GIC 378 : div_var_fast(result, &elem, result, local_rscale, true);
8866 JanWieck 10763 378 : set_var_from_var(result, &xx);
7324 tgl 10764 CBC 378 : mul_var(result, result, &x, local_rscale);
8866 JanWieck 10765 ECB :
406 dean.a.rasheed 10766 CBC 378 : ni = 1;
10767 :
10768 : for (;;)
8866 JanWieck 10769 ECB : {
406 dean.a.rasheed 10770 CBC 7011 : ni += 2;
7324 tgl 10771 GIC 7011 : mul_var(&xx, &x, &xx, local_rscale);
406 dean.a.rasheed 10772 7011 : div_var_int(&xx, ni, 0, &elem, local_rscale, true);
10773 :
7494 tgl 10774 7011 : if (elem.ndigits == 0)
8866 JanWieck 10775 378 : break;
10776 :
10777 6633 : add_var(result, &elem, result);
7331 tgl 10778 ECB :
7188 bruce 10779 GIC 6633 : if (elem.weight < (result->weight - local_rscale * 2 / DEC_DIGITS))
7331 tgl 10780 UIC 0 : break;
10781 : }
10782 :
7324 tgl 10783 ECB : /* Compensate for argument range reduction, round to requested rscale */
7324 tgl 10784 CBC 378 : mul_var(result, &fact, result, rscale);
10785 :
8866 JanWieck 10786 GIC 378 : free_var(&x);
10787 378 : free_var(&xx);
10788 378 : free_var(&elem);
10789 378 : free_var(&fact);
10790 378 : }
10791 :
8866 JanWieck 10792 ECB :
10793 : /*
10794 : * log_var() -
10795 : *
10796 : * Compute the logarithm of num in a given base.
10797 : *
10798 : * Note: this routine chooses dscale of the result.
10799 : */
10800 : static void
2037 andres 10801 GIC 108 : log_var(const NumericVar *base, const NumericVar *num, NumericVar *result)
10802 : {
8866 JanWieck 10803 ECB : NumericVar ln_base;
10804 : NumericVar ln_num;
10805 : int ln_base_dweight;
2703 tgl 10806 : int ln_num_dweight;
10807 : int result_dweight;
7324 10808 : int rscale;
10809 : int ln_base_rscale;
2703 10810 : int ln_num_rscale;
10811 :
8866 JanWieck 10812 CBC 108 : init_var(&ln_base);
10813 108 : init_var(&ln_num);
8866 JanWieck 10814 ECB :
2703 tgl 10815 : /* Estimated dweights of ln(base), ln(num) and the final result */
2703 tgl 10816 GIC 108 : ln_base_dweight = estimate_ln_dweight(base);
10817 108 : ln_num_dweight = estimate_ln_dweight(num);
2703 tgl 10818 CBC 108 : result_dweight = ln_num_dweight - ln_base_dweight;
10819 :
2703 tgl 10820 ECB : /*
10821 : * Select the scale of the result so that it will have at least
10822 : * NUMERIC_MIN_SIG_DIGITS significant digits and is not less than either
10823 : * input's display scale.
10824 : */
2703 tgl 10825 GIC 108 : rscale = NUMERIC_MIN_SIG_DIGITS - result_dweight;
7324 tgl 10826 CBC 108 : rscale = Max(rscale, base->dscale);
10827 108 : rscale = Max(rscale, num->dscale);
10828 108 : rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
10829 108 : rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
10830 :
10831 : /*
2703 tgl 10832 ECB : * Set the scales for ln(base) and ln(num) so that they each have more
10833 : * significant digits than the final result.
10834 : */
2703 tgl 10835 CBC 108 : ln_base_rscale = rscale + result_dweight - ln_base_dweight + 8;
2703 tgl 10836 GIC 108 : ln_base_rscale = Max(ln_base_rscale, NUMERIC_MIN_DISPLAY_SCALE);
10837 :
2703 tgl 10838 CBC 108 : ln_num_rscale = rscale + result_dweight - ln_num_dweight + 8;
10839 108 : ln_num_rscale = Max(ln_num_rscale, NUMERIC_MIN_DISPLAY_SCALE);
7494 tgl 10840 ECB :
10841 : /* Form natural logarithms */
2703 tgl 10842 GIC 108 : ln_var(base, &ln_base, ln_base_rscale);
2703 tgl 10843 CBC 96 : ln_var(num, &ln_num, ln_num_rscale);
8720 bruce 10844 ECB :
10845 : /* Divide and round to the required scale */
5483 tgl 10846 GIC 81 : div_var_fast(&ln_num, &ln_base, result, rscale, true);
10847 :
8866 JanWieck 10848 78 : free_var(&ln_num);
10849 78 : free_var(&ln_base);
10850 78 : }
10851 :
10852 :
7324 tgl 10853 ECB : /*
8866 JanWieck 10854 : * power_var() -
10855 : *
10856 : * Raise base to the power of exp
10857 : *
10858 : * Note: this routine chooses dscale of the result.
8866 JanWieck 10859 EUB : */
10860 : static void
2037 andres 10861 GIC 570 : power_var(const NumericVar *base, const NumericVar *exp, NumericVar *result)
10862 : {
10863 : int res_sign;
10864 : NumericVar abs_base;
10865 : NumericVar ln_base;
10866 : NumericVar ln_num;
10867 : int ln_dweight;
10868 : int rscale;
10869 : int sig_digits;
10870 : int local_rscale;
10871 : double val;
8866 JanWieck 10872 ECB :
10873 : /* If exp can be represented as an integer, use power_var_int */
7324 tgl 10874 GIC 570 : if (exp->ndigits == 0 || exp->ndigits <= exp->weight + 1)
10875 : {
7324 tgl 10876 ECB : /* exact integer, but does it fit in int? */
10877 : int64 expval64;
10878 :
2942 andres 10879 GIC 507 : if (numericvar_to_int64(exp, &expval64))
7324 tgl 10880 ECB : {
611 dean.a.rasheed 10881 GIC 504 : if (expval64 >= PG_INT32_MIN && expval64 <= PG_INT32_MAX)
7324 tgl 10882 ECB : {
10883 : /* Okay, use power_var_int */
171 dean.a.rasheed 10884 GNC 489 : power_var_int(base, (int) expval64, exp->dscale, result);
7324 tgl 10885 GIC 483 : return;
10886 : }
10887 : }
7324 tgl 10888 ECB : }
10889 :
10890 : /*
2703 10891 : * This avoids log(0) for cases of 0 raised to a non-integer. 0 ^ 0 is
10892 : * handled by power_var_int().
5449 bruce 10893 : */
5449 bruce 10894 GIC 81 : if (cmp_var(base, &const_zero) == 0)
5449 bruce 10895 ECB : {
5449 bruce 10896 CBC 9 : set_var_from_var(&const_zero, result);
2118 tgl 10897 9 : result->dscale = NUMERIC_MIN_SIG_DIGITS; /* no need to round */
5449 bruce 10898 GIC 9 : return;
5449 bruce 10899 ECB : }
5050 10900 :
617 dean.a.rasheed 10901 CBC 72 : init_var(&abs_base);
8866 JanWieck 10902 72 : init_var(&ln_base);
8866 JanWieck 10903 GIC 72 : init_var(&ln_num);
10904 :
10905 : /*
617 dean.a.rasheed 10906 ECB : * If base is negative, insist that exp be an integer. The result is then
10907 : * positive if exp is even and negative if exp is odd.
10908 : */
617 dean.a.rasheed 10909 CBC 72 : if (base->sign == NUMERIC_NEG)
10910 : {
10911 : /*
617 dean.a.rasheed 10912 ECB : * Check that exp is an integer. This error code is defined by the
10913 : * SQL standard, and matches other errors in numeric_power().
10914 : */
617 dean.a.rasheed 10915 CBC 18 : if (exp->ndigits > 0 && exp->ndigits > exp->weight + 1)
10916 9 : ereport(ERROR,
10917 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
10918 : errmsg("a negative number raised to a non-integer power yields a complex result")));
617 dean.a.rasheed 10919 ECB :
10920 : /* Test if exp is odd or even */
617 dean.a.rasheed 10921 GIC 9 : if (exp->ndigits > 0 && exp->ndigits == exp->weight + 1 &&
10922 6 : (exp->digits[exp->ndigits - 1] & 1))
10923 3 : res_sign = NUMERIC_NEG;
10924 : else
10925 6 : res_sign = NUMERIC_POS;
10926 :
10927 : /* Then work with abs(base) below */
10928 9 : set_var_from_var(base, &abs_base);
617 dean.a.rasheed 10929 CBC 9 : abs_base.sign = NUMERIC_POS;
10930 9 : base = &abs_base;
617 dean.a.rasheed 10931 ECB : }
10932 : else
617 dean.a.rasheed 10933 CBC 54 : res_sign = NUMERIC_POS;
10934 :
10935 : /*----------
2703 tgl 10936 ECB : * Decide on the scale for the ln() calculation. For this we need an
10937 : * estimate of the weight of the result, which we obtain by doing an
10938 : * initial low-precision calculation of exp * ln(base).
10939 : *
10940 : * We want result = e ^ (exp * ln(base))
10941 : * so result dweight = log10(result) = exp * ln(base) * log10(e)
2530 dean.a.rasheed 10942 : *
10943 : * We also perform a crude overflow test here so that we can exit early if
10944 : * the full-precision result is sure to overflow, and to guard against
10945 : * integer overflow when determining the scale for the real calculation.
10946 : * exp_var() supports inputs up to NUMERIC_MAX_RESULT_SCALE * 3, so the
10947 : * result will overflow if exp * ln(base) >= NUMERIC_MAX_RESULT_SCALE * 3.
10948 : * Since the values here are only approximations, we apply a small fuzz
10949 : * factor to this overflow test and let exp_var() determine the exact
10950 : * overflow threshold so that it is consistent for all inputs.
10951 : *----------
2703 tgl 10952 : */
2703 tgl 10953 CBC 63 : ln_dweight = estimate_ln_dweight(base);
10954 :
10955 : /*
10956 : * Set the scale for the low-precision calculation, computing ln(base) to
10957 : * around 8 significant digits. Note that ln_dweight may be as small as
10958 : * -SHRT_MAX, so the scale may exceed NUMERIC_MAX_DISPLAY_SCALE here.
550 dean.a.rasheed 10959 ECB : */
2703 tgl 10960 CBC 63 : local_rscale = 8 - ln_dweight;
10961 63 : local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
10962 :
7324 tgl 10963 GIC 63 : ln_var(base, &ln_base, local_rscale);
8866 JanWieck 10964 ECB :
7324 tgl 10965 GIC 63 : mul_var(&ln_base, exp, &ln_num, local_rscale);
10966 :
7494 tgl 10967 CBC 63 : val = numericvar_to_double_no_overflow(&ln_num);
10968 :
617 dean.a.rasheed 10969 ECB : /* initial overflow/underflow test with fuzz factor */
184 peter 10970 GNC 63 : if (fabs(val) > NUMERIC_MAX_RESULT_SCALE * 3.01)
617 dean.a.rasheed 10971 ECB : {
617 dean.a.rasheed 10972 CBC 3 : if (val > 0)
617 dean.a.rasheed 10973 LBC 0 : ereport(ERROR,
617 dean.a.rasheed 10974 ECB : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
10975 : errmsg("value overflows numeric format")));
617 dean.a.rasheed 10976 GIC 3 : zero_var(result);
10977 3 : result->dscale = NUMERIC_MAX_DISPLAY_SCALE;
10978 3 : return;
10979 : }
10980 :
2530 10981 60 : val *= 0.434294481903252; /* approximate decimal result weight */
10982 :
10983 : /* choose the result scale */
7324 tgl 10984 CBC 60 : rscale = NUMERIC_MIN_SIG_DIGITS - (int) val;
7324 tgl 10985 GIC 60 : rscale = Max(rscale, base->dscale);
10986 60 : rscale = Max(rscale, exp->dscale);
10987 60 : rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
10988 60 : rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
10989 :
10990 : /* significant digits required in the result */
617 dean.a.rasheed 10991 60 : sig_digits = rscale + (int) val;
10992 60 : sig_digits = Max(sig_digits, 0);
10993 :
10994 : /* set the scale for the real exp * ln(base) calculation */
617 dean.a.rasheed 10995 CBC 60 : local_rscale = sig_digits - ln_dweight + 8;
2703 tgl 10996 60 : local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
10997 :
2703 tgl 10998 ECB : /* and do the real calculation */
10999 :
2703 tgl 11000 GIC 60 : ln_var(base, &ln_base, local_rscale);
11001 :
11002 60 : mul_var(&ln_base, exp, &ln_num, local_rscale);
11003 :
7324 tgl 11004 CBC 60 : exp_var(&ln_num, result, rscale);
11005 :
617 dean.a.rasheed 11006 GIC 60 : if (res_sign == NUMERIC_NEG && result->ndigits > 0)
11007 3 : result->sign = NUMERIC_NEG;
617 dean.a.rasheed 11008 ECB :
7324 tgl 11009 GIC 60 : free_var(&ln_num);
7324 tgl 11010 CBC 60 : free_var(&ln_base);
617 dean.a.rasheed 11011 GBC 60 : free_var(&abs_base);
11012 : }
11013 :
7324 tgl 11014 ECB : /*
11015 : * power_var_int() -
11016 : *
11017 : * Raise base to the power of exp, where exp is an integer.
11018 : *
11019 : * Note: this routine chooses dscale of the result.
11020 : */
11021 : static void
171 dean.a.rasheed 11022 GNC 489 : power_var_int(const NumericVar *base, int exp, int exp_dscale,
11023 : NumericVar *result)
11024 : {
11025 : double f;
11026 : int p;
11027 : int i;
11028 : int rscale;
11029 : int sig_digits;
11030 : unsigned int mask;
11031 : bool neg;
11032 : NumericVar base_prod;
7324 tgl 11033 ECB : int local_rscale;
11034 :
11035 : /*
11036 : * Choose the result scale. For this we need an estimate of the decimal
11037 : * weight of the result, which we obtain by approximating using double
11038 : * precision arithmetic.
11039 : *
11040 : * We also perform crude overflow/underflow tests here so that we can exit
11041 : * early if the result is sure to overflow/underflow, and to guard against
11042 : * integer overflow when choosing the result scale.
11043 : */
171 dean.a.rasheed 11044 GNC 489 : if (base->ndigits != 0)
11045 : {
11046 : /*----------
11047 : * Choose f (double) and p (int) such that base ~= f * 10^p.
11048 : * Then log10(result) = log10(base^exp) ~= exp * (log10(f) + p).
11049 : *----------
11050 : */
11051 474 : f = base->digits[0];
11052 474 : p = base->weight * DEC_DIGITS;
11053 :
11054 516 : for (i = 1; i < base->ndigits && i * DEC_DIGITS < 16; i++)
11055 : {
11056 42 : f = f * NBASE + base->digits[i];
11057 42 : p -= DEC_DIGITS;
11058 : }
11059 :
11060 474 : f = exp * (log10(f) + p); /* approximate decimal result weight */
11061 : }
11062 : else
11063 15 : f = 0; /* result is 0 or 1 (weight 0), or error */
11064 :
11065 : /* overflow/underflow tests with fuzz factors */
11066 489 : if (f > (SHRT_MAX + 1) * DEC_DIGITS)
11067 6 : ereport(ERROR,
11068 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
11069 : errmsg("value overflows numeric format")));
11070 483 : if (f + 1 < -NUMERIC_MAX_DISPLAY_SCALE)
11071 : {
11072 6 : zero_var(result);
11073 6 : result->dscale = NUMERIC_MAX_DISPLAY_SCALE;
11074 93 : return;
11075 : }
11076 :
11077 : /*
11078 : * Choose the result scale in the same way as power_var(), so it has at
11079 : * least NUMERIC_MIN_SIG_DIGITS significant digits and is not less than
11080 : * either input's display scale.
11081 : */
11082 477 : rscale = NUMERIC_MIN_SIG_DIGITS - (int) f;
11083 477 : rscale = Max(rscale, base->dscale);
11084 477 : rscale = Max(rscale, exp_dscale);
11085 477 : rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
11086 477 : rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
11087 :
3132 tgl 11088 ECB : /* Handle some common special cases, as well as corner cases */
7324 tgl 11089 CBC 477 : switch (exp)
11090 : {
11091 33 : case 0:
11092 :
5449 bruce 11093 ECB : /*
5050 11094 : * While 0 ^ 0 can be either 1 or indeterminate (error), we treat
11095 : * it as 1 because most programming languages do this. SQL:2003
11096 : * also requires a return value of 1.
1728 peter_e 11097 : * https://en.wikipedia.org/wiki/Exponentiation#Zero_to_the_zero_power
5449 bruce 11098 : */
7324 tgl 11099 GIC 33 : set_var_from_var(&const_one, result);
7188 bruce 11100 33 : result->dscale = rscale; /* no need to round */
7324 tgl 11101 CBC 33 : return;
7324 tgl 11102 GIC 21 : case 1:
11103 21 : set_var_from_var(base, result);
11104 21 : round_var(result, rscale);
11105 21 : return;
11106 12 : case -1:
6518 bruce 11107 12 : div_var(&const_one, base, result, rscale, true);
7324 tgl 11108 12 : return;
11109 21 : case 2:
7324 tgl 11110 CBC 21 : mul_var(base, base, result, rscale);
11111 21 : return;
7324 tgl 11112 GIC 390 : default:
7324 tgl 11113 CBC 390 : break;
11114 : }
11115 :
11116 : /* Handle the special case where the base is zero */
2703 tgl 11117 GIC 390 : if (base->ndigits == 0)
11118 : {
2703 tgl 11119 UIC 0 : if (exp < 0)
11120 0 : ereport(ERROR,
11121 : (errcode(ERRCODE_DIVISION_BY_ZERO),
11122 : errmsg("division by zero")));
2703 tgl 11123 LBC 0 : zero_var(result);
2703 tgl 11124 UIC 0 : result->dscale = rscale;
2703 tgl 11125 LBC 0 : return;
2703 tgl 11126 ECB : }
11127 :
11128 : /*
7188 bruce 11129 : * The general case repeatedly multiplies base according to the bit
11130 : * pattern of exp.
2703 tgl 11131 : *
11132 : * The local rscale used for each multiplication is varied to keep a fixed
11133 : * number of significant digits, sufficient to give the required result
11134 : * scale.
11135 : */
11136 :
11137 : /*
11138 : * Approximate number of significant digits in the result. Note that the
11139 : * underflow test above, together with the choice of rscale, ensures that
11140 : * this approximation is necessarily > 0.
11141 : */
2703 tgl 11142 CBC 390 : sig_digits = 1 + rscale + (int) f;
11143 :
11144 : /*
11145 : * The multiplications to produce the result may introduce an error of up
11146 : * to around log10(abs(exp)) digits, so work with this many extra digits
2703 tgl 11147 ECB : * of precision (plus a few more for good measure).
11148 : */
824 dean.a.rasheed 11149 GIC 390 : sig_digits += (int) log(fabs((double) exp)) + 8;
2703 tgl 11150 ECB :
11151 : /*
11152 : * Now we can proceed with the multiplications.
11153 : */
7324 tgl 11154 GIC 390 : neg = (exp < 0);
184 peter 11155 GNC 390 : mask = abs(exp);
11156 :
7324 tgl 11157 GIC 390 : init_var(&base_prod);
11158 390 : set_var_from_var(base, &base_prod);
11159 :
3132 11160 390 : if (mask & 1)
7324 tgl 11161 CBC 195 : set_var_from_var(base, result);
7324 tgl 11162 ECB : else
7324 tgl 11163 GIC 195 : set_var_from_var(&const_one, result);
7324 tgl 11164 ECB :
3132 tgl 11165 GIC 2100 : while ((mask >>= 1) > 0)
11166 : {
2703 tgl 11167 ECB : /*
11168 : * Do the multiplications using rscales large enough to hold the
11169 : * results to the required number of significant digits, but don't
11170 : * waste time by exceeding the scales of the numbers themselves.
11171 : */
2703 tgl 11172 CBC 1710 : local_rscale = sig_digits - 2 * base_prod.weight * DEC_DIGITS;
2703 tgl 11173 GIC 1710 : local_rscale = Min(local_rscale, 2 * base_prod.dscale);
11174 1710 : local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
2703 tgl 11175 ECB :
7324 tgl 11176 GIC 1710 : mul_var(&base_prod, &base_prod, &base_prod, local_rscale);
11177 :
3132 11178 1710 : if (mask & 1)
11179 : {
2703 11180 1137 : local_rscale = sig_digits -
11181 1137 : (base_prod.weight + result->weight) * DEC_DIGITS;
11182 1137 : local_rscale = Min(local_rscale,
11183 : base_prod.dscale + result->dscale);
2703 tgl 11184 CBC 1137 : local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
11185 :
7324 tgl 11186 GIC 1137 : mul_var(&base_prod, result, result, local_rscale);
11187 : }
11188 :
11189 : /*
3132 tgl 11190 ECB : * When abs(base) > 1, the number of digits to the left of the decimal
11191 : * point in base_prod doubles at each iteration, so if exp is large we
11192 : * could easily spend large amounts of time and memory space doing the
11193 : * multiplications. But once the weight exceeds what will fit in
11194 : * int16, the final result is guaranteed to overflow (or underflow, if
11195 : * exp < 0), so we can give up before wasting too many cycles.
11196 : */
3132 tgl 11197 GIC 1710 : if (base_prod.weight > SHRT_MAX || result->weight > SHRT_MAX)
11198 : {
11199 : /* overflow, unless neg, in which case result should be 0 */
3132 tgl 11200 UIC 0 : if (!neg)
11201 0 : ereport(ERROR,
11202 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
11203 : errmsg("value overflows numeric format")));
3132 tgl 11204 LBC 0 : zero_var(result);
11205 0 : neg = false;
3132 tgl 11206 UIC 0 : break;
11207 : }
11208 : }
11209 :
7324 tgl 11210 CBC 390 : free_var(&base_prod);
11211 :
11212 : /* Compensate for input sign, and round to requested rscale */
7324 tgl 11213 GIC 390 : if (neg)
5483 tgl 11214 CBC 183 : div_var_fast(&const_one, result, result, rscale, true);
11215 : else
7324 tgl 11216 GIC 207 : round_var(result, rscale);
11217 : }
11218 :
11219 : /*
11220 : * power_ten_int() -
11221 : *
11222 : * Raise ten to the power of exp, where exp is an integer. Note that unlike
11223 : * power_var_int(), this does no overflow/underflow checking or rounding.
612 dean.a.rasheed 11224 ECB : */
11225 : static void
612 dean.a.rasheed 11226 GIC 108 : power_ten_int(int exp, NumericVar *result)
11227 : {
11228 : /* Construct the result directly, starting from 10^0 = 1 */
11229 108 : set_var_from_var(&const_one, result);
11230 :
11231 : /* Scale needed to represent the result exactly */
11232 108 : result->dscale = exp < 0 ? -exp : 0;
11233 :
11234 : /* Base-NBASE weight of result and remaining exponent */
612 dean.a.rasheed 11235 CBC 108 : if (exp >= 0)
11236 75 : result->weight = exp / DEC_DIGITS;
612 dean.a.rasheed 11237 ECB : else
612 dean.a.rasheed 11238 GIC 33 : result->weight = (exp + 1) / DEC_DIGITS - 1;
11239 :
612 dean.a.rasheed 11240 CBC 108 : exp -= result->weight * DEC_DIGITS;
612 dean.a.rasheed 11241 ECB :
11242 : /* Final adjustment of the result's single NBASE digit */
612 dean.a.rasheed 11243 GIC 273 : while (exp-- > 0)
11244 165 : result->digits[0] *= 10;
612 dean.a.rasheed 11245 CBC 108 : }
612 dean.a.rasheed 11246 ECB :
8866 JanWieck 11247 :
11248 : /* ----------------------------------------------------------------------
11249 : *
11250 : * Following are the lowest level functions that operate unsigned
11251 : * on the variable level
11252 : *
11253 : * ----------------------------------------------------------------------
11254 : */
11255 :
11256 :
11257 : /* ----------
11258 : * cmp_abs() -
11259 : *
11260 : * Compare the absolute values of var1 and var2
11261 : * Returns: -1 for ABS(var1) < ABS(var2)
11262 : * 0 for ABS(var1) == ABS(var2)
11263 : * 1 for ABS(var1) > ABS(var2)
11264 : * ----------
11265 : */
11266 : static int
2037 andres 11267 GIC 143246 : cmp_abs(const NumericVar *var1, const NumericVar *var2)
8866 JanWieck 11268 ECB : {
6270 bruce 11269 CBC 286492 : return cmp_abs_common(var1->digits, var1->ndigits, var1->weight,
6270 bruce 11270 GIC 143246 : var2->digits, var2->ndigits, var2->weight);
6270 bruce 11271 ECB : }
11272 :
11273 : /* ----------
11274 : * cmp_abs_common() -
11275 : *
6031 11276 : * Main routine of cmp_abs(). This function can be used by both
11277 : * NumericVar and Numeric.
6270 11278 : * ----------
11279 : */
11280 : static int
6270 bruce 11281 CBC 3240490 : cmp_abs_common(const NumericDigit *var1digits, int var1ndigits, int var1weight,
11282 : const NumericDigit *var2digits, int var2ndigits, int var2weight)
11283 : {
8720 bruce 11284 GIC 3240490 : int i1 = 0;
11285 3240490 : int i2 = 0;
11286 :
11287 : /* Check any digits before the first common digit */
11288 :
6270 11289 3240490 : while (var1weight > var2weight && i1 < var1ndigits)
11290 : {
7324 tgl 11291 10088 : if (var1digits[i1++] != 0)
8720 bruce 11292 10088 : return 1;
6270 bruce 11293 UIC 0 : var1weight--;
11294 : }
6270 bruce 11295 GIC 3230402 : while (var2weight > var1weight && i2 < var2ndigits)
11296 : {
7324 tgl 11297 9038 : if (var2digits[i2++] != 0)
8720 bruce 11298 9038 : return -1;
6270 bruce 11299 LBC 0 : var2weight--;
11300 : }
8866 JanWieck 11301 ECB :
7324 tgl 11302 : /* At this point, either w1 == w2 or we've run out of digits */
11303 :
6270 bruce 11304 CBC 3221364 : if (var1weight == var2weight)
8866 JanWieck 11305 ECB : {
6270 bruce 11306 GIC 6029656 : while (i1 < var1ndigits && i2 < var2ndigits)
8866 JanWieck 11307 ECB : {
7324 tgl 11308 GIC 4011418 : int stat = var1digits[i1++] - var2digits[i2++];
11309 :
8861 JanWieck 11310 4011418 : if (stat)
8861 JanWieck 11311 ECB : {
8861 JanWieck 11312 CBC 1203117 : if (stat > 0)
11313 784631 : return 1;
8861 JanWieck 11314 GIC 418486 : return -1;
8861 JanWieck 11315 ECB : }
8866 11316 : }
11317 : }
11318 :
11319 : /*
6385 bruce 11320 : * At this point, we've run out of digits on one side or the other; so any
6385 bruce 11321 EUB : * remaining nonzero digits imply that side is larger
11322 : */
6270 bruce 11323 GIC 2018415 : while (i1 < var1ndigits)
11324 : {
7324 tgl 11325 CBC 1110 : if (var1digits[i1++] != 0)
8866 JanWieck 11326 GIC 942 : return 1;
8866 JanWieck 11327 ECB : }
6270 bruce 11328 CBC 2017431 : while (i2 < var2ndigits)
8866 JanWieck 11329 ECB : {
7324 tgl 11330 CBC 402 : if (var2digits[i2++] != 0)
8866 JanWieck 11331 276 : return -1;
11332 : }
11333 :
8866 JanWieck 11334 GIC 2017029 : return 0;
11335 : }
11336 :
11337 :
11338 : /*
11339 : * add_abs() -
11340 : *
11341 : * Add the absolute values of two variables into result.
8866 JanWieck 11342 ECB : * result might point to one of the operands without danger.
11343 : */
11344 : static void
2037 andres 11345 GIC 148392 : add_abs(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
11346 : {
11347 : NumericDigit *res_buf;
11348 : NumericDigit *res_digits;
11349 : int res_ndigits;
11350 : int res_weight;
11351 : int res_rscale,
11352 : rscale1,
7324 tgl 11353 ECB : rscale2;
8720 bruce 11354 : int res_dscale;
11355 : int i,
11356 : i1,
11357 : i2;
8720 bruce 11358 CBC 148392 : int carry = 0;
8053 bruce 11359 ECB :
11360 : /* copy these values into local vars for speed in inner loop */
8301 tgl 11361 GIC 148392 : int var1ndigits = var1->ndigits;
11362 148392 : int var2ndigits = var2->ndigits;
11363 148392 : NumericDigit *var1digits = var1->digits;
11364 148392 : NumericDigit *var2digits = var2->digits;
11365 :
7720 bruce 11366 CBC 148392 : res_weight = Max(var1->weight, var2->weight) + 1;
7324 tgl 11367 ECB :
7720 bruce 11368 CBC 148392 : res_dscale = Max(var1->dscale, var2->dscale);
7324 tgl 11369 ECB :
11370 : /* Note: here we are figuring rscale in base-NBASE digits */
7324 tgl 11371 GIC 148392 : rscale1 = var1->ndigits - var1->weight - 1;
11372 148392 : rscale2 = var2->ndigits - var2->weight - 1;
11373 148392 : res_rscale = Max(rscale1, rscale2);
11374 :
8866 JanWieck 11375 148392 : res_ndigits = res_rscale + res_weight + 1;
8482 tgl 11376 CBC 148392 : if (res_ndigits <= 0)
8482 tgl 11377 LBC 0 : res_ndigits = 1;
11378 :
7324 tgl 11379 CBC 148392 : res_buf = digitbuf_alloc(res_ndigits + 1);
11380 148392 : res_buf[0] = 0; /* spare digit for later rounding */
7324 tgl 11381 GIC 148392 : res_digits = res_buf + 1;
11382 :
8866 JanWieck 11383 CBC 148392 : i1 = res_rscale + var1->weight + 1;
11384 148392 : i2 = res_rscale + var2->weight + 1;
8866 JanWieck 11385 GIC 1594356 : for (i = res_ndigits - 1; i >= 0; i--)
11386 : {
8866 JanWieck 11387 CBC 1445964 : i1--;
8866 JanWieck 11388 GIC 1445964 : i2--;
8301 tgl 11389 CBC 1445964 : if (i1 >= 0 && i1 < var1ndigits)
11390 632497 : carry += var1digits[i1];
11391 1445964 : if (i2 >= 0 && i2 < var2ndigits)
8301 tgl 11392 GIC 498901 : carry += var2digits[i2];
11393 :
7324 11394 1445964 : if (carry >= NBASE)
11395 : {
11396 110947 : res_digits[i] = carry - NBASE;
8301 11397 110947 : carry = 1;
11398 : }
11399 : else
11400 : {
11401 1335017 : res_digits[i] = carry;
8301 tgl 11402 CBC 1335017 : carry = 0;
11403 : }
11404 : }
11405 :
8301 tgl 11406 GIC 148392 : Assert(carry == 0); /* else we failed to allow for carry out */
11407 :
8866 JanWieck 11408 148392 : digitbuf_free(result->buf);
11409 148392 : result->ndigits = res_ndigits;
8720 bruce 11410 148392 : result->buf = res_buf;
11411 148392 : result->digits = res_digits;
11412 148392 : result->weight = res_weight;
11413 148392 : result->dscale = res_dscale;
11414 :
7324 tgl 11415 ECB : /* Remove leading/trailing zeroes */
7324 tgl 11416 GIC 148392 : strip_var(result);
8866 JanWieck 11417 148392 : }
11418 :
11419 :
7324 tgl 11420 ECB : /*
11421 : * sub_abs()
8866 JanWieck 11422 : *
11423 : * Subtract the absolute value of var2 from the absolute value of var1
11424 : * and store in result. result might point to one of the operands
11425 : * without danger.
11426 : *
11427 : * ABS(var1) MUST BE GREATER OR EQUAL ABS(var2) !!!
11428 : */
11429 : static void
2037 andres 11430 GIC 125803 : sub_abs(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
11431 : {
11432 : NumericDigit *res_buf;
11433 : NumericDigit *res_digits;
11434 : int res_ndigits;
8720 bruce 11435 ECB : int res_weight;
11436 : int res_rscale,
7324 tgl 11437 : rscale1,
11438 : rscale2;
8720 bruce 11439 : int res_dscale;
11440 : int i,
11441 : i1,
11442 : i2;
8720 bruce 11443 CBC 125803 : int borrow = 0;
8053 bruce 11444 ECB :
11445 : /* copy these values into local vars for speed in inner loop */
8301 tgl 11446 GIC 125803 : int var1ndigits = var1->ndigits;
11447 125803 : int var2ndigits = var2->ndigits;
11448 125803 : NumericDigit *var1digits = var1->digits;
11449 125803 : NumericDigit *var2digits = var2->digits;
8866 JanWieck 11450 ECB :
8866 JanWieck 11451 GIC 125803 : res_weight = var1->weight;
11452 :
7720 bruce 11453 125803 : res_dscale = Max(var1->dscale, var2->dscale);
11454 :
11455 : /* Note: here we are figuring rscale in base-NBASE digits */
7324 tgl 11456 CBC 125803 : rscale1 = var1->ndigits - var1->weight - 1;
11457 125803 : rscale2 = var2->ndigits - var2->weight - 1;
7324 tgl 11458 GIC 125803 : res_rscale = Max(rscale1, rscale2);
11459 :
8866 JanWieck 11460 125803 : res_ndigits = res_rscale + res_weight + 1;
8482 tgl 11461 125803 : if (res_ndigits <= 0)
8482 tgl 11462 LBC 0 : res_ndigits = 1;
8866 JanWieck 11463 ECB :
7324 tgl 11464 CBC 125803 : res_buf = digitbuf_alloc(res_ndigits + 1);
7324 tgl 11465 GIC 125803 : res_buf[0] = 0; /* spare digit for later rounding */
7324 tgl 11466 CBC 125803 : res_digits = res_buf + 1;
11467 :
8866 JanWieck 11468 GIC 125803 : i1 = res_rscale + var1->weight + 1;
8866 JanWieck 11469 CBC 125803 : i2 = res_rscale + var2->weight + 1;
11470 2143353 : for (i = res_ndigits - 1; i >= 0; i--)
8866 JanWieck 11471 ECB : {
8866 JanWieck 11472 GIC 2017550 : i1--;
11473 2017550 : i2--;
8301 tgl 11474 CBC 2017550 : if (i1 >= 0 && i1 < var1ndigits)
8301 tgl 11475 GIC 1847994 : borrow += var1digits[i1];
11476 2017550 : if (i2 >= 0 && i2 < var2ndigits)
11477 1805219 : borrow -= var2digits[i2];
11478 :
8866 JanWieck 11479 2017550 : if (borrow < 0)
11480 : {
7324 tgl 11481 190584 : res_digits[i] = borrow + NBASE;
8866 JanWieck 11482 190584 : borrow = -1;
11483 : }
11484 : else
11485 : {
11486 1826966 : res_digits[i] = borrow;
11487 1826966 : borrow = 0;
11488 : }
11489 : }
11490 :
8301 tgl 11491 125803 : Assert(borrow == 0); /* else caller gave us var1 < var2 */
11492 :
8866 JanWieck 11493 125803 : digitbuf_free(result->buf);
8866 JanWieck 11494 CBC 125803 : result->ndigits = res_ndigits;
8720 bruce 11495 GIC 125803 : result->buf = res_buf;
11496 125803 : result->digits = res_digits;
11497 125803 : result->weight = res_weight;
11498 125803 : result->dscale = res_dscale;
11499 :
11500 : /* Remove leading/trailing zeroes */
7324 tgl 11501 CBC 125803 : strip_var(result);
11502 125803 : }
11503 :
7324 tgl 11504 ECB : /*
11505 : * round_var
11506 : *
11507 : * Round the value of a variable to no more than rscale decimal digits
11508 : * after the decimal point. NOTE: we allow rscale < 0 here, implying
11509 : * rounding before the decimal point.
11510 : */
11511 : static void
7324 tgl 11512 GIC 496023 : round_var(NumericVar *var, int rscale)
7324 tgl 11513 ECB : {
7188 bruce 11514 GBC 496023 : NumericDigit *digits = var->digits;
11515 : int di;
11516 : int ndigits;
7324 tgl 11517 ECB : int carry;
11518 :
7324 tgl 11519 CBC 496023 : var->dscale = rscale;
11520 :
11521 : /* decimal digits wanted */
11522 496023 : di = (var->weight + 1) * DEC_DIGITS + rscale;
11523 :
11524 : /*
6385 bruce 11525 ECB : * If di = 0, the value loses all digits, but could round up to 1 if its
11526 : * first extra digit is >= 5. If di < 0 the result must be 0.
7324 tgl 11527 : */
7324 tgl 11528 CBC 496023 : if (di < 0)
7324 tgl 11529 ECB : {
7324 tgl 11530 GIC 34 : var->ndigits = 0;
11531 34 : var->weight = 0;
7324 tgl 11532 CBC 34 : var->sign = NUMERIC_POS;
7324 tgl 11533 ECB : }
11534 : else
11535 : {
11536 : /* NBASE digits wanted */
7188 bruce 11537 CBC 495989 : ndigits = (di + DEC_DIGITS - 1) / DEC_DIGITS;
11538 :
11539 : /* 0, or number of decimal digits to keep in last NBASE digit */
7324 tgl 11540 GIC 495989 : di %= DEC_DIGITS;
7324 tgl 11541 ECB :
7324 tgl 11542 GIC 495989 : if (ndigits < var->ndigits ||
7324 tgl 11543 CBC 409732 : (ndigits == var->ndigits && di > 0))
11544 : {
11545 329635 : var->ndigits = ndigits;
11546 :
7324 tgl 11547 ECB : #if DEC_DIGITS == 1
11548 : /* di must be zero */
11549 : carry = (digits[ndigits] >= HALF_NBASE) ? 1 : 0;
11550 : #else
7324 tgl 11551 CBC 329635 : if (di == 0)
11552 67146 : carry = (digits[ndigits] >= HALF_NBASE) ? 1 : 0;
11553 : else
11554 : {
11555 : /* Must round within last NBASE digit */
11556 : int extra,
11557 : pow10;
11558 :
11559 : #if DEC_DIGITS == 4
7324 tgl 11560 GIC 262489 : pow10 = round_powers[di];
11561 : #elif DEC_DIGITS == 2
11562 : pow10 = 10;
7324 tgl 11563 ECB : #else
11564 : #error unsupported NBASE
11565 : #endif
7324 tgl 11566 GIC 262489 : extra = digits[--ndigits] % pow10;
11567 262489 : digits[ndigits] -= extra;
11568 262489 : carry = 0;
7188 bruce 11569 262489 : if (extra >= pow10 / 2)
11570 : {
7324 tgl 11571 9665 : pow10 += digits[ndigits];
11572 9665 : if (pow10 >= NBASE)
11573 : {
11574 406 : pow10 -= NBASE;
11575 406 : carry = 1;
11576 : }
11577 9665 : digits[ndigits] = pow10;
11578 : }
11579 : }
11580 : #endif
11581 :
11582 : /* Propagate carry if needed */
11583 347212 : while (carry)
11584 : {
7324 tgl 11585 CBC 17577 : carry += digits[--ndigits];
7324 tgl 11586 GIC 17577 : if (carry >= NBASE)
11587 : {
11588 12387 : digits[ndigits] = carry - NBASE;
11589 12387 : carry = 1;
11590 : }
11591 : else
7324 tgl 11592 ECB : {
7324 tgl 11593 CBC 5190 : digits[ndigits] = carry;
7324 tgl 11594 GIC 5190 : carry = 0;
7324 tgl 11595 ECB : }
11596 : }
11597 :
7324 tgl 11598 CBC 329635 : if (ndigits < 0)
11599 : {
7324 tgl 11600 GIC 45 : Assert(ndigits == -1); /* better not have added > 1 digit */
7324 tgl 11601 CBC 45 : Assert(var->digits > var->buf);
7324 tgl 11602 GIC 45 : var->digits--;
11603 45 : var->ndigits++;
7324 tgl 11604 CBC 45 : var->weight++;
11605 : }
11606 : }
7324 tgl 11607 ECB : }
7324 tgl 11608 CBC 496023 : }
11609 :
11610 : /*
7324 tgl 11611 ECB : * trunc_var
11612 : *
5483 11613 : * Truncate (towards zero) the value of a variable at rscale decimal digits
11614 : * after the decimal point. NOTE: we allow rscale < 0 here, implying
7324 11615 : * truncation before the decimal point.
11616 : */
11617 : static void
7324 tgl 11618 GIC 29884 : trunc_var(NumericVar *var, int rscale)
11619 : {
11620 : int di;
11621 : int ndigits;
11622 :
7324 tgl 11623 CBC 29884 : var->dscale = rscale;
7324 tgl 11624 ECB :
11625 : /* decimal digits wanted */
7324 tgl 11626 CBC 29884 : di = (var->weight + 1) * DEC_DIGITS + rscale;
7324 tgl 11627 ECB :
11628 : /*
11629 : * If di <= 0, the value loses all digits.
11630 : */
7324 tgl 11631 GIC 29884 : if (di <= 0)
7324 tgl 11632 ECB : {
7324 tgl 11633 GIC 27 : var->ndigits = 0;
11634 27 : var->weight = 0;
11635 27 : var->sign = NUMERIC_POS;
11636 : }
11637 : else
11638 : {
11639 : /* NBASE digits wanted */
7188 bruce 11640 CBC 29857 : ndigits = (di + DEC_DIGITS - 1) / DEC_DIGITS;
7324 tgl 11641 ECB :
7324 tgl 11642 CBC 29857 : if (ndigits <= var->ndigits)
7324 tgl 11643 ECB : {
7324 tgl 11644 CBC 29761 : var->ndigits = ndigits;
7324 tgl 11645 ECB :
11646 : #if DEC_DIGITS == 1
11647 : /* no within-digit stuff to worry about */
11648 : #else
11649 : /* 0, or number of decimal digits to keep in last NBASE digit */
7324 tgl 11650 CBC 29761 : di %= DEC_DIGITS;
7324 tgl 11651 ECB :
7324 tgl 11652 CBC 29761 : if (di > 0)
7324 tgl 11653 ECB : {
11654 : /* Must truncate within last NBASE digit */
7188 bruce 11655 GIC 41 : NumericDigit *digits = var->digits;
11656 : int extra,
11657 : pow10;
7324 tgl 11658 ECB :
11659 : #if DEC_DIGITS == 4
7324 tgl 11660 GBC 41 : pow10 = round_powers[di];
7324 tgl 11661 EUB : #elif DEC_DIGITS == 2
11662 : pow10 = 10;
11663 : #else
11664 : #error unsupported NBASE
11665 : #endif
7324 tgl 11666 GBC 41 : extra = digits[--ndigits] % pow10;
7324 tgl 11667 GIC 41 : digits[ndigits] -= extra;
11668 : }
11669 : #endif
11670 : }
11671 : }
11672 29884 : }
11673 :
11674 : /*
11675 : * strip_var
11676 : *
11677 : * Strip any leading and trailing zeroes from a numeric variable
11678 : */
11679 : static void
11680 938626 : strip_var(NumericVar *var)
11681 : {
7188 bruce 11682 938626 : NumericDigit *digits = var->digits;
7324 tgl 11683 CBC 938626 : int ndigits = var->ndigits;
11684 :
11685 : /* Strip leading zeroes */
7324 tgl 11686 GIC 2226262 : while (ndigits > 0 && *digits == 0)
11687 : {
11688 1287636 : digits++;
11689 1287636 : var->weight--;
7324 tgl 11690 CBC 1287636 : ndigits--;
11691 : }
11692 :
11693 : /* Strip trailing zeroes */
7324 tgl 11694 GIC 1216040 : while (ndigits > 0 && digits[ndigits - 1] == 0)
7324 tgl 11695 CBC 277414 : ndigits--;
7324 tgl 11696 ECB :
11697 : /* If it's zero, normalize the sign and weight */
7324 tgl 11698 CBC 938626 : if (ndigits == 0)
7324 tgl 11699 ECB : {
7324 tgl 11700 GIC 12984 : var->sign = NUMERIC_POS;
7324 tgl 11701 CBC 12984 : var->weight = 0;
7324 tgl 11702 ECB : }
11703 :
7324 tgl 11704 CBC 938626 : var->digits = digits;
7324 tgl 11705 GIC 938626 : var->ndigits = ndigits;
8866 JanWieck 11706 CBC 938626 : }
11707 :
11708 :
11709 : /* ----------------------------------------------------------------------
11710 : *
11711 : * Fast sum accumulator functions
11712 : *
2410 heikki.linnakangas 11713 ECB : * ----------------------------------------------------------------------
11714 : */
11715 :
11716 : /*
11717 : * Reset the accumulator's value to zero. The buffers to hold the digits
11718 : * are not free'd.
11719 : */
11720 : static void
2410 heikki.linnakangas 11721 CBC 9 : accum_sum_reset(NumericSumAccum *accum)
2410 heikki.linnakangas 11722 ECB : {
11723 : int i;
11724 :
2410 heikki.linnakangas 11725 CBC 9 : accum->dscale = 0;
2410 heikki.linnakangas 11726 GIC 33 : for (i = 0; i < accum->ndigits; i++)
2410 heikki.linnakangas 11727 ECB : {
2410 heikki.linnakangas 11728 GIC 24 : accum->pos_digits[i] = 0;
11729 24 : accum->neg_digits[i] = 0;
11730 : }
11731 9 : }
11732 :
11733 : /*
11734 : * Accumulate a new value.
11735 : */
11736 : static void
2037 andres 11737 1177852 : accum_sum_add(NumericSumAccum *accum, const NumericVar *val)
2410 heikki.linnakangas 11738 ECB : {
11739 : int32 *accum_digits;
11740 : int i,
2410 heikki.linnakangas 11741 EUB : val_i;
11742 : int val_ndigits;
11743 : NumericDigit *val_digits;
11744 :
11745 : /*
11746 : * If we have accumulated too many values since the last carry
11747 : * propagation, do it now, to avoid overflowing. (We could allow more
11748 : * than NBASE - 1, if we reserved two extra digits, rather than one, for
11749 : * carry propagation. But even with NBASE - 1, this needs to be done so
11750 : * seldom, that the performance difference is negligible.)
2410 heikki.linnakangas 11751 ECB : */
2410 heikki.linnakangas 11752 GIC 1177852 : if (accum->num_uncarried == NBASE - 1)
11753 81 : accum_sum_carry(accum);
2410 heikki.linnakangas 11754 ECB :
11755 : /*
11756 : * Adjust the weight or scale of the old value, so that it can accommodate
11757 : * the new value.
11758 : */
2410 heikki.linnakangas 11759 GIC 1177852 : accum_sum_rescale(accum, val);
11760 :
11761 : /* */
11762 1177852 : if (val->sign == NUMERIC_POS)
11763 877513 : accum_digits = accum->pos_digits;
11764 : else
11765 300339 : accum_digits = accum->neg_digits;
11766 :
2410 heikki.linnakangas 11767 ECB : /* copy these values into local vars for speed in loop */
2410 heikki.linnakangas 11768 GIC 1177852 : val_ndigits = val->ndigits;
11769 1177852 : val_digits = val->digits;
2410 heikki.linnakangas 11770 ECB :
2410 heikki.linnakangas 11771 GIC 1177852 : i = accum->weight - val->weight;
11772 5944973 : for (val_i = 0; val_i < val_ndigits; val_i++)
2410 heikki.linnakangas 11773 ECB : {
2410 heikki.linnakangas 11774 GIC 4767121 : accum_digits[i] += (int32) val_digits[val_i];
11775 4767121 : i++;
2410 heikki.linnakangas 11776 ECB : }
11777 :
2410 heikki.linnakangas 11778 GIC 1177852 : accum->num_uncarried++;
2410 heikki.linnakangas 11779 CBC 1177852 : }
11780 :
2410 heikki.linnakangas 11781 ECB : /*
11782 : * Propagate carries.
11783 : */
11784 : static void
2410 heikki.linnakangas 11785 CBC 86382 : accum_sum_carry(NumericSumAccum *accum)
2410 heikki.linnakangas 11786 ECB : {
11787 : int i;
11788 : int ndigits;
11789 : int32 *dig;
11790 : int32 carry;
2410 heikki.linnakangas 11791 GIC 86382 : int32 newdig = 0;
11792 :
11793 : /*
11794 : * If no new values have been added since last carry propagation, nothing
11795 : * to do.
11796 : */
11797 86382 : if (accum->num_uncarried == 0)
11798 36 : return;
11799 :
11800 : /*
11801 : * We maintain that the weight of the accumulator is always one larger
11802 : * than needed to hold the current value, before carrying, to make sure
11803 : * there is enough space for the possible extra digit when carry is
11804 : * propagated. We cannot expand the buffer here, unless we require
11805 : * callers of accum_sum_final() to switch to the right memory context.
11806 : */
11807 86346 : Assert(accum->pos_digits[0] == 0 && accum->neg_digits[0] == 0);
2410 heikki.linnakangas 11808 ECB :
2410 heikki.linnakangas 11809 GIC 86346 : ndigits = accum->ndigits;
2410 heikki.linnakangas 11810 ECB :
11811 : /* Propagate carry in the positive sum */
2410 heikki.linnakangas 11812 GIC 86346 : dig = accum->pos_digits;
11813 86346 : carry = 0;
11814 1302779 : for (i = ndigits - 1; i >= 0; i--)
11815 : {
11816 1216433 : newdig = dig[i] + carry;
11817 1216433 : if (newdig >= NBASE)
11818 : {
11819 55407 : carry = newdig / NBASE;
11820 55407 : newdig -= carry * NBASE;
11821 : }
2410 heikki.linnakangas 11822 ECB : else
2410 heikki.linnakangas 11823 GIC 1161026 : carry = 0;
11824 1216433 : dig[i] = newdig;
2410 heikki.linnakangas 11825 ECB : }
11826 : /* Did we use up the digit reserved for carry propagation? */
2410 heikki.linnakangas 11827 GIC 86346 : if (newdig > 0)
11828 1321 : accum->have_carry_space = false;
11829 :
2410 heikki.linnakangas 11830 ECB : /* And the same for the negative sum */
2410 heikki.linnakangas 11831 GIC 86346 : dig = accum->neg_digits;
2410 heikki.linnakangas 11832 CBC 86346 : carry = 0;
11833 1302779 : for (i = ndigits - 1; i >= 0; i--)
2410 heikki.linnakangas 11834 EUB : {
2410 heikki.linnakangas 11835 GIC 1216433 : newdig = dig[i] + carry;
2410 heikki.linnakangas 11836 CBC 1216433 : if (newdig >= NBASE)
11837 : {
11838 99 : carry = newdig / NBASE;
11839 99 : newdig -= carry * NBASE;
2410 heikki.linnakangas 11840 EUB : }
11841 : else
2410 heikki.linnakangas 11842 GIC 1216334 : carry = 0;
11843 1216433 : dig[i] = newdig;
11844 : }
2410 heikki.linnakangas 11845 CBC 86346 : if (newdig > 0)
2410 heikki.linnakangas 11846 GIC 15 : accum->have_carry_space = false;
2410 heikki.linnakangas 11847 ECB :
2410 heikki.linnakangas 11848 GIC 86346 : accum->num_uncarried = 0;
2410 heikki.linnakangas 11849 ECB : }
11850 :
11851 : /*
11852 : * Re-scale accumulator to accommodate new value.
11853 : *
11854 : * If the new value has more digits than the current digit buffers in the
11855 : * accumulator, enlarge the buffers.
11856 : */
11857 : static void
2037 andres 11858 GIC 1177852 : accum_sum_rescale(NumericSumAccum *accum, const NumericVar *val)
11859 : {
2410 heikki.linnakangas 11860 1177852 : int old_weight = accum->weight;
11861 1177852 : int old_ndigits = accum->ndigits;
11862 : int accum_ndigits;
11863 : int accum_weight;
2410 heikki.linnakangas 11864 ECB : int accum_rscale;
11865 : int val_rscale;
11866 :
2410 heikki.linnakangas 11867 CBC 1177852 : accum_weight = old_weight;
2410 heikki.linnakangas 11868 GIC 1177852 : accum_ndigits = old_ndigits;
2410 heikki.linnakangas 11869 ECB :
11870 : /*
11871 : * Does the new value have a larger weight? If so, enlarge the buffers,
11872 : * and shift the existing value to the new weight, by adding leading
11873 : * zeros.
11874 : *
11875 : * We enforce that the accumulator always has a weight one larger than
11876 : * needed for the inputs, so that we have space for an extra digit at the
11877 : * final carry-propagation phase, if necessary.
11878 : */
2410 heikki.linnakangas 11879 GIC 1177852 : if (val->weight >= accum_weight)
11880 : {
11881 131114 : accum_weight = val->weight + 1;
11882 131114 : accum_ndigits = accum_ndigits + (accum_weight - old_weight);
11883 : }
11884 :
11885 : /*
2410 heikki.linnakangas 11886 ECB : * Even though the new value is small, we might've used up the space
11887 : * reserved for the carry digit in the last call to accum_sum_carry(). If
11888 : * so, enlarge to make room for another one.
11889 : */
2410 heikki.linnakangas 11890 GIC 1046738 : else if (!accum->have_carry_space)
11891 : {
11892 37 : accum_weight++;
11893 37 : accum_ndigits++;
11894 : }
11895 :
11896 : /* Is the new value wider on the right side? */
11897 1177852 : accum_rscale = accum_ndigits - accum_weight - 1;
11898 1177852 : val_rscale = val->ndigits - val->weight - 1;
2410 heikki.linnakangas 11899 CBC 1177852 : if (val_rscale > accum_rscale)
2410 heikki.linnakangas 11900 GIC 86123 : accum_ndigits = accum_ndigits + (val_rscale - accum_rscale);
11901 :
2410 heikki.linnakangas 11902 CBC 1177852 : if (accum_ndigits != old_ndigits ||
2410 heikki.linnakangas 11903 ECB : accum_weight != old_weight)
11904 : {
11905 : int32 *new_pos_digits;
11906 : int32 *new_neg_digits;
11907 : int weightdiff;
11908 :
2410 heikki.linnakangas 11909 CBC 131298 : weightdiff = accum_weight - old_weight;
11910 :
2410 heikki.linnakangas 11911 GIC 131298 : new_pos_digits = palloc0(accum_ndigits * sizeof(int32));
2410 heikki.linnakangas 11912 CBC 131298 : new_neg_digits = palloc0(accum_ndigits * sizeof(int32));
2410 heikki.linnakangas 11913 ECB :
2410 heikki.linnakangas 11914 CBC 131298 : if (accum->pos_digits)
11915 : {
11916 45210 : memcpy(&new_pos_digits[weightdiff], accum->pos_digits,
2410 heikki.linnakangas 11917 ECB : old_ndigits * sizeof(int32));
2410 heikki.linnakangas 11918 GBC 45210 : pfree(accum->pos_digits);
11919 :
2410 heikki.linnakangas 11920 CBC 45210 : memcpy(&new_neg_digits[weightdiff], accum->neg_digits,
2410 heikki.linnakangas 11921 ECB : old_ndigits * sizeof(int32));
2410 heikki.linnakangas 11922 CBC 45210 : pfree(accum->neg_digits);
11923 : }
2410 heikki.linnakangas 11924 ECB :
2410 heikki.linnakangas 11925 CBC 131298 : accum->pos_digits = new_pos_digits;
11926 131298 : accum->neg_digits = new_neg_digits;
11927 :
11928 131298 : accum->weight = accum_weight;
11929 131298 : accum->ndigits = accum_ndigits;
2410 heikki.linnakangas 11930 ECB :
2410 heikki.linnakangas 11931 CBC 131298 : Assert(accum->pos_digits[0] == 0 && accum->neg_digits[0] == 0);
11932 131298 : accum->have_carry_space = true;
2410 heikki.linnakangas 11933 ECB : }
11934 :
2410 heikki.linnakangas 11935 CBC 1177852 : if (val->dscale > accum->dscale)
2410 heikki.linnakangas 11936 GIC 150 : accum->dscale = val->dscale;
2410 heikki.linnakangas 11937 CBC 1177852 : }
2410 heikki.linnakangas 11938 ECB :
11939 : /*
11940 : * Return the current value of the accumulator. This perform final carry
11941 : * propagation, and adds together the positive and negative sums.
11942 : *
11943 : * Unlike all the other routines, the caller is not required to switch to
11944 : * the memory context that holds the accumulator.
11945 : */
11946 : static void
2410 heikki.linnakangas 11947 CBC 86301 : accum_sum_final(NumericSumAccum *accum, NumericVar *result)
11948 : {
2410 heikki.linnakangas 11949 ECB : int i;
11950 : NumericVar pos_var;
11951 : NumericVar neg_var;
11952 :
2410 heikki.linnakangas 11953 CBC 86301 : if (accum->ndigits == 0)
2410 heikki.linnakangas 11954 ECB : {
2410 heikki.linnakangas 11955 UIC 0 : set_var_from_var(&const_zero, result);
11956 0 : return;
2410 heikki.linnakangas 11957 ECB : }
11958 :
11959 : /* Perform final carry */
2410 heikki.linnakangas 11960 GIC 86301 : accum_sum_carry(accum);
11961 :
11962 : /* Create NumericVars representing the positive and negative sums */
11963 86301 : init_var(&pos_var);
11964 86301 : init_var(&neg_var);
11965 :
11966 86301 : pos_var.ndigits = neg_var.ndigits = accum->ndigits;
11967 86301 : pos_var.weight = neg_var.weight = accum->weight;
11968 86301 : pos_var.dscale = neg_var.dscale = accum->dscale;
11969 86301 : pos_var.sign = NUMERIC_POS;
11970 86301 : neg_var.sign = NUMERIC_NEG;
2410 heikki.linnakangas 11971 ECB :
2410 heikki.linnakangas 11972 GIC 86301 : pos_var.buf = pos_var.digits = digitbuf_alloc(accum->ndigits);
11973 86301 : neg_var.buf = neg_var.digits = digitbuf_alloc(accum->ndigits);
11974 :
11975 1302547 : for (i = 0; i < accum->ndigits; i++)
11976 : {
11977 1216246 : Assert(accum->pos_digits[i] < NBASE);
11978 1216246 : pos_var.digits[i] = (int16) accum->pos_digits[i];
11979 :
11980 1216246 : Assert(accum->neg_digits[i] < NBASE);
11981 1216246 : neg_var.digits[i] = (int16) accum->neg_digits[i];
11982 : }
11983 :
2410 heikki.linnakangas 11984 ECB : /* And add them together */
2410 heikki.linnakangas 11985 GIC 86301 : add_var(&pos_var, &neg_var, result);
11986 :
2410 heikki.linnakangas 11987 ECB : /* Remove leading/trailing zeroes */
2410 heikki.linnakangas 11988 CBC 86301 : strip_var(result);
2410 heikki.linnakangas 11989 ECB : }
11990 :
11991 : /*
11992 : * Copy an accumulator's state.
11993 : *
11994 : * 'dst' is assumed to be uninitialized beforehand. No attempt is made at
11995 : * freeing old values.
11996 : */
11997 : static void
2410 heikki.linnakangas 11998 CBC 21 : accum_sum_copy(NumericSumAccum *dst, NumericSumAccum *src)
2410 heikki.linnakangas 11999 ECB : {
2410 heikki.linnakangas 12000 GIC 21 : dst->pos_digits = palloc(src->ndigits * sizeof(int32));
2410 heikki.linnakangas 12001 CBC 21 : dst->neg_digits = palloc(src->ndigits * sizeof(int32));
2410 heikki.linnakangas 12002 ECB :
2410 heikki.linnakangas 12003 GBC 21 : memcpy(dst->pos_digits, src->pos_digits, src->ndigits * sizeof(int32));
2410 heikki.linnakangas 12004 GIC 21 : memcpy(dst->neg_digits, src->neg_digits, src->ndigits * sizeof(int32));
2410 heikki.linnakangas 12005 CBC 21 : dst->num_uncarried = src->num_uncarried;
12006 21 : dst->ndigits = src->ndigits;
12007 21 : dst->weight = src->weight;
2410 heikki.linnakangas 12008 GIC 21 : dst->dscale = src->dscale;
2410 heikki.linnakangas 12009 CBC 21 : }
2410 heikki.linnakangas 12010 ECB :
12011 : /*
12012 : * Add the current value of 'accum2' into 'accum'.
12013 : */
12014 : static void
2410 heikki.linnakangas 12015 CBC 24 : accum_sum_combine(NumericSumAccum *accum, NumericSumAccum *accum2)
2410 heikki.linnakangas 12016 ECB : {
12017 : NumericVar tmp_var;
12018 :
2410 heikki.linnakangas 12019 GIC 24 : init_var(&tmp_var);
2410 heikki.linnakangas 12020 ECB :
2410 heikki.linnakangas 12021 GIC 24 : accum_sum_final(accum2, &tmp_var);
2410 heikki.linnakangas 12022 CBC 24 : accum_sum_add(accum, &tmp_var);
2410 heikki.linnakangas 12023 ECB :
2410 heikki.linnakangas 12024 GIC 24 : free_var(&tmp_var);
12025 24 : }
|