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

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

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

2865 {
2866  NumericVar arg1;
2867  NumericVar arg2;
2868  NumericVar result;
2869  Numeric res;
2870 
2871  /*
2872  * Handle NaN and infinities
2873  */
2874  if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
2875  {
2876  if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2877  return make_result(&const_nan);
2878  if (NUMERIC_IS_PINF(num1))
2879  {
2880  if (NUMERIC_IS_NINF(num2))
2881  return make_result(&const_nan); /* Inf + -Inf */
2882  else
2883  return make_result(&const_pinf);
2884  }
2885  if (NUMERIC_IS_NINF(num1))
2886  {
2887  if (NUMERIC_IS_PINF(num2))
2888  return make_result(&const_nan); /* -Inf + Inf */
2889  else
2890  return make_result(&const_ninf);
2891  }
2892  /* by here, num1 must be finite, so num2 is not */
2893  if (NUMERIC_IS_PINF(num2))
2894  return make_result(&const_pinf);
2895  Assert(NUMERIC_IS_NINF(num2));
2896  return make_result(&const_ninf);
2897  }
2898 
2899  /*
2900  * Unpack the values, let add_var() compute the result and return it.
2901  */
2902  init_var_from_num(num1, &arg1);
2903  init_var_from_num(num2, &arg2);
2904 
2905  init_var(&result);
2906  add_var(&arg1, &arg2, &result);
2907 
2908  res = make_result_opt_error(&result, have_error);
2909 
2910  free_var(&result);
2911 
2912  return res;
2913 }
static const NumericVar const_pinf
Definition: numeric.c:461
static const NumericVar const_ninf
Definition: numeric.c:464
static void add_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
Definition: numeric.c:8428
#define NUMERIC_IS_SPECIAL(n)
Definition: numeric.c:174
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:7448
#define NUMERIC_IS_PINF(n)
Definition: numeric.c:206
static Numeric make_result_opt_error(const NumericVar *var, bool *have_error)
Definition: numeric.c:7779
#define NUMERIC_IS_NINF(n)
Definition: numeric.c:207
static const NumericVar const_nan
Definition: numeric.c:458
#define NUMERIC_IS_NAN(n)
Definition: numeric.c:205
#define Assert(condition)
Definition: c.h:863

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

3142 {
3143  NumericVar arg1;
3144  NumericVar arg2;
3145  NumericVar result;
3146  Numeric res;
3147  int rscale;
3148 
3149  if (have_error)
3150  *have_error = false;
3151 
3152  /*
3153  * Handle NaN and infinities
3154  */
3155  if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
3156  {
3157  if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
3158  return make_result(&const_nan);
3159  if (NUMERIC_IS_PINF(num1))
3160  {
3161  if (NUMERIC_IS_SPECIAL(num2))
3162  return make_result(&const_nan); /* Inf / [-]Inf */
3163  switch (numeric_sign_internal(num2))
3164  {
3165  case 0:
3166  if (have_error)
3167  {
3168  *have_error = true;
3169  return NULL;
3170  }
3171  ereport(ERROR,
3172  (errcode(ERRCODE_DIVISION_BY_ZERO),
3173  errmsg("division by zero")));
3174  break;
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  if (have_error)
3190  {
3191  *have_error = true;
3192  return NULL;
3193  }
3194  ereport(ERROR,
3195  (errcode(ERRCODE_DIVISION_BY_ZERO),
3196  errmsg("division by zero")));
3197  break;
3198  case 1:
3199  return make_result(&const_ninf);
3200  case -1:
3201  return make_result(&const_pinf);
3202  }
3203  Assert(false);
3204  }
3205  /* by here, num1 must be finite, so num2 is not */
3206 
3207  /*
3208  * POSIX would have us return zero or minus zero if num1 is zero, and
3209  * otherwise throw an underflow error. But the numeric type doesn't
3210  * really do underflow, so let's just return zero.
3211  */
3212  return make_result(&const_zero);
3213  }
3214 
3215  /*
3216  * Unpack the arguments
3217  */
3218  init_var_from_num(num1, &arg1);
3219  init_var_from_num(num2, &arg2);
3220 
3221  init_var(&result);
3222 
3223  /*
3224  * Select scale for division result
3225  */
3226  rscale = select_div_scale(&arg1, &arg2);
3227 
3228  /*
3229  * If "have_error" is provided, check for division by zero here
3230  */
3231  if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
3232  {
3233  *have_error = true;
3234  return NULL;
3235  }
3236 
3237  /*
3238  * Do the divide and return the result
3239  */
3240  div_var(&arg1, &arg2, &result, rscale, true, true);
3241 
3242  res = make_result_opt_error(&result, have_error);
3243 
3244  free_var(&result);
3245 
3246  return res;
3247 }
static int numeric_sign_internal(Numeric num)
Definition: numeric.c:1477
static int select_div_scale(const NumericVar *var1, const NumericVar *var2)
Definition: numeric.c:10013
static const NumericVar const_zero
Definition: numeric.c:424
static void div_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result, int rscale, bool round, bool exact)
Definition: numeric.c:9244
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:314
NumericDigit * digits
Definition: numeric.c:319

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

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

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(), numeric_int4(), and numeric_to_char().

◆ numeric_int8_opt_error()

int64 numeric_int8_opt_error ( Numeric  num,
bool have_error 
)

Definition at line 4482 of file numeric.c.

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

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

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

References NUMERIC_IS_INF.

Referenced by executeItemOptUnwrapTarget(), and PLyNumber_ToJsonbValue().

◆ numeric_is_nan()

bool numeric_is_nan ( Numeric  num)

Definition at line 850 of file numeric.c.

851 {
852  return NUMERIC_IS_NAN(num);
853 }

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

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

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

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

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

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

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

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

992 {
993  NumericVar x;
994  char *str;
995 
996  /*
997  * Handle NaN and infinities
998  */
999  if (NUMERIC_IS_SPECIAL(num))
1000  {
1001  if (NUMERIC_IS_PINF(num))
1002  return pstrdup("Infinity");
1003  else if (NUMERIC_IS_NINF(num))
1004  return pstrdup("-Infinity");
1005  else
1006  return pstrdup("NaN");
1007  }
1008 
1009  init_var_from_num(num, &x);
1010 
1012 
1013  return str;
1014 }
static char * get_str_from_var_sci(const NumericVar *var, int rscale)
Definition: numeric.c:7644
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 2942 of file numeric.c.

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

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

4226 {
4227  NumericVar rmin_var;
4228  NumericVar rmax_var;
4229  NumericVar result;
4230  Numeric res;
4231 
4232  /* Range bounds must not be NaN/infinity */
4233  if (NUMERIC_IS_SPECIAL(rmin))
4234  {
4235  if (NUMERIC_IS_NAN(rmin))
4236  ereport(ERROR,
4237  errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4238  errmsg("lower bound cannot be NaN"));
4239  else
4240  ereport(ERROR,
4241  errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4242  errmsg("lower bound cannot be infinity"));
4243  }
4244  if (NUMERIC_IS_SPECIAL(rmax))
4245  {
4246  if (NUMERIC_IS_NAN(rmax))
4247  ereport(ERROR,
4248  errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4249  errmsg("upper bound cannot be NaN"));
4250  else
4251  ereport(ERROR,
4252  errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4253  errmsg("upper bound cannot be infinity"));
4254  }
4255 
4256  /* Return a random value in the range [rmin, rmax] */
4257  init_var_from_num(rmin, &rmin_var);
4258  init_var_from_num(rmax, &rmax_var);
4259 
4260  init_var(&result);
4261 
4262  random_var(state, &rmin_var, &rmax_var, &result);
4263 
4264  res = make_result(&result);
4265 
4266  free_var(&result);
4267 
4268  return res;
4269 }
static void random_var(pg_prng_state *state, const NumericVar *rmin, const NumericVar *rmax, NumericVar *result)
Definition: numeric.c:11559
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().