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)
 
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 4285 of file numeric.c.

4286{
4287 Numeric res;
4289 int rscale;
4290 int w;
4291 int m;
4292
4293 init_var(&result);
4294
4295 /* result scale */
4296 rscale = log10val2 < 0 ? 0 : log10val2;
4297
4298 /* how much to decrease the weight by */
4299 w = log10val2 / DEC_DIGITS;
4300 /* how much is left to divide by */
4301 m = log10val2 % DEC_DIGITS;
4302 if (m < 0)
4303 {
4304 m += DEC_DIGITS;
4305 w--;
4306 }
4307
4308 /*
4309 * If there is anything left to divide by (10^m with 0 < m < DEC_DIGITS),
4310 * multiply the dividend by 10^(DEC_DIGITS - m), and shift the weight by
4311 * one more.
4312 */
4313 if (m > 0)
4314 {
4315#if DEC_DIGITS == 4
4316 static const int pow10[] = {1, 10, 100, 1000};
4317#elif DEC_DIGITS == 2
4318 static const int pow10[] = {1, 10};
4319#elif DEC_DIGITS == 1
4320 static const int pow10[] = {1};
4321#else
4322#error unsupported NBASE
4323#endif
4326
4327 StaticAssertDecl(lengthof(pow10) == DEC_DIGITS, "mismatch with DEC_DIGITS");
4328
4330 {
4331 /* do the multiplication using 128-bit integers */
4332 INT128 tmp;
4333
4334 tmp = int64_to_int128(0);
4336
4338 }
4339 else
4341
4342 w++;
4343 }
4344 else
4346
4347 result.weight -= w;
4348 result.dscale = rscale;
4349
4350 res = make_result(&result);
4351
4352 free_var(&result);
4353
4354 return res;
4355}
static void free_var(NumericVar *var)
Definition numeric.c:6729
static void int64_to_numericvar(int64 val, NumericVar *var)
Definition numeric.c:7848
static Numeric make_result(const NumericVar *var)
Definition numeric.c:7635
#define DEC_DIGITS
Definition numeric.c:99
static void int128_to_numericvar(INT128 val, NumericVar *var)
Definition numeric.c:7965
#define init_var(v)
Definition numeric.c:486
int64_t int64
Definition c.h:621
#define unlikely(x)
Definition c.h:438
#define lengthof(array)
Definition c.h:873
#define StaticAssertDecl(condition, errmessage)
Definition c.h:1008
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()

◆ numeric_add_safe()

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

Definition at line 2883 of file numeric.c.

2884{
2888 Numeric res;
2889
2890 /*
2891 * Handle NaN and infinities
2892 */
2894 {
2896 return make_result(&const_nan);
2897 if (NUMERIC_IS_PINF(num1))
2898 {
2899 if (NUMERIC_IS_NINF(num2))
2900 return make_result(&const_nan); /* Inf + -Inf */
2901 else
2902 return make_result(&const_pinf);
2903 }
2904 if (NUMERIC_IS_NINF(num1))
2905 {
2906 if (NUMERIC_IS_PINF(num2))
2907 return make_result(&const_nan); /* -Inf + Inf */
2908 else
2909 return make_result(&const_ninf);
2910 }
2911 /* by here, num1 must be finite, so num2 is not */
2912 if (NUMERIC_IS_PINF(num2))
2913 return make_result(&const_pinf);
2915 return make_result(&const_ninf);
2916 }
2917
2918 /*
2919 * Unpack the values, let add_var() compute the result and return it.
2920 */
2923
2924 init_var(&result);
2925 add_var(&arg1, &arg2, &result);
2926
2927 res = make_result_safe(&result, escontext);
2928
2929 free_var(&result);
2930
2931 return res;
2932}
static const NumericVar const_pinf
Definition numeric.c:454
static Numeric make_result_safe(const NumericVar *var, Node *escontext)
Definition numeric.c:7539
static const NumericVar const_ninf
Definition numeric.c:457
static void add_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
Definition numeric.c:8091
#define NUMERIC_IS_SPECIAL(n)
Definition numeric.c:176
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition numeric.c:7211
#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:943

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 3157 of file numeric.c.

3158{
3162 Numeric res;
3163 int rscale;
3164
3165 /*
3166 * Handle NaN and infinities
3167 */
3169 {
3171 return make_result(&const_nan);
3172 if (NUMERIC_IS_PINF(num1))
3173 {
3175 return make_result(&const_nan); /* Inf / [-]Inf */
3176 switch (numeric_sign_internal(num2))
3177 {
3178 case 0:
3179 goto division_by_zero;
3180 case 1:
3181 return make_result(&const_pinf);
3182 case -1:
3183 return make_result(&const_ninf);
3184 }
3185 Assert(false);
3186 }
3187 if (NUMERIC_IS_NINF(num1))
3188 {
3190 return make_result(&const_nan); /* -Inf / [-]Inf */
3191 switch (numeric_sign_internal(num2))
3192 {
3193 case 0:
3194 goto division_by_zero;
3195 case 1:
3196 return make_result(&const_ninf);
3197 case -1:
3198 return make_result(&const_pinf);
3199 }
3200 Assert(false);
3201 }
3202 /* by here, num1 must be finite, so num2 is not */
3203
3204 /*
3205 * POSIX would have us return zero or minus zero if num1 is zero, and
3206 * otherwise throw an underflow error. But the numeric type doesn't
3207 * really do underflow, so let's just return zero.
3208 */
3209 return make_result(&const_zero);
3210 }
3211
3212 /*
3213 * Unpack the arguments
3214 */
3217
3218 init_var(&result);
3219
3220 /*
3221 * Select scale for division result
3222 */
3223 rscale = select_div_scale(&arg1, &arg2);
3224
3225 /* Check for division by zero */
3226 if (arg2.ndigits == 0 || arg2.digits[0] == 0)
3227 goto division_by_zero;
3228
3229 /*
3230 * Do the divide and return the result
3231 */
3232 div_var(&arg1, &arg2, &result, rscale, true, true);
3233
3234 res = make_result_safe(&result, escontext);
3235
3236 free_var(&result);
3237
3238 return res;
3239
3241 ereturn(escontext, NULL,
3243 errmsg("division by zero"));
3244}
static int numeric_sign_internal(Numeric num)
Definition numeric.c:1463
static int select_div_scale(const NumericVar *var1, const NumericVar *var2)
Definition numeric.c:9676
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:8907
int errcode(int sqlerrcode)
Definition elog.c:874
#define ereturn(context, dummy_value,...)
Definition elog.h:279
static char * errmsg

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 4369 of file numeric.c.

4370{
4371 NumericVar x;
4372 int32 result;
4373
4374 if (NUMERIC_IS_SPECIAL(num))
4375 {
4376 if (NUMERIC_IS_NAN(num))
4377 ereturn(escontext, 0,
4379 errmsg("cannot convert NaN to %s", "integer")));
4380 else
4381 ereturn(escontext, 0,
4383 errmsg("cannot convert infinity to %s", "integer")));
4384 }
4385
4386 /* Convert to variable format, then convert to int4 */
4387 init_var_from_num(num, &x);
4388
4389 if (!numericvar_to_int32(&x, &result))
4390 ereturn(escontext, 0,
4392 errmsg("integer out of range")));
4393
4394 return result;
4395}
static bool numericvar_to_int32(const NumericVar *var, int32 *result)
Definition numeric.c:4417
int32_t int32
Definition c.h:620
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(), getArrayIndex(), numeric_int4(), and numeric_to_char().

◆ numeric_int8_safe()

int64 numeric_int8_safe ( Numeric  num,
Node escontext 
)
extern

Definition at line 4445 of file numeric.c.

4446{
4447 NumericVar x;
4448 int64 result;
4449
4450 if (NUMERIC_IS_SPECIAL(num))
4451 {
4452 if (NUMERIC_IS_NAN(num))
4453 ereturn(escontext, 0,
4455 errmsg("cannot convert NaN to %s", "bigint")));
4456 else
4457 ereturn(escontext, 0,
4459 errmsg("cannot convert infinity to %s", "bigint")));
4460 }
4461
4462 /* Convert to variable format, then convert to int8 */
4463 init_var_from_num(num, &x);
4464
4465 if (!numericvar_to_int64(&x, &result))
4466 ereturn(escontext, 0,
4468 errmsg("bigint out of range")));
4469
4470 return result;
4471}
static bool numericvar_to_int64(const NumericVar *var, int64 *result)
Definition numeric.c:7773

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 3360 of file numeric.c.

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

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 3038 of file numeric.c.

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

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:7254
const char * str
char * pstrdup(const char *in)
Definition mcxt.c:1781

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:7407
static int scale
Definition pgbench.c:182

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 2959 of file numeric.c.

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

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 4209 of file numeric.c.

4210{
4214 Numeric res;
4215
4216 /* Range bounds must not be NaN/infinity */
4218 {
4219 if (NUMERIC_IS_NAN(rmin))
4220 ereport(ERROR,
4222 errmsg("lower bound cannot be NaN"));
4223 else
4224 ereport(ERROR,
4226 errmsg("lower bound cannot be infinity"));
4227 }
4229 {
4230 if (NUMERIC_IS_NAN(rmax))
4231 ereport(ERROR,
4233 errmsg("upper bound cannot be NaN"));
4234 else
4235 ereport(ERROR,
4237 errmsg("upper bound cannot be infinity"));
4238 }
4239
4240 /* Return a random value in the range [rmin, rmax] */
4243
4244 init_var(&result);
4245
4247
4248 res = make_result(&result);
4249
4250 free_var(&result);
4251
4252 return res;
4253}
static void random_var(pg_prng_state *state, const NumericVar *rmin, const NumericVar *rmax, NumericVar *result)
Definition numeric.c:11222
#define ERROR
Definition elog.h:39
#define ereport(elevel,...)
Definition elog.h:151

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