PostgreSQL Source Code git master
numeric.h File Reference
#include "common/pg_prng.h"
#include "fmgr.h"
Include dependency graph for numeric.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define NUMERIC_MAX_PRECISION   1000
 
#define NUMERIC_MIN_SCALE   (-1000)
 
#define NUMERIC_MAX_SCALE   1000
 
#define NUMERIC_MAX_DISPLAY_SCALE   NUMERIC_MAX_PRECISION
 
#define NUMERIC_MIN_DISPLAY_SCALE   0
 
#define NUMERIC_MAX_RESULT_SCALE   (NUMERIC_MAX_PRECISION * 2)
 
#define NUMERIC_MIN_SIG_DIGITS   16
 
#define PG_GETARG_NUMERIC(n)   DatumGetNumeric(PG_GETARG_DATUM(n))
 
#define PG_GETARG_NUMERIC_COPY(n)   DatumGetNumericCopy(PG_GETARG_DATUM(n))
 
#define PG_RETURN_NUMERIC(x)   return NumericGetDatum(x)
 

Typedefs

typedef struct NumericDataNumeric
 

Functions

static Numeric DatumGetNumeric (Datum X)
 
static Numeric DatumGetNumericCopy (Datum X)
 
static Datum NumericGetDatum (Numeric X)
 
bool numeric_is_nan (Numeric num)
 
bool numeric_is_inf (Numeric num)
 
int32 numeric_maximum_size (int32 typmod)
 
char * numeric_out_sci (Numeric num, int scale)
 
char * numeric_normalize (Numeric num)
 
Numeric int64_to_numeric (int64 val)
 
Numeric int64_div_fast_to_numeric (int64 val1, int log10val2)
 
Numeric numeric_add_opt_error (Numeric num1, Numeric num2, bool *have_error)
 
Numeric numeric_sub_opt_error (Numeric num1, Numeric num2, bool *have_error)
 
Numeric numeric_mul_opt_error (Numeric num1, Numeric num2, bool *have_error)
 
Numeric numeric_div_opt_error (Numeric num1, Numeric num2, bool *have_error)
 
Numeric numeric_mod_opt_error (Numeric num1, Numeric num2, bool *have_error)
 
int32 numeric_int4_opt_error (Numeric num, bool *have_error)
 
int64 numeric_int8_opt_error (Numeric num, bool *have_error)
 
Numeric random_numeric (pg_prng_state *state, Numeric rmin, Numeric rmax)
 

Macro Definition Documentation

◆ NUMERIC_MAX_DISPLAY_SCALE

#define NUMERIC_MAX_DISPLAY_SCALE   NUMERIC_MAX_PRECISION

Definition at line 40 of file numeric.h.

◆ NUMERIC_MAX_PRECISION

#define NUMERIC_MAX_PRECISION   1000

Definition at line 32 of file numeric.h.

◆ NUMERIC_MAX_RESULT_SCALE

#define NUMERIC_MAX_RESULT_SCALE   (NUMERIC_MAX_PRECISION * 2)

Definition at line 43 of file numeric.h.

◆ NUMERIC_MAX_SCALE

#define NUMERIC_MAX_SCALE   1000

Definition at line 35 of file numeric.h.

◆ NUMERIC_MIN_DISPLAY_SCALE

#define NUMERIC_MIN_DISPLAY_SCALE   0

Definition at line 41 of file numeric.h.

◆ NUMERIC_MIN_SCALE

#define NUMERIC_MIN_SCALE   (-1000)

Definition at line 34 of file numeric.h.

◆ NUMERIC_MIN_SIG_DIGITS

#define NUMERIC_MIN_SIG_DIGITS   16

Definition at line 50 of file numeric.h.

◆ PG_GETARG_NUMERIC

#define PG_GETARG_NUMERIC (   n)    DatumGetNumeric(PG_GETARG_DATUM(n))

Definition at line 78 of file numeric.h.

◆ PG_GETARG_NUMERIC_COPY

#define PG_GETARG_NUMERIC_COPY (   n)    DatumGetNumericCopy(PG_GETARG_DATUM(n))

Definition at line 79 of file numeric.h.

◆ PG_RETURN_NUMERIC

#define PG_RETURN_NUMERIC (   x)    return NumericGetDatum(x)

Definition at line 80 of file numeric.h.

Typedef Documentation

◆ Numeric

typedef struct NumericData* Numeric

Definition at line 54 of file numeric.h.

Function Documentation

◆ DatumGetNumeric()

◆ DatumGetNumericCopy()

static Numeric DatumGetNumericCopy ( Datum  X)
inlinestatic

Definition at line 67 of file numeric.h.

68{
70}
#define PG_DETOAST_DATUM_COPY(datum)
Definition: fmgr.h:242

References PG_DETOAST_DATUM_COPY.

Referenced by jsonb_numeric().

◆ int64_div_fast_to_numeric()

Numeric int64_div_fast_to_numeric ( int64  val1,
int  log10val2 
)

Definition at line 4422 of file numeric.c.

4423{
4424 Numeric res;
4425 NumericVar result;
4426 int rscale;
4427 int w;
4428 int m;
4429
4430 init_var(&result);
4431
4432 /* result scale */
4433 rscale = log10val2 < 0 ? 0 : log10val2;
4434
4435 /* how much to decrease the weight by */
4436 w = log10val2 / DEC_DIGITS;
4437 /* how much is left to divide by */
4438 m = log10val2 % DEC_DIGITS;
4439 if (m < 0)
4440 {
4441 m += DEC_DIGITS;
4442 w--;
4443 }
4444
4445 /*
4446 * If there is anything left to divide by (10^m with 0 < m < DEC_DIGITS),
4447 * multiply the dividend by 10^(DEC_DIGITS - m), and shift the weight by
4448 * one more.
4449 */
4450 if (m > 0)
4451 {
4452#if DEC_DIGITS == 4
4453 static const int pow10[] = {1, 10, 100, 1000};
4454#elif DEC_DIGITS == 2
4455 static const int pow10[] = {1, 10};
4456#elif DEC_DIGITS == 1
4457 static const int pow10[] = {1};
4458#else
4459#error unsupported NBASE
4460#endif
4461 int64 factor = pow10[DEC_DIGITS - m];
4462 int64 new_val1;
4463
4464 StaticAssertDecl(lengthof(pow10) == DEC_DIGITS, "mismatch with DEC_DIGITS");
4465
4466 if (unlikely(pg_mul_s64_overflow(val1, factor, &new_val1)))
4467 {
4468#ifdef HAVE_INT128
4469 /* do the multiplication using 128-bit integers */
4470 int128 tmp;
4471
4472 tmp = (int128) val1 * (int128) factor;
4473
4474 int128_to_numericvar(tmp, &result);
4475#else
4476 /* do the multiplication using numerics */
4477 NumericVar tmp;
4478
4479 init_var(&tmp);
4480
4481 int64_to_numericvar(val1, &result);
4482 int64_to_numericvar(factor, &tmp);
4483 mul_var(&result, &tmp, &result, 0);
4484
4485 free_var(&tmp);
4486#endif
4487 }
4488 else
4489 int64_to_numericvar(new_val1, &result);
4490
4491 w++;
4492 }
4493 else
4494 int64_to_numericvar(val1, &result);
4495
4496 result.weight -= w;
4497 result.dscale = rscale;
4498
4499 res = make_result(&result);
4500
4501 free_var(&result);
4502
4503 return res;
4504}
static void free_var(NumericVar *var)
Definition: numeric.c:7087
static void mul_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result, int rscale)
Definition: numeric.c:8787
static void int64_to_numericvar(int64 val, NumericVar *var)
Definition: numeric.c:8222
static Numeric make_result(const NumericVar *var)
Definition: numeric.c:8009
#define DEC_DIGITS
Definition: numeric.c:98
#define init_var(v)
Definition: numeric.c:494
int64_t int64
Definition: c.h:485
#define unlikely(x)
Definition: c.h:333
#define lengthof(array)
Definition: c.h:745
#define StaticAssertDecl(condition, errmessage)
Definition: c.h:893
static bool pg_mul_s64_overflow(int64 a, int64 b, int64 *result)
Definition: int.h:293
int dscale
Definition: numeric.c:318
int weight
Definition: numeric.c:316

References DEC_DIGITS, NumericVar::dscale, free_var(), init_var, int64_to_numericvar(), lengthof, make_result(), mul_var(), pg_mul_s64_overflow(), res, StaticAssertDecl, unlikely, and NumericVar::weight.

Referenced by interval_part_common(), time_part_common(), timestamp_part_common(), timestamptz_part_common(), and timetz_part_common().

◆ int64_to_numeric()

◆ numeric_add_opt_error()

Numeric numeric_add_opt_error ( Numeric  num1,
Numeric  num2,
bool *  have_error 
)

Definition at line 2985 of file numeric.c.

2986{
2987 NumericVar arg1;
2988 NumericVar arg2;
2989 NumericVar result;
2990 Numeric res;
2991
2992 /*
2993 * Handle NaN and infinities
2994 */
2995 if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
2996 {
2997 if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2998 return make_result(&const_nan);
2999 if (NUMERIC_IS_PINF(num1))
3000 {
3001 if (NUMERIC_IS_NINF(num2))
3002 return make_result(&const_nan); /* Inf + -Inf */
3003 else
3004 return make_result(&const_pinf);
3005 }
3006 if (NUMERIC_IS_NINF(num1))
3007 {
3008 if (NUMERIC_IS_PINF(num2))
3009 return make_result(&const_nan); /* -Inf + Inf */
3010 else
3011 return make_result(&const_ninf);
3012 }
3013 /* by here, num1 must be finite, so num2 is not */
3014 if (NUMERIC_IS_PINF(num2))
3015 return make_result(&const_pinf);
3016 Assert(NUMERIC_IS_NINF(num2));
3017 return make_result(&const_ninf);
3018 }
3019
3020 /*
3021 * Unpack the values, let add_var() compute the result and return it.
3022 */
3023 init_var_from_num(num1, &arg1);
3024 init_var_from_num(num2, &arg2);
3025
3026 init_var(&result);
3027 add_var(&arg1, &arg2, &result);
3028
3029 res = make_result_opt_error(&result, have_error);
3030
3031 free_var(&result);
3032
3033 return res;
3034}
static const NumericVar const_pinf
Definition: numeric.c:462
static const NumericVar const_ninf
Definition: numeric.c:465
static void add_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
Definition: numeric.c:8549
#define NUMERIC_IS_SPECIAL(n)
Definition: numeric.c:175
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:7569
#define NUMERIC_IS_PINF(n)
Definition: numeric.c:207
static Numeric make_result_opt_error(const NumericVar *var, bool *have_error)
Definition: numeric.c:7900
#define NUMERIC_IS_NINF(n)
Definition: numeric.c:208
static const NumericVar const_nan
Definition: numeric.c:459
#define NUMERIC_IS_NAN(n)
Definition: numeric.c:206
#define Assert(condition)
Definition: c.h:815

References add_var(), Assert, const_nan, const_ninf, const_pinf, free_var(), init_var, init_var_from_num(), make_result(), make_result_opt_error(), NUMERIC_IS_NAN, NUMERIC_IS_NINF, NUMERIC_IS_PINF, NUMERIC_IS_SPECIAL, and res.

Referenced by executeItemOptUnwrapTarget(), interval_part_common(), numeric_add(), timestamp_part_common(), and timestamptz_part_common().

◆ numeric_div_opt_error()

Numeric numeric_div_opt_error ( Numeric  num1,
Numeric  num2,
bool *  have_error 
)

Definition at line 3262 of file numeric.c.

3263{
3264 NumericVar arg1;
3265 NumericVar arg2;
3266 NumericVar result;
3267 Numeric res;
3268 int rscale;
3269
3270 if (have_error)
3271 *have_error = false;
3272
3273 /*
3274 * Handle NaN and infinities
3275 */
3276 if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
3277 {
3278 if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
3279 return make_result(&const_nan);
3280 if (NUMERIC_IS_PINF(num1))
3281 {
3282 if (NUMERIC_IS_SPECIAL(num2))
3283 return make_result(&const_nan); /* Inf / [-]Inf */
3284 switch (numeric_sign_internal(num2))
3285 {
3286 case 0:
3287 if (have_error)
3288 {
3289 *have_error = true;
3290 return NULL;
3291 }
3292 ereport(ERROR,
3293 (errcode(ERRCODE_DIVISION_BY_ZERO),
3294 errmsg("division by zero")));
3295 break;
3296 case 1:
3297 return make_result(&const_pinf);
3298 case -1:
3299 return make_result(&const_ninf);
3300 }
3301 Assert(false);
3302 }
3303 if (NUMERIC_IS_NINF(num1))
3304 {
3305 if (NUMERIC_IS_SPECIAL(num2))
3306 return make_result(&const_nan); /* -Inf / [-]Inf */
3307 switch (numeric_sign_internal(num2))
3308 {
3309 case 0:
3310 if (have_error)
3311 {
3312 *have_error = true;
3313 return NULL;
3314 }
3315 ereport(ERROR,
3316 (errcode(ERRCODE_DIVISION_BY_ZERO),
3317 errmsg("division by zero")));
3318 break;
3319 case 1:
3320 return make_result(&const_ninf);
3321 case -1:
3322 return make_result(&const_pinf);
3323 }
3324 Assert(false);
3325 }
3326 /* by here, num1 must be finite, so num2 is not */
3327
3328 /*
3329 * POSIX would have us return zero or minus zero if num1 is zero, and
3330 * otherwise throw an underflow error. But the numeric type doesn't
3331 * really do underflow, so let's just return zero.
3332 */
3333 return make_result(&const_zero);
3334 }
3335
3336 /*
3337 * Unpack the arguments
3338 */
3339 init_var_from_num(num1, &arg1);
3340 init_var_from_num(num2, &arg2);
3341
3342 init_var(&result);
3343
3344 /*
3345 * Select scale for division result
3346 */
3347 rscale = select_div_scale(&arg1, &arg2);
3348
3349 /*
3350 * If "have_error" is provided, check for division by zero here
3351 */
3352 if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
3353 {
3354 *have_error = true;
3355 return NULL;
3356 }
3357
3358 /*
3359 * Do the divide and return the result
3360 */
3361 div_var(&arg1, &arg2, &result, rscale, true, true);
3362
3363 res = make_result_opt_error(&result, have_error);
3364
3365 free_var(&result);
3366
3367 return res;
3368}
static int numeric_sign_internal(Numeric num)
Definition: numeric.c:1478
static int select_div_scale(const NumericVar *var1, const NumericVar *var2)
Definition: numeric.c:10134
static const NumericVar const_zero
Definition: numeric.c:425
static void div_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result, int rscale, bool round, bool exact)
Definition: numeric.c:9365
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
int ndigits
Definition: numeric.c:315
NumericDigit * digits
Definition: numeric.c:320

References Assert, const_nan, const_ninf, const_pinf, const_zero, NumericVar::digits, div_var(), ereport, errcode(), errmsg(), ERROR, free_var(), init_var, init_var_from_num(), make_result(), make_result_opt_error(), NumericVar::ndigits, NUMERIC_IS_NAN, NUMERIC_IS_NINF, NUMERIC_IS_PINF, NUMERIC_IS_SPECIAL, numeric_sign_internal(), res, and select_div_scale().

Referenced by executeItemOptUnwrapTarget(), numeric_div(), timestamp_part_common(), and timestamptz_part_common().

◆ numeric_int4_opt_error()

int32 numeric_int4_opt_error ( Numeric  num,
bool *  have_error 
)

Definition at line 4515 of file numeric.c.

4516{
4517 NumericVar x;
4518 int32 result;
4519
4520 if (have_error)
4521 *have_error = false;
4522
4523 if (NUMERIC_IS_SPECIAL(num))
4524 {
4525 if (have_error)
4526 {
4527 *have_error = true;
4528 return 0;
4529 }
4530 else
4531 {
4532 if (NUMERIC_IS_NAN(num))
4533 ereport(ERROR,
4534 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4535 errmsg("cannot convert NaN to %s", "integer")));
4536 else
4537 ereport(ERROR,
4538 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4539 errmsg("cannot convert infinity to %s", "integer")));
4540 }
4541 }
4542
4543 /* Convert to variable format, then convert to int4 */
4544 init_var_from_num(num, &x);
4545
4546 if (!numericvar_to_int32(&x, &result))
4547 {
4548 if (have_error)
4549 {
4550 *have_error = true;
4551 return 0;
4552 }
4553 else
4554 {
4555 ereport(ERROR,
4556 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4557 errmsg("integer out of range")));
4558 }
4559 }
4560
4561 return result;
4562}
static bool numericvar_to_int32(const NumericVar *var, int32 *result)
Definition: numeric.c:4578
int32_t int32
Definition: c.h:484
int x
Definition: isn.c:70

References ereport, errcode(), errmsg(), ERROR, init_var_from_num(), NUMERIC_IS_NAN, NUMERIC_IS_SPECIAL, numericvar_to_int32(), and x.

Referenced by executeDateTimeMethod(), executeItemOptUnwrapTarget(), getArrayIndex(), numeric_int4(), and numeric_to_char().

◆ numeric_int8_opt_error()

int64 numeric_int8_opt_error ( Numeric  num,
bool *  have_error 
)

Definition at line 4603 of file numeric.c.

4604{
4605 NumericVar x;
4606 int64 result;
4607
4608 if (have_error)
4609 *have_error = false;
4610
4611 if (NUMERIC_IS_SPECIAL(num))
4612 {
4613 if (have_error)
4614 {
4615 *have_error = true;
4616 return 0;
4617 }
4618 else
4619 {
4620 if (NUMERIC_IS_NAN(num))
4621 ereport(ERROR,
4622 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4623 errmsg("cannot convert NaN to %s", "bigint")));
4624 else
4625 ereport(ERROR,
4626 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4627 errmsg("cannot convert infinity to %s", "bigint")));
4628 }
4629 }
4630
4631 /* Convert to variable format, then convert to int8 */
4632 init_var_from_num(num, &x);
4633
4634 if (!numericvar_to_int64(&x, &result))
4635 {
4636 if (have_error)
4637 {
4638 *have_error = true;
4639 return 0;
4640 }
4641 else
4642 {
4643 ereport(ERROR,
4644 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4645 errmsg("bigint out of range")));
4646 }
4647 }
4648
4649 return result;
4650}
static bool numericvar_to_int64(const NumericVar *var, int64 *result)
Definition: numeric.c:8147

References ereport, errcode(), errmsg(), ERROR, init_var_from_num(), NUMERIC_IS_NAN, NUMERIC_IS_SPECIAL, numericvar_to_int64(), and x.

Referenced by executeItemOptUnwrapTarget(), and numeric_int8().

◆ numeric_is_inf()

bool numeric_is_inf ( Numeric  num)

Definition at line 862 of file numeric.c.

863{
864 return NUMERIC_IS_INF(num);
865}
#define NUMERIC_IS_INF(n)
Definition: numeric.c:209

References NUMERIC_IS_INF.

Referenced by executeItemOptUnwrapTarget(), and PLyNumber_ToJsonbValue().

◆ numeric_is_nan()

bool numeric_is_nan ( Numeric  num)

Definition at line 851 of file numeric.c.

852{
853 return NUMERIC_IS_NAN(num);
854}

References NUMERIC_IS_NAN.

Referenced by executeItemOptUnwrapTarget(), gbt_numeric_penalty(), pg_lsn_mii(), pg_lsn_pli(), and PLyNumber_ToJsonbValue().

◆ numeric_maximum_size()

int32 numeric_maximum_size ( int32  typmod)

Definition at line 953 of file numeric.c.

954{
955 int precision;
956 int numeric_digits;
957
958 if (!is_valid_numeric_typmod(typmod))
959 return -1;
960
961 /* precision (ie, max # of digits) is in upper bits of typmod */
962 precision = numeric_typmod_precision(typmod);
963
964 /*
965 * This formula computes the maximum number of NumericDigits we could need
966 * in order to store the specified number of decimal digits. Because the
967 * weight is stored as a number of NumericDigits rather than a number of
968 * decimal digits, it's possible that the first NumericDigit will contain
969 * only a single decimal digit. Thus, the first two decimal digits can
970 * require two NumericDigits to store, but it isn't until we reach
971 * DEC_DIGITS + 2 decimal digits that we potentially need a third
972 * NumericDigit.
973 */
974 numeric_digits = (precision + 2 * (DEC_DIGITS - 1)) / DEC_DIGITS;
975
976 /*
977 * In most cases, the size of a numeric will be smaller than the value
978 * computed below, because the varlena header will typically get toasted
979 * down to a single byte before being stored on disk, and it may also be
980 * possible to use a short numeric header. But our job here is to compute
981 * the worst case.
982 */
983 return NUMERIC_HDRSZ + (numeric_digits * sizeof(NumericDigit));
984}
static bool is_valid_numeric_typmod(int32 typmod)
Definition: numeric.c:916
int16 NumericDigit
Definition: numeric.c:102
#define NUMERIC_HDRSZ
Definition: numeric.c:177
static int numeric_typmod_precision(int32 typmod)
Definition: numeric.c:927

References DEC_DIGITS, is_valid_numeric_typmod(), NUMERIC_HDRSZ, and numeric_typmod_precision().

Referenced by type_maximum_size().

◆ numeric_mod_opt_error()

Numeric numeric_mod_opt_error ( Numeric  num1,
Numeric  num2,
bool *  have_error 
)

Definition at line 3486 of file numeric.c.

3487{
3488 Numeric res;
3489 NumericVar arg1;
3490 NumericVar arg2;
3491 NumericVar result;
3492
3493 if (have_error)
3494 *have_error = false;
3495
3496 /*
3497 * Handle NaN and infinities. We follow POSIX fmod() on this, except that
3498 * POSIX treats x-is-infinite and y-is-zero identically, raising EDOM and
3499 * returning NaN. We choose to throw error only for y-is-zero.
3500 */
3501 if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
3502 {
3503 if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
3504 return make_result(&const_nan);
3505 if (NUMERIC_IS_INF(num1))
3506 {
3507 if (numeric_sign_internal(num2) == 0)
3508 {
3509 if (have_error)
3510 {
3511 *have_error = true;
3512 return NULL;
3513 }
3514 ereport(ERROR,
3515 (errcode(ERRCODE_DIVISION_BY_ZERO),
3516 errmsg("division by zero")));
3517 }
3518 /* Inf % any nonzero = NaN */
3519 return make_result(&const_nan);
3520 }
3521 /* num2 must be [-]Inf; result is num1 regardless of sign of num2 */
3522 return duplicate_numeric(num1);
3523 }
3524
3525 init_var_from_num(num1, &arg1);
3526 init_var_from_num(num2, &arg2);
3527
3528 init_var(&result);
3529
3530 /*
3531 * If "have_error" is provided, check for division by zero here
3532 */
3533 if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
3534 {
3535 *have_error = true;
3536 return NULL;
3537 }
3538
3539 mod_var(&arg1, &arg2, &result);
3540
3541 res = make_result_opt_error(&result, NULL);
3542
3543 free_var(&result);
3544
3545 return res;
3546}
static void mod_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
Definition: numeric.c:10203
static Numeric duplicate_numeric(Numeric num)
Definition: numeric.c:7881

References const_nan, NumericVar::digits, duplicate_numeric(), ereport, errcode(), errmsg(), ERROR, free_var(), init_var, init_var_from_num(), make_result(), make_result_opt_error(), mod_var(), NumericVar::ndigits, NUMERIC_IS_INF, NUMERIC_IS_NAN, NUMERIC_IS_SPECIAL, numeric_sign_internal(), and res.

Referenced by executeItemOptUnwrapTarget(), and numeric_mod().

◆ numeric_mul_opt_error()

Numeric numeric_mul_opt_error ( Numeric  num1,
Numeric  num2,
bool *  have_error 
)

Definition at line 3141 of file numeric.c.

3142{
3143 NumericVar arg1;
3144 NumericVar arg2;
3145 NumericVar result;
3146 Numeric res;
3147
3148 /*
3149 * Handle NaN and infinities
3150 */
3151 if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
3152 {
3153 if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
3154 return make_result(&const_nan);
3155 if (NUMERIC_IS_PINF(num1))
3156 {
3157 switch (numeric_sign_internal(num2))
3158 {
3159 case 0:
3160 return make_result(&const_nan); /* Inf * 0 */
3161 case 1:
3162 return make_result(&const_pinf);
3163 case -1:
3164 return make_result(&const_ninf);
3165 }
3166 Assert(false);
3167 }
3168 if (NUMERIC_IS_NINF(num1))
3169 {
3170 switch (numeric_sign_internal(num2))
3171 {
3172 case 0:
3173 return make_result(&const_nan); /* -Inf * 0 */
3174 case 1:
3175 return make_result(&const_ninf);
3176 case -1:
3177 return make_result(&const_pinf);
3178 }
3179 Assert(false);
3180 }
3181 /* by here, num1 must be finite, so num2 is not */
3182 if (NUMERIC_IS_PINF(num2))
3183 {
3184 switch (numeric_sign_internal(num1))
3185 {
3186 case 0:
3187 return make_result(&const_nan); /* 0 * Inf */
3188 case 1:
3189 return make_result(&const_pinf);
3190 case -1:
3191 return make_result(&const_ninf);
3192 }
3193 Assert(false);
3194 }
3195 Assert(NUMERIC_IS_NINF(num2));
3196 switch (numeric_sign_internal(num1))
3197 {
3198 case 0:
3199 return make_result(&const_nan); /* 0 * -Inf */
3200 case 1:
3201 return make_result(&const_ninf);
3202 case -1:
3203 return make_result(&const_pinf);
3204 }
3205 Assert(false);
3206 }
3207
3208 /*
3209 * Unpack the values, let mul_var() compute the result and return it.
3210 * Unlike add_var() and sub_var(), mul_var() will round its result. In the
3211 * case of numeric_mul(), which is invoked for the * operator on numerics,
3212 * we request exact representation for the product (rscale = sum(dscale of
3213 * arg1, dscale of arg2)). If the exact result has more digits after the
3214 * decimal point than can be stored in a numeric, we round it. Rounding
3215 * after computing the exact result ensures that the final result is
3216 * correctly rounded (rounding in mul_var() using a truncated product
3217 * would not guarantee this).
3218 */
3219 init_var_from_num(num1, &arg1);
3220 init_var_from_num(num2, &arg2);
3221
3222 init_var(&result);
3223 mul_var(&arg1, &arg2, &result, arg1.dscale + arg2.dscale);
3224
3225 if (result.dscale > NUMERIC_DSCALE_MAX)
3226 round_var(&result, NUMERIC_DSCALE_MAX);
3227
3228 res = make_result_opt_error(&result, have_error);
3229
3230 free_var(&result);
3231
3232 return res;
3233}
#define NUMERIC_DSCALE_MAX
Definition: numeric.c:237
static void round_var(NumericVar *var, int rscale)
Definition: numeric.c:12108

References Assert, const_nan, const_ninf, const_pinf, NumericVar::dscale, free_var(), init_var, init_var_from_num(), make_result(), make_result_opt_error(), mul_var(), NUMERIC_DSCALE_MAX, NUMERIC_IS_NAN, NUMERIC_IS_NINF, NUMERIC_IS_PINF, NUMERIC_IS_SPECIAL, numeric_sign_internal(), res, and round_var().

Referenced by executeItemOptUnwrapTarget(), and numeric_mul().

◆ numeric_normalize()

char * numeric_normalize ( Numeric  num)

Definition at line 1026 of file numeric.c.

1027{
1028 NumericVar x;
1029 char *str;
1030 int last;
1031
1032 /*
1033 * Handle NaN and infinities
1034 */
1035 if (NUMERIC_IS_SPECIAL(num))
1036 {
1037 if (NUMERIC_IS_PINF(num))
1038 return pstrdup("Infinity");
1039 else if (NUMERIC_IS_NINF(num))
1040 return pstrdup("-Infinity");
1041 else
1042 return pstrdup("NaN");
1043 }
1044
1045 init_var_from_num(num, &x);
1046
1048
1049 /* If there's no decimal point, there's certainly nothing to remove. */
1050 if (strchr(str, '.') != NULL)
1051 {
1052 /*
1053 * Back up over trailing fractional zeroes. Since there is a decimal
1054 * point, this loop will terminate safely.
1055 */
1056 last = strlen(str) - 1;
1057 while (str[last] == '0')
1058 last--;
1059
1060 /* We want to get rid of the decimal point too, if it's now last. */
1061 if (str[last] == '.')
1062 last--;
1063
1064 /* Delete whatever we backed up over. */
1065 str[last + 1] = '\0';
1066 }
1067
1068 return str;
1069}
static char * get_str_from_var(const NumericVar *var)
Definition: numeric.c:7612
const char * str
char * pstrdup(const char *in)
Definition: mcxt.c:1696

References get_str_from_var(), init_var_from_num(), NUMERIC_IS_NINF, NUMERIC_IS_PINF, NUMERIC_IS_SPECIAL, pstrdup(), str, and x.

Referenced by make_scalar_key().

◆ numeric_out_sci()

char * numeric_out_sci ( Numeric  num,
int  scale 
)

Definition at line 992 of file numeric.c.

993{
995 char *str;
996
997 /*
998 * Handle NaN and infinities
999 */
1000 if (NUMERIC_IS_SPECIAL(num))
1001 {
1002 if (NUMERIC_IS_PINF(num))
1003 return pstrdup("Infinity");
1004 else if (NUMERIC_IS_NINF(num))
1005 return pstrdup("-Infinity");
1006 else
1007 return pstrdup("NaN");
1008 }
1009
1010 init_var_from_num(num, &x);
1011
1013
1014 return str;
1015}
static char * get_str_from_var_sci(const NumericVar *var, int rscale)
Definition: numeric.c:7765
static int scale
Definition: pgbench.c:181

References get_str_from_var_sci(), init_var_from_num(), NUMERIC_IS_NINF, NUMERIC_IS_PINF, NUMERIC_IS_SPECIAL, pstrdup(), scale, str, and x.

Referenced by int8_to_char(), and numeric_to_char().

◆ numeric_sub_opt_error()

Numeric numeric_sub_opt_error ( Numeric  num1,
Numeric  num2,
bool *  have_error 
)

Definition at line 3063 of file numeric.c.

3064{
3065 NumericVar arg1;
3066 NumericVar arg2;
3067 NumericVar result;
3068 Numeric res;
3069
3070 /*
3071 * Handle NaN and infinities
3072 */
3073 if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
3074 {
3075 if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
3076 return make_result(&const_nan);
3077 if (NUMERIC_IS_PINF(num1))
3078 {
3079 if (NUMERIC_IS_PINF(num2))
3080 return make_result(&const_nan); /* Inf - Inf */
3081 else
3082 return make_result(&const_pinf);
3083 }
3084 if (NUMERIC_IS_NINF(num1))
3085 {
3086 if (NUMERIC_IS_NINF(num2))
3087 return make_result(&const_nan); /* -Inf - -Inf */
3088 else
3089 return make_result(&const_ninf);
3090 }
3091 /* by here, num1 must be finite, so num2 is not */
3092 if (NUMERIC_IS_PINF(num2))
3093 return make_result(&const_ninf);
3094 Assert(NUMERIC_IS_NINF(num2));
3095 return make_result(&const_pinf);
3096 }
3097
3098 /*
3099 * Unpack the values, let sub_var() compute the result and return it.
3100 */
3101 init_var_from_num(num1, &arg1);
3102 init_var_from_num(num2, &arg2);
3103
3104 init_var(&result);
3105 sub_var(&arg1, &arg2, &result);
3106
3107 res = make_result_opt_error(&result, have_error);
3108
3109 free_var(&result);
3110
3111 return res;
3112}
static void sub_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
Definition: numeric.c:8666

References Assert, const_nan, const_ninf, const_pinf, free_var(), init_var, init_var_from_num(), make_result(), make_result_opt_error(), NUMERIC_IS_NAN, NUMERIC_IS_NINF, NUMERIC_IS_PINF, NUMERIC_IS_SPECIAL, res, and sub_var().

Referenced by executeItemOptUnwrapTarget(), numeric_sub(), timestamp_part_common(), and timestamptz_part_common().

◆ NumericGetDatum()

◆ random_numeric()

Numeric random_numeric ( pg_prng_state state,
Numeric  rmin,
Numeric  rmax 
)

Definition at line 4346 of file numeric.c.

4347{
4348 NumericVar rmin_var;
4349 NumericVar rmax_var;
4350 NumericVar result;
4351 Numeric res;
4352
4353 /* Range bounds must not be NaN/infinity */
4354 if (NUMERIC_IS_SPECIAL(rmin))
4355 {
4356 if (NUMERIC_IS_NAN(rmin))
4357 ereport(ERROR,
4358 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4359 errmsg("lower bound cannot be NaN"));
4360 else
4361 ereport(ERROR,
4362 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4363 errmsg("lower bound cannot be infinity"));
4364 }
4365 if (NUMERIC_IS_SPECIAL(rmax))
4366 {
4367 if (NUMERIC_IS_NAN(rmax))
4368 ereport(ERROR,
4369 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4370 errmsg("upper bound cannot be NaN"));
4371 else
4372 ereport(ERROR,
4373 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4374 errmsg("upper bound cannot be infinity"));
4375 }
4376
4377 /* Return a random value in the range [rmin, rmax] */
4378 init_var_from_num(rmin, &rmin_var);
4379 init_var_from_num(rmax, &rmax_var);
4380
4381 init_var(&result);
4382
4383 random_var(state, &rmin_var, &rmax_var, &result);
4384
4385 res = make_result(&result);
4386
4387 free_var(&result);
4388
4389 return res;
4390}
static void random_var(pg_prng_state *state, const NumericVar *rmin, const NumericVar *rmax, NumericVar *result)
Definition: numeric.c:11680
Definition: regguts.h:323

References ereport, errcode(), errmsg(), ERROR, free_var(), init_var, init_var_from_num(), make_result(), NUMERIC_IS_NAN, NUMERIC_IS_SPECIAL, random_var(), and res.

Referenced by numeric_random().