PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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 Node Node
 
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)
 
charnumeric_out_sci (Numeric num, int scale)
 
charnumeric_normalize (Numeric num)
 
Numeric int64_to_numeric (int64 val)
 
Numeric int64_div_fast_to_numeric (int64 val1, int log10val2)
 
Numeric numeric_add_safe (Numeric num1, Numeric num2, Node *escontext)
 
Numeric numeric_sub_safe (Numeric num1, Numeric num2, Node *escontext)
 
Numeric numeric_mul_safe (Numeric num1, Numeric num2, Node *escontext)
 
Numeric numeric_div_safe (Numeric num1, Numeric num2, Node *escontext)
 
Numeric numeric_mod_safe (Numeric num1, Numeric num2, Node *escontext)
 
int32 numeric_int4_safe (Numeric num, Node *escontext)
 
int64 numeric_int8_safe (Numeric num, Node *escontext)
 
int32 make_numeric_typmod_safe (int32 precision, int32 scale, Node *escontext)
 
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 43 of file numeric.h.

◆ NUMERIC_MAX_PRECISION

#define NUMERIC_MAX_PRECISION   1000

Definition at line 35 of file numeric.h.

◆ NUMERIC_MAX_RESULT_SCALE

#define NUMERIC_MAX_RESULT_SCALE   (NUMERIC_MAX_PRECISION * 2)

Definition at line 46 of file numeric.h.

◆ NUMERIC_MAX_SCALE

#define NUMERIC_MAX_SCALE   1000

Definition at line 38 of file numeric.h.

◆ NUMERIC_MIN_DISPLAY_SCALE

#define NUMERIC_MIN_DISPLAY_SCALE   0

Definition at line 44 of file numeric.h.

◆ NUMERIC_MIN_SCALE

#define NUMERIC_MIN_SCALE   (-1000)

Definition at line 37 of file numeric.h.

◆ NUMERIC_MIN_SIG_DIGITS

#define NUMERIC_MIN_SIG_DIGITS   16

Definition at line 53 of file numeric.h.

◆ PG_GETARG_NUMERIC

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

Definition at line 81 of file numeric.h.

◆ PG_GETARG_NUMERIC_COPY

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

Definition at line 82 of file numeric.h.

◆ PG_RETURN_NUMERIC

#define PG_RETURN_NUMERIC (   x)    return NumericGetDatum(x)

Definition at line 83 of file numeric.h.

Typedef Documentation

◆ Node

typedef struct Node Node

Definition at line 21 of file numeric.h.

◆ Numeric

Definition at line 57 of file numeric.h.

Function Documentation

◆ DatumGetNumeric()

◆ DatumGetNumericCopy()

static Numeric DatumGetNumericCopy ( Datum  X)
inlinestatic

Definition at line 70 of file numeric.h.

71{
73}
#define PG_DETOAST_DATUM_COPY(datum)
Definition fmgr.h:242

References fb(), and PG_DETOAST_DATUM_COPY.

Referenced by jsonb_numeric().

◆ int64_div_fast_to_numeric()

Numeric int64_div_fast_to_numeric ( int64  val1,
int  log10val2 
)
extern

Definition at line 4291 of file numeric.c.

4292{
4293 Numeric res;
4295 int rscale;
4296 int w;
4297 int m;
4298
4299 init_var(&result);
4300
4301 /* result scale */
4302 rscale = log10val2 < 0 ? 0 : log10val2;
4303
4304 /* how much to decrease the weight by */
4305 w = log10val2 / DEC_DIGITS;
4306 /* how much is left to divide by */
4307 m = log10val2 % DEC_DIGITS;
4308 if (m < 0)
4309 {
4310 m += DEC_DIGITS;
4311 w--;
4312 }
4313
4314 /*
4315 * If there is anything left to divide by (10^m with 0 < m < DEC_DIGITS),
4316 * multiply the dividend by 10^(DEC_DIGITS - m), and shift the weight by
4317 * one more.
4318 */
4319 if (m > 0)
4320 {
4321#if DEC_DIGITS == 4
4322 static const int pow10[] = {1, 10, 100, 1000};
4323#elif DEC_DIGITS == 2
4324 static const int pow10[] = {1, 10};
4325#elif DEC_DIGITS == 1
4326 static const int pow10[] = {1};
4327#else
4328#error unsupported NBASE
4329#endif
4332
4333 StaticAssertDecl(lengthof(pow10) == DEC_DIGITS, "mismatch with DEC_DIGITS");
4334
4336 {
4337 /* do the multiplication using 128-bit integers */
4338 INT128 tmp;
4339
4340 tmp = int64_to_int128(0);
4342
4344 }
4345 else
4347
4348 w++;
4349 }
4350 else
4352
4353 result.weight -= w;
4354 result.dscale = rscale;
4355
4356 res = make_result(&result);
4357
4358 free_var(&result);
4359
4360 return res;
4361}
static void free_var(NumericVar *var)
Definition numeric.c:6735
static void int64_to_numericvar(int64 val, NumericVar *var)
Definition numeric.c:7854
static Numeric make_result(const NumericVar *var)
Definition numeric.c:7641
#define DEC_DIGITS
Definition numeric.c:99
static void int128_to_numericvar(INT128 val, NumericVar *var)
Definition numeric.c:7971
#define init_var(v)
Definition numeric.c:486
int64_t int64
Definition c.h:680
#define unlikely(x)
Definition c.h:497
#define lengthof(array)
Definition c.h:932
#define StaticAssertDecl(condition, errmessage)
Definition c.h:1067
uint32 result
static INT128 int64_to_int128(int64 v)
Definition int128.h:450
static void int128_add_int64_mul_int64(INT128 *i128, int64 x, int64 y)
Definition int128.h:203
static bool pg_mul_s64_overflow(int64 a, int64 b, int64 *result)
Definition int.h:293

References DEC_DIGITS, fb(), free_var(), init_var, int128_add_int64_mul_int64(), int128_to_numericvar(), int64_to_int128(), int64_to_numericvar(), lengthof, make_result(), pg_mul_s64_overflow(), result, StaticAssertDecl, and unlikely.

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

◆ int64_to_numeric()

◆ make_numeric_typmod_safe()

int32 make_numeric_typmod_safe ( int32  precision,
int32  scale,
Node escontext 
)
extern

Definition at line 1315 of file numeric.c.

1316{
1318 ereturn(escontext, -1,
1320 errmsg("NUMERIC precision %d must be between 1 and %d",
1321 precision, NUMERIC_MAX_PRECISION)));
1323 ereturn(escontext, -1,
1325 errmsg("NUMERIC scale %d must be between %d and %d",
1327
1328 return make_numeric_typmod(precision, scale);
1329}
static int32 make_numeric_typmod(int precision, int scale)
Definition numeric.c:890
int errcode(int sqlerrcode)
Definition elog.c:875
#define ereturn(context, dummy_value,...)
Definition elog.h:280
#define NUMERIC_MIN_SCALE
Definition numeric.h:37
#define NUMERIC_MAX_PRECISION
Definition numeric.h:35
#define NUMERIC_MAX_SCALE
Definition numeric.h:38
static char * errmsg
static int scale
Definition pgbench.c:182

References ereturn, errcode(), errmsg, fb(), make_numeric_typmod(), NUMERIC_MAX_PRECISION, NUMERIC_MAX_SCALE, NUMERIC_MIN_SCALE, and scale.

Referenced by executeItemOptUnwrapTarget(), and numerictypmodin().

◆ numeric_add_safe()

Numeric numeric_add_safe ( Numeric  num1,
Numeric  num2,
Node escontext 
)
extern

Definition at line 2889 of file numeric.c.

2890{
2894 Numeric res;
2895
2896 /*
2897 * Handle NaN and infinities
2898 */
2900 {
2902 return make_result(&const_nan);
2903 if (NUMERIC_IS_PINF(num1))
2904 {
2905 if (NUMERIC_IS_NINF(num2))
2906 return make_result(&const_nan); /* Inf + -Inf */
2907 else
2908 return make_result(&const_pinf);
2909 }
2910 if (NUMERIC_IS_NINF(num1))
2911 {
2912 if (NUMERIC_IS_PINF(num2))
2913 return make_result(&const_nan); /* -Inf + Inf */
2914 else
2915 return make_result(&const_ninf);
2916 }
2917 /* by here, num1 must be finite, so num2 is not */
2918 if (NUMERIC_IS_PINF(num2))
2919 return make_result(&const_pinf);
2921 return make_result(&const_ninf);
2922 }
2923
2924 /*
2925 * Unpack the values, let add_var() compute the result and return it.
2926 */
2929
2930 init_var(&result);
2931 add_var(&arg1, &arg2, &result);
2932
2933 res = make_result_safe(&result, escontext);
2934
2935 free_var(&result);
2936
2937 return res;
2938}
static const NumericVar const_pinf
Definition numeric.c:454
static Numeric make_result_safe(const NumericVar *var, Node *escontext)
Definition numeric.c:7545
static const NumericVar const_ninf
Definition numeric.c:457
static void add_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
Definition numeric.c:8097
#define NUMERIC_IS_SPECIAL(n)
Definition numeric.c:176
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition numeric.c:7217
#define NUMERIC_IS_PINF(n)
Definition numeric.c:208
#define NUMERIC_IS_NINF(n)
Definition numeric.c:209
static const NumericVar const_nan
Definition numeric.c:451
#define NUMERIC_IS_NAN(n)
Definition numeric.c:207
#define Assert(condition)
Definition c.h:1002

References add_var(), Assert, const_nan, const_ninf, const_pinf, fb(), free_var(), init_var, init_var_from_num(), make_result(), make_result_safe(), NUMERIC_IS_NAN, NUMERIC_IS_NINF, NUMERIC_IS_PINF, NUMERIC_IS_SPECIAL, and result.

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

◆ numeric_div_safe()

Numeric numeric_div_safe ( Numeric  num1,
Numeric  num2,
Node escontext 
)
extern

Definition at line 3163 of file numeric.c.

3164{
3168 Numeric res;
3169 int rscale;
3170
3171 /*
3172 * Handle NaN and infinities
3173 */
3175 {
3177 return make_result(&const_nan);
3178 if (NUMERIC_IS_PINF(num1))
3179 {
3181 return make_result(&const_nan); /* Inf / [-]Inf */
3182 switch (numeric_sign_internal(num2))
3183 {
3184 case 0:
3185 goto division_by_zero;
3186 case 1:
3187 return make_result(&const_pinf);
3188 case -1:
3189 return make_result(&const_ninf);
3190 }
3191 Assert(false);
3192 }
3193 if (NUMERIC_IS_NINF(num1))
3194 {
3196 return make_result(&const_nan); /* -Inf / [-]Inf */
3197 switch (numeric_sign_internal(num2))
3198 {
3199 case 0:
3200 goto division_by_zero;
3201 case 1:
3202 return make_result(&const_ninf);
3203 case -1:
3204 return make_result(&const_pinf);
3205 }
3206 Assert(false);
3207 }
3208 /* by here, num1 must be finite, so num2 is not */
3209
3210 /*
3211 * POSIX would have us return zero or minus zero if num1 is zero, and
3212 * otherwise throw an underflow error. But the numeric type doesn't
3213 * really do underflow, so let's just return zero.
3214 */
3215 return make_result(&const_zero);
3216 }
3217
3218 /*
3219 * Unpack the arguments
3220 */
3223
3224 init_var(&result);
3225
3226 /*
3227 * Select scale for division result
3228 */
3229 rscale = select_div_scale(&arg1, &arg2);
3230
3231 /* Check for division by zero */
3232 if (arg2.ndigits == 0 || arg2.digits[0] == 0)
3233 goto division_by_zero;
3234
3235 /*
3236 * Do the divide and return the result
3237 */
3238 div_var(&arg1, &arg2, &result, rscale, true, true);
3239
3240 res = make_result_safe(&result, escontext);
3241
3242 free_var(&result);
3243
3244 return res;
3245
3247 ereturn(escontext, NULL,
3249 errmsg("division by zero"));
3250}
static int numeric_sign_internal(Numeric num)
Definition numeric.c:1469
static int select_div_scale(const NumericVar *var1, const NumericVar *var2)
Definition numeric.c:9682
static const NumericVar const_zero
Definition numeric.c:417
static void div_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result, int rscale, bool round, bool exact)
Definition numeric.c:8913

References Assert, const_nan, const_ninf, const_pinf, const_zero, div_var(), ereturn, errcode(), errmsg, fb(), free_var(), init_var, init_var_from_num(), make_result(), make_result_safe(), NUMERIC_IS_NAN, NUMERIC_IS_NINF, NUMERIC_IS_PINF, NUMERIC_IS_SPECIAL, numeric_sign_internal(), result, and select_div_scale().

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

◆ numeric_int4_safe()

int32 numeric_int4_safe ( Numeric  num,
Node escontext 
)
extern

Definition at line 4375 of file numeric.c.

4376{
4377 NumericVar x;
4378 int32 result;
4379
4380 if (NUMERIC_IS_SPECIAL(num))
4381 {
4382 if (NUMERIC_IS_NAN(num))
4383 ereturn(escontext, 0,
4385 errmsg("cannot convert NaN to %s", "integer")));
4386 else
4387 ereturn(escontext, 0,
4389 errmsg("cannot convert infinity to %s", "integer")));
4390 }
4391
4392 /* Convert to variable format, then convert to int4 */
4393 init_var_from_num(num, &x);
4394
4395 if (!numericvar_to_int32(&x, &result))
4396 ereturn(escontext, 0,
4398 errmsg("integer out of range")));
4399
4400 return result;
4401}
static bool numericvar_to_int32(const NumericVar *var, int32 *result)
Definition numeric.c:4423
int32_t int32
Definition c.h:679
int x
Definition isn.c:75

References ereturn, errcode(), errmsg, fb(), init_var_from_num(), NUMERIC_IS_NAN, NUMERIC_IS_SPECIAL, numericvar_to_int32(), result, and x.

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

◆ numeric_int8_safe()

int64 numeric_int8_safe ( Numeric  num,
Node escontext 
)
extern

Definition at line 4451 of file numeric.c.

4452{
4453 NumericVar x;
4454 int64 result;
4455
4456 if (NUMERIC_IS_SPECIAL(num))
4457 {
4458 if (NUMERIC_IS_NAN(num))
4459 ereturn(escontext, 0,
4461 errmsg("cannot convert NaN to %s", "bigint")));
4462 else
4463 ereturn(escontext, 0,
4465 errmsg("cannot convert infinity to %s", "bigint")));
4466 }
4467
4468 /* Convert to variable format, then convert to int8 */
4469 init_var_from_num(num, &x);
4470
4471 if (!numericvar_to_int64(&x, &result))
4472 ereturn(escontext, 0,
4474 errmsg("bigint out of range")));
4475
4476 return result;
4477}
static bool numericvar_to_int64(const NumericVar *var, int64 *result)
Definition numeric.c:7779

References ereturn, errcode(), errmsg, fb(), init_var_from_num(), NUMERIC_IS_NAN, NUMERIC_IS_SPECIAL, numericvar_to_int64(), result, and x.

Referenced by executeItemOptUnwrapTarget(), numeric_cash(), and numeric_int8().

◆ numeric_is_inf()

bool numeric_is_inf ( Numeric  num)
extern

Definition at line 845 of file numeric.c.

846{
847 return NUMERIC_IS_INF(num);
848}
#define NUMERIC_IS_INF(n)
Definition numeric.c:210

References NUMERIC_IS_INF.

Referenced by datum_to_jsonb_internal(), executeItemOptUnwrapTarget(), and PLyNumber_ToJsonbValue().

◆ numeric_is_nan()

bool numeric_is_nan ( Numeric  num)
extern

◆ numeric_maximum_size()

int32 numeric_maximum_size ( int32  typmod)
extern

Definition at line 936 of file numeric.c.

937{
938 int precision;
939 int numeric_digits;
940
941 if (!is_valid_numeric_typmod(typmod))
942 return -1;
943
944 /* precision (ie, max # of digits) is in upper bits of typmod */
945 precision = numeric_typmod_precision(typmod);
946
947 /*
948 * This formula computes the maximum number of NumericDigits we could need
949 * in order to store the specified number of decimal digits. Because the
950 * weight is stored as a number of NumericDigits rather than a number of
951 * decimal digits, it's possible that the first NumericDigit will contain
952 * only a single decimal digit. Thus, the first two decimal digits can
953 * require two NumericDigits to store, but it isn't until we reach
954 * DEC_DIGITS + 2 decimal digits that we potentially need a third
955 * NumericDigit.
956 */
957 numeric_digits = (precision + 2 * (DEC_DIGITS - 1)) / DEC_DIGITS;
958
959 /*
960 * In most cases, the size of a numeric will be smaller than the value
961 * computed below, because the varlena header will typically get toasted
962 * down to a single byte before being stored on disk, and it may also be
963 * possible to use a short numeric header. But our job here is to compute
964 * the worst case.
965 */
966 return NUMERIC_HDRSZ + (numeric_digits * sizeof(NumericDigit));
967}
static bool is_valid_numeric_typmod(int32 typmod)
Definition numeric.c:899
int16 NumericDigit
Definition numeric.c:103
#define NUMERIC_HDRSZ
Definition numeric.c:178
static int numeric_typmod_precision(int32 typmod)
Definition numeric.c:910

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

Referenced by type_maximum_size().

◆ numeric_mod_safe()

Numeric numeric_mod_safe ( Numeric  num1,
Numeric  num2,
Node escontext 
)
extern

Definition at line 3366 of file numeric.c.

3367{
3368 Numeric res;
3372
3373 /*
3374 * Handle NaN and infinities. We follow POSIX fmod() on this, except that
3375 * POSIX treats x-is-infinite and y-is-zero identically, raising EDOM and
3376 * returning NaN. We choose to throw error only for y-is-zero.
3377 */
3379 {
3381 return make_result(&const_nan);
3382 if (NUMERIC_IS_INF(num1))
3383 {
3384 if (numeric_sign_internal(num2) == 0)
3385 goto division_by_zero;
3386
3387 /* Inf % any nonzero = NaN */
3388 return make_result(&const_nan);
3389 }
3390 /* num2 must be [-]Inf; result is num1 regardless of sign of num2 */
3391 return duplicate_numeric(num1);
3392 }
3393
3396
3397 init_var(&result);
3398
3399 /* Check for division by zero */
3400 if (arg2.ndigits == 0 || arg2.digits[0] == 0)
3401 goto division_by_zero;
3402
3403 mod_var(&arg1, &arg2, &result);
3404
3405 res = make_result_safe(&result, escontext);
3406
3407 free_var(&result);
3408
3409 return res;
3410
3412 ereturn(escontext, NULL,
3414 errmsg("division by zero"));
3415}
static void mod_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
Definition numeric.c:9751
static Numeric duplicate_numeric(Numeric num)
Definition numeric.c:7529

References const_nan, duplicate_numeric(), ereturn, errcode(), errmsg, fb(), free_var(), init_var, init_var_from_num(), make_result(), make_result_safe(), mod_var(), NUMERIC_IS_INF, NUMERIC_IS_NAN, NUMERIC_IS_SPECIAL, numeric_sign_internal(), and result.

Referenced by executeItemOptUnwrapTarget(), and numeric_mod().

◆ numeric_mul_safe()

Numeric numeric_mul_safe ( Numeric  num1,
Numeric  num2,
Node escontext 
)
extern

Definition at line 3044 of file numeric.c.

3045{
3049 Numeric res;
3050
3051 /*
3052 * Handle NaN and infinities
3053 */
3055 {
3057 return make_result(&const_nan);
3058 if (NUMERIC_IS_PINF(num1))
3059 {
3060 switch (numeric_sign_internal(num2))
3061 {
3062 case 0:
3063 return make_result(&const_nan); /* Inf * 0 */
3064 case 1:
3065 return make_result(&const_pinf);
3066 case -1:
3067 return make_result(&const_ninf);
3068 }
3069 Assert(false);
3070 }
3071 if (NUMERIC_IS_NINF(num1))
3072 {
3073 switch (numeric_sign_internal(num2))
3074 {
3075 case 0:
3076 return make_result(&const_nan); /* -Inf * 0 */
3077 case 1:
3078 return make_result(&const_ninf);
3079 case -1:
3080 return make_result(&const_pinf);
3081 }
3082 Assert(false);
3083 }
3084 /* by here, num1 must be finite, so num2 is not */
3085 if (NUMERIC_IS_PINF(num2))
3086 {
3087 switch (numeric_sign_internal(num1))
3088 {
3089 case 0:
3090 return make_result(&const_nan); /* 0 * Inf */
3091 case 1:
3092 return make_result(&const_pinf);
3093 case -1:
3094 return make_result(&const_ninf);
3095 }
3096 Assert(false);
3097 }
3099 switch (numeric_sign_internal(num1))
3100 {
3101 case 0:
3102 return make_result(&const_nan); /* 0 * -Inf */
3103 case 1:
3104 return make_result(&const_ninf);
3105 case -1:
3106 return make_result(&const_pinf);
3107 }
3108 Assert(false);
3109 }
3110
3111 /*
3112 * Unpack the values, let mul_var() compute the result and return it.
3113 * Unlike add_var() and sub_var(), mul_var() will round its result. In the
3114 * case of numeric_mul(), which is invoked for the * operator on numerics,
3115 * we request exact representation for the product (rscale = sum(dscale of
3116 * arg1, dscale of arg2)). If the exact result has more digits after the
3117 * decimal point than can be stored in a numeric, we round it. Rounding
3118 * after computing the exact result ensures that the final result is
3119 * correctly rounded (rounding in mul_var() using a truncated product
3120 * would not guarantee this).
3121 */
3124
3125 init_var(&result);
3126 mul_var(&arg1, &arg2, &result, arg1.dscale + arg2.dscale);
3127
3128 if (result.dscale > NUMERIC_DSCALE_MAX)
3130
3131 res = make_result_safe(&result, escontext);
3132
3133 free_var(&result);
3134
3135 return res;
3136}
static void mul_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result, int rscale)
Definition numeric.c:8335
#define NUMERIC_DSCALE_MAX
Definition numeric.c:238
static void round_var(NumericVar *var, int rscale)
Definition numeric.c:11656

References Assert, const_nan, const_ninf, const_pinf, fb(), free_var(), init_var, init_var_from_num(), make_result(), make_result_safe(), mul_var(), NUMERIC_DSCALE_MAX, NUMERIC_IS_NAN, NUMERIC_IS_NINF, NUMERIC_IS_PINF, NUMERIC_IS_SPECIAL, numeric_sign_internal(), result, and round_var().

Referenced by executeItemOptUnwrapTarget(), numeric_cash(), and numeric_mul().

◆ numeric_normalize()

char * numeric_normalize ( Numeric  num)
extern

Definition at line 1009 of file numeric.c.

1010{
1011 NumericVar x;
1012 char *str;
1013 int last;
1014
1015 /*
1016 * Handle NaN and infinities
1017 */
1018 if (NUMERIC_IS_SPECIAL(num))
1019 {
1020 if (NUMERIC_IS_PINF(num))
1021 return pstrdup("Infinity");
1022 else if (NUMERIC_IS_NINF(num))
1023 return pstrdup("-Infinity");
1024 else
1025 return pstrdup("NaN");
1026 }
1027
1028 init_var_from_num(num, &x);
1029
1031
1032 /* If there's no decimal point, there's certainly nothing to remove. */
1033 if (strchr(str, '.') != NULL)
1034 {
1035 /*
1036 * Back up over trailing fractional zeroes. Since there is a decimal
1037 * point, this loop will terminate safely.
1038 */
1039 last = strlen(str) - 1;
1040 while (str[last] == '0')
1041 last--;
1042
1043 /* We want to get rid of the decimal point too, if it's now last. */
1044 if (str[last] == '.')
1045 last--;
1046
1047 /* Delete whatever we backed up over. */
1048 str[last + 1] = '\0';
1049 }
1050
1051 return str;
1052}
static char * get_str_from_var(const NumericVar *var)
Definition numeric.c:7260
const char * str
char * pstrdup(const char *in)
Definition mcxt.c:1910

References fb(), 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 
)
extern

Definition at line 975 of file numeric.c.

976{
978 char *str;
979
980 /*
981 * Handle NaN and infinities
982 */
983 if (NUMERIC_IS_SPECIAL(num))
984 {
985 if (NUMERIC_IS_PINF(num))
986 return pstrdup("Infinity");
987 else if (NUMERIC_IS_NINF(num))
988 return pstrdup("-Infinity");
989 else
990 return pstrdup("NaN");
991 }
992
993 init_var_from_num(num, &x);
994
996
997 return str;
998}
static char * get_str_from_var_sci(const NumericVar *var, int rscale)
Definition numeric.c:7413

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_safe()

Numeric numeric_sub_safe ( Numeric  num1,
Numeric  num2,
Node escontext 
)
extern

Definition at line 2965 of file numeric.c.

2966{
2970 Numeric res;
2971
2972 /*
2973 * Handle NaN and infinities
2974 */
2976 {
2978 return make_result(&const_nan);
2979 if (NUMERIC_IS_PINF(num1))
2980 {
2981 if (NUMERIC_IS_PINF(num2))
2982 return make_result(&const_nan); /* Inf - Inf */
2983 else
2984 return make_result(&const_pinf);
2985 }
2986 if (NUMERIC_IS_NINF(num1))
2987 {
2988 if (NUMERIC_IS_NINF(num2))
2989 return make_result(&const_nan); /* -Inf - -Inf */
2990 else
2991 return make_result(&const_ninf);
2992 }
2993 /* by here, num1 must be finite, so num2 is not */
2994 if (NUMERIC_IS_PINF(num2))
2995 return make_result(&const_ninf);
2997 return make_result(&const_pinf);
2998 }
2999
3000 /*
3001 * Unpack the values, let sub_var() compute the result and return it.
3002 */
3005
3006 init_var(&result);
3007 sub_var(&arg1, &arg2, &result);
3008
3009 res = make_result_safe(&result, escontext);
3010
3011 free_var(&result);
3012
3013 return res;
3014}
static void sub_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
Definition numeric.c:8214

References Assert, const_nan, const_ninf, const_pinf, fb(), free_var(), init_var, init_var_from_num(), make_result(), make_result_safe(), NUMERIC_IS_NAN, NUMERIC_IS_NINF, NUMERIC_IS_PINF, NUMERIC_IS_SPECIAL, result, 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 
)
extern

Definition at line 4215 of file numeric.c.

4216{
4220 Numeric res;
4221
4222 /* Range bounds must not be NaN/infinity */
4224 {
4225 if (NUMERIC_IS_NAN(rmin))
4226 ereport(ERROR,
4228 errmsg("lower bound cannot be NaN"));
4229 else
4230 ereport(ERROR,
4232 errmsg("lower bound cannot be infinity"));
4233 }
4235 {
4236 if (NUMERIC_IS_NAN(rmax))
4237 ereport(ERROR,
4239 errmsg("upper bound cannot be NaN"));
4240 else
4241 ereport(ERROR,
4243 errmsg("upper bound cannot be infinity"));
4244 }
4245
4246 /* Return a random value in the range [rmin, rmax] */
4249
4250 init_var(&result);
4251
4253
4254 res = make_result(&result);
4255
4256 free_var(&result);
4257
4258 return res;
4259}
static void random_var(pg_prng_state *state, const NumericVar *rmin, const NumericVar *rmax, NumericVar *result)
Definition numeric.c:11228
#define ERROR
Definition elog.h:40
#define ereport(elevel,...)
Definition elog.h:152

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

Referenced by numeric_random().