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

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

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

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

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

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

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 executeItemOptUnwrapTarget(), and PLyNumber_ToJsonbValue().

◆ numeric_is_nan()

bool numeric_is_nan ( Numeric  num)

Definition at line 834 of file numeric.c.

835{
836 return NUMERIC_IS_NAN(num);
837}

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

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

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

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

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:7225
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:7378
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 2958 of file numeric.c.

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

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

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