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 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)
 
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_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

typedef struct NumericData* 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 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 4280 of file numeric.c.

4281{
4282 Numeric res;
4283 NumericVar result;
4284 int rscale;
4285 int w;
4286 int m;
4287
4288 init_var(&result);
4289
4290 /* result scale */
4291 rscale = log10val2 < 0 ? 0 : log10val2;
4292
4293 /* how much to decrease the weight by */
4294 w = log10val2 / DEC_DIGITS;
4295 /* how much is left to divide by */
4296 m = log10val2 % DEC_DIGITS;
4297 if (m < 0)
4298 {
4299 m += DEC_DIGITS;
4300 w--;
4301 }
4302
4303 /*
4304 * If there is anything left to divide by (10^m with 0 < m < DEC_DIGITS),
4305 * multiply the dividend by 10^(DEC_DIGITS - m), and shift the weight by
4306 * one more.
4307 */
4308 if (m > 0)
4309 {
4310#if DEC_DIGITS == 4
4311 static const int pow10[] = {1, 10, 100, 1000};
4312#elif DEC_DIGITS == 2
4313 static const int pow10[] = {1, 10};
4314#elif DEC_DIGITS == 1
4315 static const int pow10[] = {1};
4316#else
4317#error unsupported NBASE
4318#endif
4319 int64 factor = pow10[DEC_DIGITS - m];
4320 int64 new_val1;
4321
4322 StaticAssertDecl(lengthof(pow10) == DEC_DIGITS, "mismatch with DEC_DIGITS");
4323
4324 if (unlikely(pg_mul_s64_overflow(val1, factor, &new_val1)))
4325 {
4326 /* do the multiplication using 128-bit integers */
4327 INT128 tmp;
4328
4329 tmp = int64_to_int128(0);
4330 int128_add_int64_mul_int64(&tmp, val1, factor);
4331
4332 int128_to_numericvar(tmp, &result);
4333 }
4334 else
4335 int64_to_numericvar(new_val1, &result);
4336
4337 w++;
4338 }
4339 else
4340 int64_to_numericvar(val1, &result);
4341
4342 result.weight -= w;
4343 result.dscale = rscale;
4344
4345 res = make_result(&result);
4346
4347 free_var(&result);
4348
4349 return res;
4350}
static void free_var(NumericVar *var)
Definition: numeric.c:6699
static void int64_to_numericvar(int64 val, NumericVar *var)
Definition: numeric.c:7818
static Numeric make_result(const NumericVar *var)
Definition: numeric.c:7605
#define DEC_DIGITS
Definition: numeric.c:99
static void int128_to_numericvar(INT128 val, NumericVar *var)
Definition: numeric.c:7935
#define init_var(v)
Definition: numeric.c:486
int64_t int64
Definition: c.h:549
#define unlikely(x)
Definition: c.h:418
#define lengthof(array)
Definition: c.h:801
#define StaticAssertDecl(condition, errmessage)
Definition: c.h:948
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
Definition: int128.h:55
int dscale
Definition: numeric.c:319
int weight
Definition: numeric.c:317

References DEC_DIGITS, NumericVar::dscale, 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(), 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_safe()

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

Definition at line 2881 of file numeric.c.

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

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

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 
)

Definition at line 3152 of file numeric.c.

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

References Assert(), const_nan, const_ninf, const_pinf, const_zero, NumericVar::digits, div_var(), ereturn, errcode(), errmsg(), free_var(), init_var, init_var_from_num(), make_result(), make_result_safe(), NumericVar::ndigits, NUMERIC_IS_NAN, NUMERIC_IS_NINF, NUMERIC_IS_PINF, NUMERIC_IS_SPECIAL, numeric_sign_internal(), 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 
)

Definition at line 4364 of file numeric.c.

4365{
4366 NumericVar x;
4367 int32 result;
4368
4369 if (NUMERIC_IS_SPECIAL(num))
4370 {
4371 if (NUMERIC_IS_NAN(num))
4372 ereturn(escontext, 0,
4373 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4374 errmsg("cannot convert NaN to %s", "integer")));
4375 else
4376 ereturn(escontext, 0,
4377 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4378 errmsg("cannot convert infinity to %s", "integer")));
4379 }
4380
4381 /* Convert to variable format, then convert to int4 */
4382 init_var_from_num(num, &x);
4383
4384 if (!numericvar_to_int32(&x, &result))
4385 ereturn(escontext, 0,
4386 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4387 errmsg("integer out of range")));
4388
4389 return result;
4390}
static bool numericvar_to_int32(const NumericVar *var, int32 *result)
Definition: numeric.c:4406
int32_t int32
Definition: c.h:548
int x
Definition: isn.c:75

References ereturn, errcode(), errmsg(), 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_safe()

int64 numeric_int8_safe ( Numeric  num,
Node escontext 
)

Definition at line 4434 of file numeric.c.

4435{
4436 NumericVar x;
4437 int64 result;
4438
4439 if (NUMERIC_IS_SPECIAL(num))
4440 {
4441 if (NUMERIC_IS_NAN(num))
4442 ereturn(escontext, 0,
4443 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4444 errmsg("cannot convert NaN to %s", "bigint")));
4445 else
4446 ereturn(escontext, 0,
4447 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4448 errmsg("cannot convert infinity to %s", "bigint")));
4449 }
4450
4451 /* Convert to variable format, then convert to int8 */
4452 init_var_from_num(num, &x);
4453
4454 if (!numericvar_to_int64(&x, &result))
4455 ereturn(escontext, 0,
4456 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4457 errmsg("bigint out of range")));
4458
4459 return result;
4460}
static bool numericvar_to_int64(const NumericVar *var, int64 *result)
Definition: numeric.c:7743

References ereturn, errcode(), errmsg(), 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 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)

◆ numeric_maximum_size()

int32 numeric_maximum_size ( int32  typmod)

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, 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 
)

Definition at line 3355 of file numeric.c.

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

References const_nan, NumericVar::digits, duplicate_numeric(), ereturn, errcode(), errmsg(), free_var(), init_var, init_var_from_num(), make_result(), make_result_safe(), mod_var(), NumericVar::ndigits, NUMERIC_IS_INF, NUMERIC_IS_NAN, NUMERIC_IS_SPECIAL, and numeric_sign_internal().

Referenced by executeItemOptUnwrapTarget(), and numeric_mod().

◆ numeric_mul_safe()

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

Definition at line 3033 of file numeric.c.

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

References Assert(), const_nan, const_ninf, const_pinf, NumericVar::dscale, 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(), and round_var().

Referenced by executeItemOptUnwrapTarget(), and numeric_mul().

◆ numeric_normalize()

char * numeric_normalize ( Numeric  num)

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

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 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:7377
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 
)

Definition at line 2957 of file numeric.c.

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

References Assert(), const_nan, const_ninf, const_pinf, 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 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 4204 of file numeric.c.

4205{
4206 NumericVar rmin_var;
4207 NumericVar rmax_var;
4208 NumericVar result;
4209 Numeric res;
4210
4211 /* Range bounds must not be NaN/infinity */
4212 if (NUMERIC_IS_SPECIAL(rmin))
4213 {
4214 if (NUMERIC_IS_NAN(rmin))
4215 ereport(ERROR,
4216 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4217 errmsg("lower bound cannot be NaN"));
4218 else
4219 ereport(ERROR,
4220 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4221 errmsg("lower bound cannot be infinity"));
4222 }
4223 if (NUMERIC_IS_SPECIAL(rmax))
4224 {
4225 if (NUMERIC_IS_NAN(rmax))
4226 ereport(ERROR,
4227 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4228 errmsg("upper bound cannot be NaN"));
4229 else
4230 ereport(ERROR,
4231 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4232 errmsg("upper bound cannot be infinity"));
4233 }
4234
4235 /* Return a random value in the range [rmin, rmax] */
4236 init_var_from_num(rmin, &rmin_var);
4237 init_var_from_num(rmax, &rmax_var);
4238
4239 init_var(&result);
4240
4241 random_var(state, &rmin_var, &rmax_var, &result);
4242
4243 res = make_result(&result);
4244
4245 free_var(&result);
4246
4247 return res;
4248}
static void random_var(pg_prng_state *state, const NumericVar *rmin, const NumericVar *rmax, NumericVar *result)
Definition: numeric.c:11192
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:150
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, and random_var().

Referenced by numeric_random().