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

Go to the source code of this file.

Macros

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

Typedefs

typedef struct NumericDataNumeric
 

Functions

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

Macro Definition Documentation

◆ NUMERIC_MAX_DISPLAY_SCALE

#define NUMERIC_MAX_DISPLAY_SCALE   NUMERIC_MAX_PRECISION

Definition at line 40 of file numeric.h.

◆ NUMERIC_MAX_PRECISION

#define NUMERIC_MAX_PRECISION   1000

Definition at line 32 of file numeric.h.

◆ NUMERIC_MAX_RESULT_SCALE

#define NUMERIC_MAX_RESULT_SCALE   (NUMERIC_MAX_PRECISION * 2)

Definition at line 43 of file numeric.h.

◆ NUMERIC_MAX_SCALE

#define NUMERIC_MAX_SCALE   1000

Definition at line 35 of file numeric.h.

◆ NUMERIC_MIN_DISPLAY_SCALE

#define NUMERIC_MIN_DISPLAY_SCALE   0

Definition at line 41 of file numeric.h.

◆ NUMERIC_MIN_SCALE

#define NUMERIC_MIN_SCALE   (-1000)

Definition at line 34 of file numeric.h.

◆ NUMERIC_MIN_SIG_DIGITS

#define NUMERIC_MIN_SIG_DIGITS   16

Definition at line 50 of file numeric.h.

◆ PG_GETARG_NUMERIC

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

Definition at line 78 of file numeric.h.

◆ PG_GETARG_NUMERIC_COPY

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

Definition at line 79 of file numeric.h.

◆ PG_RETURN_NUMERIC

#define PG_RETURN_NUMERIC (   x)    return NumericGetDatum(x)

Definition at line 80 of file numeric.h.

Typedef Documentation

◆ Numeric

typedef struct NumericData* Numeric

Definition at line 54 of file numeric.h.

Function Documentation

◆ DatumGetNumeric()

◆ DatumGetNumericCopy()

static Numeric DatumGetNumericCopy ( Datum  X)
inlinestatic

Definition at line 67 of file numeric.h.

68 {
69  return (Numeric) PG_DETOAST_DATUM_COPY(X);
70 }
#define PG_DETOAST_DATUM_COPY(datum)
Definition: fmgr.h:242

References PG_DETOAST_DATUM_COPY.

Referenced by jsonb_numeric().

◆ int64_div_fast_to_numeric()

Numeric int64_div_fast_to_numeric ( int64  val1,
int  log10val2 
)

Definition at line 4308 of file numeric.c.

4309 {
4310  Numeric res;
4311  NumericVar result;
4312  int rscale;
4313  int w;
4314  int m;
4315 
4316  init_var(&result);
4317 
4318  /* result scale */
4319  rscale = log10val2 < 0 ? 0 : log10val2;
4320 
4321  /* how much to decrease the weight by */
4322  w = log10val2 / DEC_DIGITS;
4323  /* how much is left to divide by */
4324  m = log10val2 % DEC_DIGITS;
4325  if (m < 0)
4326  {
4327  m += DEC_DIGITS;
4328  w--;
4329  }
4330 
4331  /*
4332  * If there is anything left to divide by (10^m with 0 < m < DEC_DIGITS),
4333  * multiply the dividend by 10^(DEC_DIGITS - m), and shift the weight by
4334  * one more.
4335  */
4336  if (m > 0)
4337  {
4338 #if DEC_DIGITS == 4
4339  static const int pow10[] = {1, 10, 100, 1000};
4340 #elif DEC_DIGITS == 2
4341  static const int pow10[] = {1, 10};
4342 #elif DEC_DIGITS == 1
4343  static const int pow10[] = {1};
4344 #else
4345 #error unsupported NBASE
4346 #endif
4347  int64 factor = pow10[DEC_DIGITS - m];
4348  int64 new_val1;
4349 
4350  StaticAssertDecl(lengthof(pow10) == DEC_DIGITS, "mismatch with DEC_DIGITS");
4351 
4352  if (unlikely(pg_mul_s64_overflow(val1, factor, &new_val1)))
4353  {
4354 #ifdef HAVE_INT128
4355  /* do the multiplication using 128-bit integers */
4356  int128 tmp;
4357 
4358  tmp = (int128) val1 * (int128) factor;
4359 
4360  int128_to_numericvar(tmp, &result);
4361 #else
4362  /* do the multiplication using numerics */
4363  NumericVar tmp;
4364 
4365  init_var(&tmp);
4366 
4367  int64_to_numericvar(val1, &result);
4368  int64_to_numericvar(factor, &tmp);
4369  mul_var(&result, &tmp, &result, 0);
4370 
4371  free_var(&tmp);
4372 #endif
4373  }
4374  else
4375  int64_to_numericvar(new_val1, &result);
4376 
4377  w++;
4378  }
4379  else
4380  int64_to_numericvar(val1, &result);
4381 
4382  result.weight -= w;
4383  result.dscale = rscale;
4384 
4385  res = make_result(&result);
4386 
4387  free_var(&result);
4388 
4389  return res;
4390 }
static void free_var(NumericVar *var)
Definition: numeric.c:6973
static void mul_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result, int rscale)
Definition: numeric.c:8673
static void int64_to_numericvar(int64 val, NumericVar *var)
Definition: numeric.c:8108
static Numeric make_result(const NumericVar *var)
Definition: numeric.c:7895
#define DEC_DIGITS
Definition: numeric.c:97
#define init_var(v)
Definition: numeric.c:491
#define unlikely(x)
Definition: c.h:311
#define lengthof(array)
Definition: c.h:788
#define StaticAssertDecl(condition, errmessage)
Definition: c.h:936
static bool pg_mul_s64_overflow(int64 a, int64 b, int64 *result)
Definition: int.h:219
int dscale
Definition: numeric.c:315
int weight
Definition: numeric.c:313

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

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

◆ int64_to_numeric()

◆ numeric_add_opt_error()

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

Definition at line 2871 of file numeric.c.

2872 {
2873  NumericVar arg1;
2874  NumericVar arg2;
2875  NumericVar result;
2876  Numeric res;
2877 
2878  /*
2879  * Handle NaN and infinities
2880  */
2881  if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
2882  {
2883  if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2884  return make_result(&const_nan);
2885  if (NUMERIC_IS_PINF(num1))
2886  {
2887  if (NUMERIC_IS_NINF(num2))
2888  return make_result(&const_nan); /* Inf + -Inf */
2889  else
2890  return make_result(&const_pinf);
2891  }
2892  if (NUMERIC_IS_NINF(num1))
2893  {
2894  if (NUMERIC_IS_PINF(num2))
2895  return make_result(&const_nan); /* -Inf + Inf */
2896  else
2897  return make_result(&const_ninf);
2898  }
2899  /* by here, num1 must be finite, so num2 is not */
2900  if (NUMERIC_IS_PINF(num2))
2901  return make_result(&const_pinf);
2902  Assert(NUMERIC_IS_NINF(num2));
2903  return make_result(&const_ninf);
2904  }
2905 
2906  /*
2907  * Unpack the values, let add_var() compute the result and return it.
2908  */
2909  init_var_from_num(num1, &arg1);
2910  init_var_from_num(num2, &arg2);
2911 
2912  init_var(&result);
2913  add_var(&arg1, &arg2, &result);
2914 
2915  res = make_result_opt_error(&result, have_error);
2916 
2917  free_var(&result);
2918 
2919  return res;
2920 }
static const NumericVar const_pinf
Definition: numeric.c:459
static const NumericVar const_ninf
Definition: numeric.c:462
static void add_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
Definition: numeric.c:8435
#define NUMERIC_IS_SPECIAL(n)
Definition: numeric.c:172
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:7455
#define NUMERIC_IS_PINF(n)
Definition: numeric.c:204
static Numeric make_result_opt_error(const NumericVar *var, bool *have_error)
Definition: numeric.c:7786
#define NUMERIC_IS_NINF(n)
Definition: numeric.c:205
static const NumericVar const_nan
Definition: numeric.c:456
#define NUMERIC_IS_NAN(n)
Definition: numeric.c:203
#define Assert(condition)
Definition: c.h:858

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

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

◆ numeric_div_opt_error()

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

Definition at line 3148 of file numeric.c.

3149 {
3150  NumericVar arg1;
3151  NumericVar arg2;
3152  NumericVar result;
3153  Numeric res;
3154  int rscale;
3155 
3156  if (have_error)
3157  *have_error = false;
3158 
3159  /*
3160  * Handle NaN and infinities
3161  */
3162  if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
3163  {
3164  if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
3165  return make_result(&const_nan);
3166  if (NUMERIC_IS_PINF(num1))
3167  {
3168  if (NUMERIC_IS_SPECIAL(num2))
3169  return make_result(&const_nan); /* Inf / [-]Inf */
3170  switch (numeric_sign_internal(num2))
3171  {
3172  case 0:
3173  if (have_error)
3174  {
3175  *have_error = true;
3176  return NULL;
3177  }
3178  ereport(ERROR,
3179  (errcode(ERRCODE_DIVISION_BY_ZERO),
3180  errmsg("division by zero")));
3181  break;
3182  case 1:
3183  return make_result(&const_pinf);
3184  case -1:
3185  return make_result(&const_ninf);
3186  }
3187  Assert(false);
3188  }
3189  if (NUMERIC_IS_NINF(num1))
3190  {
3191  if (NUMERIC_IS_SPECIAL(num2))
3192  return make_result(&const_nan); /* -Inf / [-]Inf */
3193  switch (numeric_sign_internal(num2))
3194  {
3195  case 0:
3196  if (have_error)
3197  {
3198  *have_error = true;
3199  return NULL;
3200  }
3201  ereport(ERROR,
3202  (errcode(ERRCODE_DIVISION_BY_ZERO),
3203  errmsg("division by zero")));
3204  break;
3205  case 1:
3206  return make_result(&const_ninf);
3207  case -1:
3208  return make_result(&const_pinf);
3209  }
3210  Assert(false);
3211  }
3212  /* by here, num1 must be finite, so num2 is not */
3213 
3214  /*
3215  * POSIX would have us return zero or minus zero if num1 is zero, and
3216  * otherwise throw an underflow error. But the numeric type doesn't
3217  * really do underflow, so let's just return zero.
3218  */
3219  return make_result(&const_zero);
3220  }
3221 
3222  /*
3223  * Unpack the arguments
3224  */
3225  init_var_from_num(num1, &arg1);
3226  init_var_from_num(num2, &arg2);
3227 
3228  init_var(&result);
3229 
3230  /*
3231  * Select scale for division result
3232  */
3233  rscale = select_div_scale(&arg1, &arg2);
3234 
3235  /*
3236  * If "have_error" is provided, check for division by zero here
3237  */
3238  if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
3239  {
3240  *have_error = true;
3241  return NULL;
3242  }
3243 
3244  /*
3245  * Do the divide and return the result
3246  */
3247  div_var(&arg1, &arg2, &result, rscale, true);
3248 
3249  res = make_result_opt_error(&result, have_error);
3250 
3251  free_var(&result);
3252 
3253  return res;
3254 }
static int numeric_sign_internal(Numeric num)
Definition: numeric.c:1478
static int select_div_scale(const NumericVar *var1, const NumericVar *var2)
Definition: numeric.c:9997
static const NumericVar const_zero
Definition: numeric.c:422
static void div_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result, int rscale, bool round)
Definition: numeric.c:9097
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
int ndigits
Definition: numeric.c:312
NumericDigit * digits
Definition: numeric.c:317

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

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

◆ numeric_int4_opt_error()

int32 numeric_int4_opt_error ( Numeric  num,
bool have_error 
)

Definition at line 4401 of file numeric.c.

4402 {
4403  NumericVar x;
4404  int32 result;
4405 
4406  if (have_error)
4407  *have_error = false;
4408 
4409  if (NUMERIC_IS_SPECIAL(num))
4410  {
4411  if (have_error)
4412  {
4413  *have_error = true;
4414  return 0;
4415  }
4416  else
4417  {
4418  if (NUMERIC_IS_NAN(num))
4419  ereport(ERROR,
4420  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4421  errmsg("cannot convert NaN to %s", "integer")));
4422  else
4423  ereport(ERROR,
4424  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4425  errmsg("cannot convert infinity to %s", "integer")));
4426  }
4427  }
4428 
4429  /* Convert to variable format, then convert to int4 */
4430  init_var_from_num(num, &x);
4431 
4432  if (!numericvar_to_int32(&x, &result))
4433  {
4434  if (have_error)
4435  {
4436  *have_error = true;
4437  return 0;
4438  }
4439  else
4440  {
4441  ereport(ERROR,
4442  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4443  errmsg("integer out of range")));
4444  }
4445  }
4446 
4447  return result;
4448 }
static bool numericvar_to_int32(const NumericVar *var, int32 *result)
Definition: numeric.c:4464
signed int int32
Definition: c.h:494
int x
Definition: isn.c:71

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

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

◆ numeric_int8_opt_error()

int64 numeric_int8_opt_error ( Numeric  num,
bool have_error 
)

Definition at line 4489 of file numeric.c.

4490 {
4491  NumericVar x;
4492  int64 result;
4493 
4494  if (have_error)
4495  *have_error = false;
4496 
4497  if (NUMERIC_IS_SPECIAL(num))
4498  {
4499  if (have_error)
4500  {
4501  *have_error = true;
4502  return 0;
4503  }
4504  else
4505  {
4506  if (NUMERIC_IS_NAN(num))
4507  ereport(ERROR,
4508  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4509  errmsg("cannot convert NaN to %s", "bigint")));
4510  else
4511  ereport(ERROR,
4512  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4513  errmsg("cannot convert infinity to %s", "bigint")));
4514  }
4515  }
4516 
4517  /* Convert to variable format, then convert to int8 */
4518  init_var_from_num(num, &x);
4519 
4520  if (!numericvar_to_int64(&x, &result))
4521  {
4522  if (have_error)
4523  {
4524  *have_error = true;
4525  return 0;
4526  }
4527  else
4528  {
4529  ereport(ERROR,
4530  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4531  errmsg("bigint out of range")));
4532  }
4533  }
4534 
4535  return result;
4536 }
static bool numericvar_to_int64(const NumericVar *var, int64 *result)
Definition: numeric.c:8033

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

Referenced by executeItemOptUnwrapTarget(), and numeric_int8().

◆ numeric_is_inf()

bool numeric_is_inf ( Numeric  num)

Definition at line 862 of file numeric.c.

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

References NUMERIC_IS_INF.

Referenced by executeItemOptUnwrapTarget(), and PLyNumber_ToJsonbValue().

◆ numeric_is_nan()

bool numeric_is_nan ( Numeric  num)

Definition at line 851 of file numeric.c.

852 {
853  return NUMERIC_IS_NAN(num);
854 }

References NUMERIC_IS_NAN.

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

◆ numeric_maximum_size()

int32 numeric_maximum_size ( int32  typmod)

Definition at line 953 of file numeric.c.

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

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

Referenced by type_maximum_size().

◆ numeric_mod_opt_error()

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

Definition at line 3372 of file numeric.c.

3373 {
3374  Numeric res;
3375  NumericVar arg1;
3376  NumericVar arg2;
3377  NumericVar result;
3378 
3379  if (have_error)
3380  *have_error = false;
3381 
3382  /*
3383  * Handle NaN and infinities. We follow POSIX fmod() on this, except that
3384  * POSIX treats x-is-infinite and y-is-zero identically, raising EDOM and
3385  * returning NaN. We choose to throw error only for y-is-zero.
3386  */
3387  if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
3388  {
3389  if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
3390  return make_result(&const_nan);
3391  if (NUMERIC_IS_INF(num1))
3392  {
3393  if (numeric_sign_internal(num2) == 0)
3394  {
3395  if (have_error)
3396  {
3397  *have_error = true;
3398  return NULL;
3399  }
3400  ereport(ERROR,
3401  (errcode(ERRCODE_DIVISION_BY_ZERO),
3402  errmsg("division by zero")));
3403  }
3404  /* Inf % any nonzero = NaN */
3405  return make_result(&const_nan);
3406  }
3407  /* num2 must be [-]Inf; result is num1 regardless of sign of num2 */
3408  return duplicate_numeric(num1);
3409  }
3410 
3411  init_var_from_num(num1, &arg1);
3412  init_var_from_num(num2, &arg2);
3413 
3414  init_var(&result);
3415 
3416  /*
3417  * If "have_error" is provided, check for division by zero here
3418  */
3419  if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
3420  {
3421  *have_error = true;
3422  return NULL;
3423  }
3424 
3425  mod_var(&arg1, &arg2, &result);
3426 
3427  res = make_result_opt_error(&result, NULL);
3428 
3429  free_var(&result);
3430 
3431  return res;
3432 }
static void mod_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
Definition: numeric.c:10066
static Numeric duplicate_numeric(Numeric num)
Definition: numeric.c:7767

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

Referenced by executeItemOptUnwrapTarget(), and numeric_mod().

◆ numeric_mul_opt_error()

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

Definition at line 3027 of file numeric.c.

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

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

Referenced by executeItemOptUnwrapTarget(), and numeric_mul().

◆ numeric_normalize()

char* numeric_normalize ( Numeric  num)

Definition at line 1026 of file numeric.c.

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

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

Referenced by make_scalar_key().

◆ numeric_out_sci()

char* numeric_out_sci ( Numeric  num,
int  scale 
)

Definition at line 992 of file numeric.c.

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

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

Referenced by int8_to_char(), and numeric_to_char().

◆ numeric_sub_opt_error()

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

Definition at line 2949 of file numeric.c.

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

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

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

◆ NumericGetDatum()

◆ random_numeric()

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

Definition at line 4232 of file numeric.c.

4233 {
4234  NumericVar rmin_var;
4235  NumericVar rmax_var;
4236  NumericVar result;
4237  Numeric res;
4238 
4239  /* Range bounds must not be NaN/infinity */
4240  if (NUMERIC_IS_SPECIAL(rmin))
4241  {
4242  if (NUMERIC_IS_NAN(rmin))
4243  ereport(ERROR,
4244  errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4245  errmsg("lower bound cannot be NaN"));
4246  else
4247  ereport(ERROR,
4248  errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4249  errmsg("lower bound cannot be infinity"));
4250  }
4251  if (NUMERIC_IS_SPECIAL(rmax))
4252  {
4253  if (NUMERIC_IS_NAN(rmax))
4254  ereport(ERROR,
4255  errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4256  errmsg("upper bound cannot be NaN"));
4257  else
4258  ereport(ERROR,
4259  errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4260  errmsg("upper bound cannot be infinity"));
4261  }
4262 
4263  /* Return a random value in the range [rmin, rmax] */
4264  init_var_from_num(rmin, &rmin_var);
4265  init_var_from_num(rmax, &rmax_var);
4266 
4267  init_var(&result);
4268 
4269  random_var(state, &rmin_var, &rmax_var, &result);
4270 
4271  res = make_result(&result);
4272 
4273  free_var(&result);
4274 
4275  return res;
4276 }
static void random_var(pg_prng_state *state, const NumericVar *rmin, const NumericVar *rmax, NumericVar *result)
Definition: numeric.c:11543
Definition: regguts.h:323

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

Referenced by numeric_random().