PostgreSQL Source Code  git master
numeric.h File Reference
#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_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 DatumGetNumeric(X)   ((Numeric) PG_DETOAST_DATUM(X))
 
#define DatumGetNumericCopy(X)   ((Numeric) PG_DETOAST_DATUM_COPY(X))
 
#define NumericGetDatum(X)   PointerGetDatum(X)
 
#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

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 *error)
 

Macro Definition Documentation

◆ DatumGetNumeric

◆ DatumGetNumericCopy

#define DatumGetNumericCopy (   X)    ((Numeric) PG_DETOAST_DATUM_COPY(X))

Definition at line 50 of file numeric.h.

Referenced by jsonb_numeric().

◆ NUMERIC_MAX_DISPLAY_SCALE

#define NUMERIC_MAX_DISPLAY_SCALE   NUMERIC_MAX_PRECISION

◆ NUMERIC_MAX_PRECISION

#define NUMERIC_MAX_PRECISION   1000

Definition at line 24 of file numeric.h.

Referenced by numerictypmodin().

◆ NUMERIC_MAX_RESULT_SCALE

#define NUMERIC_MAX_RESULT_SCALE   (NUMERIC_MAX_PRECISION * 2)

Definition at line 32 of file numeric.h.

Referenced by exp_var(), numeric_exp(), numeric_round(), numeric_trunc(), and power_var().

◆ NUMERIC_MIN_DISPLAY_SCALE

#define NUMERIC_MIN_DISPLAY_SCALE   0

◆ NUMERIC_MIN_SIG_DIGITS

#define NUMERIC_MIN_SIG_DIGITS   16

Definition at line 39 of file numeric.h.

Referenced by log_var(), numeric_exp(), numeric_ln(), numeric_sqrt(), power_var(), and select_div_scale().

◆ NumericGetDatum

◆ PG_GETARG_NUMERIC

◆ PG_GETARG_NUMERIC_COPY

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

Definition at line 53 of file numeric.h.

◆ PG_RETURN_NUMERIC

Typedef Documentation

◆ Numeric

typedef struct NumericData* Numeric

Definition at line 43 of file numeric.h.

Function Documentation

◆ int64_div_fast_to_numeric()

Numeric int64_div_fast_to_numeric ( int64  val1,
int  log10val2 
)

Definition at line 4100 of file numeric.c.

References DatumGetNumeric, DEC_DIGITS, DirectFunctionCall2, NumericVar::dscale, free_var(), i, init_var, Int32GetDatum, int64_to_numeric(), int64_to_numericvar(), lengthof, make_result(), numeric_div_opt_error(), numeric_round(), NumericGetDatum, pg_mul_s64_overflow(), StaticAssertStmt, unlikely, and NumericVar::weight.

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

4101 {
4102  Numeric res;
4103  NumericVar result;
4104  int64 saved_val1 = val1;
4105  int w;
4106  int m;
4107 
4108  /* how much to decrease the weight by */
4109  w = log10val2 / DEC_DIGITS;
4110  /* how much is left */
4111  m = log10val2 % DEC_DIGITS;
4112 
4113  /*
4114  * If there is anything left, multiply the dividend by what's left, then
4115  * shift the weight by one more.
4116  */
4117  if (m > 0)
4118  {
4119  static int pow10[] = {1, 10, 100, 1000};
4120 
4121  StaticAssertStmt(lengthof(pow10) == DEC_DIGITS, "mismatch with DEC_DIGITS");
4122  if (unlikely(pg_mul_s64_overflow(val1, pow10[DEC_DIGITS - m], &val1)))
4123  {
4124  /*
4125  * If it doesn't fit, do the whole computation in numeric the slow
4126  * way. Note that va1l may have been overwritten, so use
4127  * saved_val1 instead.
4128  */
4129  int val2 = 1;
4130 
4131  for (int i = 0; i < log10val2; i++)
4132  val2 *= 10;
4133  res = numeric_div_opt_error(int64_to_numeric(saved_val1), int64_to_numeric(val2), NULL);
4135  NumericGetDatum(res),
4136  Int32GetDatum(log10val2)));
4137  return res;
4138  }
4139  w++;
4140  }
4141 
4142  init_var(&result);
4143 
4144  int64_to_numericvar(val1, &result);
4145 
4146  result.weight -= w;
4147  result.dscale += w * DEC_DIGITS - (DEC_DIGITS - m);
4148 
4149  res = make_result(&result);
4150 
4151  free_var(&result);
4152 
4153  return res;
4154 }
int weight
Definition: numeric.c:307
Numeric numeric_div_opt_error(Numeric num1, Numeric num2, bool *have_error)
Definition: numeric.c:3000
#define NumericGetDatum(X)
Definition: numeric.h:51
Datum numeric_round(PG_FUNCTION_ARGS)
Definition: numeric.c:1408
#define lengthof(array)
Definition: c.h:734
int dscale
Definition: numeric.c:309
#define StaticAssertStmt(condition, errmessage)
Definition: c.h:918
Numeric int64_to_numeric(int64 val)
Definition: numeric.c:4079
static void free_var(NumericVar *var)
Definition: numeric.c:6781
static bool pg_mul_s64_overflow(int64 a, int64 b, int64 *result)
Definition: int.h:215
#define DatumGetNumeric(X)
Definition: numeric.h:49
static Numeric make_result(const NumericVar *var)
Definition: numeric.c:7423
#define Int32GetDatum(X)
Definition: postgres.h:523
static void int64_to_numericvar(int64 val, NumericVar *var)
Definition: numeric.c:7626
int i
#define unlikely(x)
Definition: c.h:273
#define DEC_DIGITS
Definition: numeric.c:99
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:628
#define init_var(v)
Definition: numeric.c:495

◆ int64_to_numeric()

Numeric int64_to_numeric ( int64  val)

◆ numeric_add_opt_error()

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

Definition at line 2730 of file numeric.c.

References add_var(), Assert, free_var(), init_var, init_var_from_num(), make_result(), make_result_opt_error(), 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().

2731 {
2732  NumericVar arg1;
2733  NumericVar arg2;
2734  NumericVar result;
2735  Numeric res;
2736 
2737  /*
2738  * Handle NaN and infinities
2739  */
2740  if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
2741  {
2742  if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2743  return make_result(&const_nan);
2744  if (NUMERIC_IS_PINF(num1))
2745  {
2746  if (NUMERIC_IS_NINF(num2))
2747  return make_result(&const_nan); /* Inf + -Inf */
2748  else
2749  return make_result(&const_pinf);
2750  }
2751  if (NUMERIC_IS_NINF(num1))
2752  {
2753  if (NUMERIC_IS_PINF(num2))
2754  return make_result(&const_nan); /* -Inf + Inf */
2755  else
2756  return make_result(&const_ninf);
2757  }
2758  /* by here, num1 must be finite, so num2 is not */
2759  if (NUMERIC_IS_PINF(num2))
2760  return make_result(&const_pinf);
2761  Assert(NUMERIC_IS_NINF(num2));
2762  return make_result(&const_ninf);
2763  }
2764 
2765  /*
2766  * Unpack the values, let add_var() compute the result and return it.
2767  */
2768  init_var_from_num(num1, &arg1);
2769  init_var_from_num(num2, &arg2);
2770 
2771  init_var(&result);
2772  add_var(&arg1, &arg2, &result);
2773 
2774  res = make_result_opt_error(&result, have_error);
2775 
2776  free_var(&result);
2777 
2778  return res;
2779 }
#define NUMERIC_IS_SPECIAL(n)
Definition: numeric.c:174
#define NUMERIC_IS_PINF(n)
Definition: numeric.c:206
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:7014
static const NumericVar const_ninf
Definition: numeric.c:466
static Numeric make_result_opt_error(const NumericVar *var, bool *error)
Definition: numeric.c:7314
static void free_var(NumericVar *var)
Definition: numeric.c:6781
static const NumericVar const_pinf
Definition: numeric.c:463
#define Assert(condition)
Definition: c.h:804
static void add_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
Definition: numeric.c:7953
#define NUMERIC_IS_NINF(n)
Definition: numeric.c:207
static const NumericVar const_nan
Definition: numeric.c:460
static Numeric make_result(const NumericVar *var)
Definition: numeric.c:7423
#define NUMERIC_IS_NAN(n)
Definition: numeric.c:205
#define init_var(v)
Definition: numeric.c:495

◆ numeric_div_opt_error()

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

Definition at line 3000 of file numeric.c.

References Assert, 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(), and select_div_scale().

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

3001 {
3002  NumericVar arg1;
3003  NumericVar arg2;
3004  NumericVar result;
3005  Numeric res;
3006  int rscale;
3007 
3008  if (have_error)
3009  *have_error = false;
3010 
3011  /*
3012  * Handle NaN and infinities
3013  */
3014  if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
3015  {
3016  if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
3017  return make_result(&const_nan);
3018  if (NUMERIC_IS_PINF(num1))
3019  {
3020  if (NUMERIC_IS_SPECIAL(num2))
3021  return make_result(&const_nan); /* Inf / [-]Inf */
3022  switch (numeric_sign_internal(num2))
3023  {
3024  case 0:
3025  if (have_error)
3026  {
3027  *have_error = true;
3028  return NULL;
3029  }
3030  ereport(ERROR,
3031  (errcode(ERRCODE_DIVISION_BY_ZERO),
3032  errmsg("division by zero")));
3033  break;
3034  case 1:
3035  return make_result(&const_pinf);
3036  case -1:
3037  return make_result(&const_ninf);
3038  }
3039  Assert(false);
3040  }
3041  if (NUMERIC_IS_NINF(num1))
3042  {
3043  if (NUMERIC_IS_SPECIAL(num2))
3044  return make_result(&const_nan); /* -Inf / [-]Inf */
3045  switch (numeric_sign_internal(num2))
3046  {
3047  case 0:
3048  if (have_error)
3049  {
3050  *have_error = true;
3051  return NULL;
3052  }
3053  ereport(ERROR,
3054  (errcode(ERRCODE_DIVISION_BY_ZERO),
3055  errmsg("division by zero")));
3056  break;
3057  case 1:
3058  return make_result(&const_ninf);
3059  case -1:
3060  return make_result(&const_pinf);
3061  }
3062  Assert(false);
3063  }
3064  /* by here, num1 must be finite, so num2 is not */
3065 
3066  /*
3067  * POSIX would have us return zero or minus zero if num1 is zero, and
3068  * otherwise throw an underflow error. But the numeric type doesn't
3069  * really do underflow, so let's just return zero.
3070  */
3071  return make_result(&const_zero);
3072  }
3073 
3074  /*
3075  * Unpack the arguments
3076  */
3077  init_var_from_num(num1, &arg1);
3078  init_var_from_num(num2, &arg2);
3079 
3080  init_var(&result);
3081 
3082  /*
3083  * Select scale for division result
3084  */
3085  rscale = select_div_scale(&arg1, &arg2);
3086 
3087  /*
3088  * If "have_error" is provided, check for division by zero here
3089  */
3090  if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
3091  {
3092  *have_error = true;
3093  return NULL;
3094  }
3095 
3096  /*
3097  * Do the divide and return the result
3098  */
3099  div_var(&arg1, &arg2, &result, rscale, true);
3100 
3101  res = make_result_opt_error(&result, have_error);
3102 
3103  free_var(&result);
3104 
3105  return res;
3106 }
int errcode(int sqlerrcode)
Definition: elog.c:698
int ndigits
Definition: numeric.c:306
static void div_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result, int rscale, bool round)
Definition: numeric.c:8399
static int select_div_scale(const NumericVar *var1, const NumericVar *var2)
Definition: numeric.c:8990
#define NUMERIC_IS_SPECIAL(n)
Definition: numeric.c:174
#define ERROR
Definition: elog.h:46
#define NUMERIC_IS_PINF(n)
Definition: numeric.c:206
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:7014
static const NumericVar const_ninf
Definition: numeric.c:466
static const NumericVar const_zero
Definition: numeric.c:416
static Numeric make_result_opt_error(const NumericVar *var, bool *error)
Definition: numeric.c:7314
static void free_var(NumericVar *var)
Definition: numeric.c:6781
#define ereport(elevel,...)
Definition: elog.h:157
static const NumericVar const_pinf
Definition: numeric.c:463
#define Assert(condition)
Definition: c.h:804
NumericDigit * digits
Definition: numeric.c:311
#define NUMERIC_IS_NINF(n)
Definition: numeric.c:207
static const NumericVar const_nan
Definition: numeric.c:460
static Numeric make_result(const NumericVar *var)
Definition: numeric.c:7423
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define NUMERIC_IS_NAN(n)
Definition: numeric.c:205
#define init_var(v)
Definition: numeric.c:495
static int numeric_sign_internal(Numeric num)
Definition: numeric.c:1343

◆ numeric_int4_opt_error()

int32 numeric_int4_opt_error ( Numeric  num,
bool error 
)

Definition at line 4165 of file numeric.c.

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

Referenced by getArrayIndex(), and numeric_int4().

4166 {
4167  NumericVar x;
4168  int32 result;
4169 
4170  if (have_error)
4171  *have_error = false;
4172 
4173  if (NUMERIC_IS_SPECIAL(num))
4174  {
4175  if (have_error)
4176  {
4177  *have_error = true;
4178  return 0;
4179  }
4180  else
4181  {
4182  if (NUMERIC_IS_NAN(num))
4183  ereport(ERROR,
4184  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4185  errmsg("cannot convert NaN to integer")));
4186  else
4187  ereport(ERROR,
4188  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4189  errmsg("cannot convert infinity to integer")));
4190  }
4191  }
4192 
4193  /* Convert to variable format, then convert to int4 */
4194  init_var_from_num(num, &x);
4195 
4196  if (!numericvar_to_int32(&x, &result))
4197  {
4198  if (have_error)
4199  {
4200  *have_error = true;
4201  return 0;
4202  }
4203  else
4204  {
4205  ereport(ERROR,
4206  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4207  errmsg("integer out of range")));
4208  }
4209  }
4210 
4211  return result;
4212 }
int errcode(int sqlerrcode)
Definition: elog.c:698
signed int int32
Definition: c.h:429
#define NUMERIC_IS_SPECIAL(n)
Definition: numeric.c:174
#define ERROR
Definition: elog.h:46
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:7014
static bool numericvar_to_int32(const NumericVar *var, int32 *result)
Definition: numeric.c:4228
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define NUMERIC_IS_NAN(n)
Definition: numeric.c:205

◆ numeric_is_inf()

bool numeric_is_inf ( Numeric  num)

Definition at line 785 of file numeric.c.

References NUMERIC_IS_INF.

Referenced by PLyNumber_ToJsonbValue().

786 {
787  return NUMERIC_IS_INF(num);
788 }
#define NUMERIC_IS_INF(n)
Definition: numeric.c:208

◆ numeric_is_nan()

bool numeric_is_nan ( Numeric  num)

Definition at line 774 of file numeric.c.

References NUMERIC_IS_NAN.

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

775 {
776  return NUMERIC_IS_NAN(num);
777 }
#define NUMERIC_IS_NAN(n)
Definition: numeric.c:205

◆ numeric_maximum_size()

int32 numeric_maximum_size ( int32  typmod)

Definition at line 820 of file numeric.c.

References DEC_DIGITS, NUMERIC_HDRSZ, and VARHDRSZ.

Referenced by type_maximum_size().

821 {
822  int precision;
823  int numeric_digits;
824 
825  if (typmod < (int32) (VARHDRSZ))
826  return -1;
827 
828  /* precision (ie, max # of digits) is in upper bits of typmod */
829  precision = ((typmod - VARHDRSZ) >> 16) & 0xffff;
830 
831  /*
832  * This formula computes the maximum number of NumericDigits we could need
833  * in order to store the specified number of decimal digits. Because the
834  * weight is stored as a number of NumericDigits rather than a number of
835  * decimal digits, it's possible that the first NumericDigit will contain
836  * only a single decimal digit. Thus, the first two decimal digits can
837  * require two NumericDigits to store, but it isn't until we reach
838  * DEC_DIGITS + 2 decimal digits that we potentially need a third
839  * NumericDigit.
840  */
841  numeric_digits = (precision + 2 * (DEC_DIGITS - 1)) / DEC_DIGITS;
842 
843  /*
844  * In most cases, the size of a numeric will be smaller than the value
845  * computed below, because the varlena header will typically get toasted
846  * down to a single byte before being stored on disk, and it may also be
847  * possible to use a short numeric header. But our job here is to compute
848  * the worst case.
849  */
850  return NUMERIC_HDRSZ + (numeric_digits * sizeof(NumericDigit));
851 }
#define NUMERIC_HDRSZ
Definition: numeric.c:176
#define VARHDRSZ
Definition: c.h:627
signed int int32
Definition: c.h:429
int16 NumericDigit
Definition: numeric.c:103
#define DEC_DIGITS
Definition: numeric.c:99

◆ numeric_mod_opt_error()

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

Definition at line 3224 of file numeric.c.

References 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, and numeric_sign_internal().

Referenced by executeItemOptUnwrapTarget(), and numeric_mod().

3225 {
3226  Numeric res;
3227  NumericVar arg1;
3228  NumericVar arg2;
3229  NumericVar result;
3230 
3231  if (have_error)
3232  *have_error = false;
3233 
3234  /*
3235  * Handle NaN and infinities. We follow POSIX fmod() on this, except that
3236  * POSIX treats x-is-infinite and y-is-zero identically, raising EDOM and
3237  * returning NaN. We choose to throw error only for y-is-zero.
3238  */
3239  if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
3240  {
3241  if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
3242  return make_result(&const_nan);
3243  if (NUMERIC_IS_INF(num1))
3244  {
3245  if (numeric_sign_internal(num2) == 0)
3246  {
3247  if (have_error)
3248  {
3249  *have_error = true;
3250  return NULL;
3251  }
3252  ereport(ERROR,
3253  (errcode(ERRCODE_DIVISION_BY_ZERO),
3254  errmsg("division by zero")));
3255  }
3256  /* Inf % any nonzero = NaN */
3257  return make_result(&const_nan);
3258  }
3259  /* num2 must be [-]Inf; result is num1 regardless of sign of num2 */
3260  return duplicate_numeric(num1);
3261  }
3262 
3263  init_var_from_num(num1, &arg1);
3264  init_var_from_num(num2, &arg2);
3265 
3266  init_var(&result);
3267 
3268  /*
3269  * If "have_error" is provided, check for division by zero here
3270  */
3271  if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
3272  {
3273  *have_error = true;
3274  return NULL;
3275  }
3276 
3277  mod_var(&arg1, &arg2, &result);
3278 
3279  res = make_result_opt_error(&result, NULL);
3280 
3281  free_var(&result);
3282 
3283  return res;
3284 }
int errcode(int sqlerrcode)
Definition: elog.c:698
int ndigits
Definition: numeric.c:306
static Numeric duplicate_numeric(Numeric num)
Definition: numeric.c:7295
#define NUMERIC_IS_SPECIAL(n)
Definition: numeric.c:174
#define ERROR
Definition: elog.h:46
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:7014
#define NUMERIC_IS_INF(n)
Definition: numeric.c:208
static void mod_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
Definition: numeric.c:9059
static Numeric make_result_opt_error(const NumericVar *var, bool *error)
Definition: numeric.c:7314
static void free_var(NumericVar *var)
Definition: numeric.c:6781
#define ereport(elevel,...)
Definition: elog.h:157
NumericDigit * digits
Definition: numeric.c:311
static const NumericVar const_nan
Definition: numeric.c:460
static Numeric make_result(const NumericVar *var)
Definition: numeric.c:7423
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define NUMERIC_IS_NAN(n)
Definition: numeric.c:205
#define init_var(v)
Definition: numeric.c:495
static int numeric_sign_internal(Numeric num)
Definition: numeric.c:1343

◆ numeric_mul_opt_error()

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

Definition at line 2886 of file numeric.c.

References Assert, NumericVar::dscale, free_var(), init_var, init_var_from_num(), make_result(), make_result_opt_error(), mul_var(), NUMERIC_IS_NAN, NUMERIC_IS_NINF, NUMERIC_IS_PINF, NUMERIC_IS_SPECIAL, and numeric_sign_internal().

Referenced by executeItemOptUnwrapTarget(), and numeric_mul().

2887 {
2888  NumericVar arg1;
2889  NumericVar arg2;
2890  NumericVar result;
2891  Numeric res;
2892 
2893  /*
2894  * Handle NaN and infinities
2895  */
2896  if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
2897  {
2898  if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2899  return make_result(&const_nan);
2900  if (NUMERIC_IS_PINF(num1))
2901  {
2902  switch (numeric_sign_internal(num2))
2903  {
2904  case 0:
2905  return make_result(&const_nan); /* Inf * 0 */
2906  case 1:
2907  return make_result(&const_pinf);
2908  case -1:
2909  return make_result(&const_ninf);
2910  }
2911  Assert(false);
2912  }
2913  if (NUMERIC_IS_NINF(num1))
2914  {
2915  switch (numeric_sign_internal(num2))
2916  {
2917  case 0:
2918  return make_result(&const_nan); /* -Inf * 0 */
2919  case 1:
2920  return make_result(&const_ninf);
2921  case -1:
2922  return make_result(&const_pinf);
2923  }
2924  Assert(false);
2925  }
2926  /* by here, num1 must be finite, so num2 is not */
2927  if (NUMERIC_IS_PINF(num2))
2928  {
2929  switch (numeric_sign_internal(num1))
2930  {
2931  case 0:
2932  return make_result(&const_nan); /* 0 * Inf */
2933  case 1:
2934  return make_result(&const_pinf);
2935  case -1:
2936  return make_result(&const_ninf);
2937  }
2938  Assert(false);
2939  }
2940  Assert(NUMERIC_IS_NINF(num2));
2941  switch (numeric_sign_internal(num1))
2942  {
2943  case 0:
2944  return make_result(&const_nan); /* 0 * -Inf */
2945  case 1:
2946  return make_result(&const_ninf);
2947  case -1:
2948  return make_result(&const_pinf);
2949  }
2950  Assert(false);
2951  }
2952 
2953  /*
2954  * Unpack the values, let mul_var() compute the result and return it.
2955  * Unlike add_var() and sub_var(), mul_var() will round its result. In the
2956  * case of numeric_mul(), which is invoked for the * operator on numerics,
2957  * we request exact representation for the product (rscale = sum(dscale of
2958  * arg1, dscale of arg2)).
2959  */
2960  init_var_from_num(num1, &arg1);
2961  init_var_from_num(num2, &arg2);
2962 
2963  init_var(&result);
2964  mul_var(&arg1, &arg2, &result, arg1.dscale + arg2.dscale);
2965 
2966  res = make_result_opt_error(&result, have_error);
2967 
2968  free_var(&result);
2969 
2970  return res;
2971 }
int dscale
Definition: numeric.c:309
#define NUMERIC_IS_SPECIAL(n)
Definition: numeric.c:174
#define NUMERIC_IS_PINF(n)
Definition: numeric.c:206
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:7014
static const NumericVar const_ninf
Definition: numeric.c:466
static Numeric make_result_opt_error(const NumericVar *var, bool *error)
Definition: numeric.c:7314
static void free_var(NumericVar *var)
Definition: numeric.c:6781
static const NumericVar const_pinf
Definition: numeric.c:463
#define Assert(condition)
Definition: c.h:804
static void mul_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result, int rscale)
Definition: numeric.c:8191
#define NUMERIC_IS_NINF(n)
Definition: numeric.c:207
static const NumericVar const_nan
Definition: numeric.c:460
static Numeric make_result(const NumericVar *var)
Definition: numeric.c:7423
#define NUMERIC_IS_NAN(n)
Definition: numeric.c:205
#define init_var(v)
Definition: numeric.c:495
static int numeric_sign_internal(Numeric num)
Definition: numeric.c:1343

◆ numeric_normalize()

char* numeric_normalize ( Numeric  num)

Definition at line 893 of file numeric.c.

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

Referenced by make_scalar_key().

894 {
895  NumericVar x;
896  char *str;
897  int last;
898 
899  /*
900  * Handle NaN and infinities
901  */
902  if (NUMERIC_IS_SPECIAL(num))
903  {
904  if (NUMERIC_IS_PINF(num))
905  return pstrdup("Infinity");
906  else if (NUMERIC_IS_NINF(num))
907  return pstrdup("-Infinity");
908  else
909  return pstrdup("NaN");
910  }
911 
912  init_var_from_num(num, &x);
913 
914  str = get_str_from_var(&x);
915 
916  /* If there's no decimal point, there's certainly nothing to remove. */
917  if (strchr(str, '.') != NULL)
918  {
919  /*
920  * Back up over trailing fractional zeroes. Since there is a decimal
921  * point, this loop will terminate safely.
922  */
923  last = strlen(str) - 1;
924  while (str[last] == '0')
925  last--;
926 
927  /* We want to get rid of the decimal point too, if it's now last. */
928  if (str[last] == '.')
929  last--;
930 
931  /* Delete whatever we backed up over. */
932  str[last + 1] = '\0';
933  }
934 
935  return str;
936 }
char * pstrdup(const char *in)
Definition: mcxt.c:1299
#define NUMERIC_IS_SPECIAL(n)
Definition: numeric.c:174
#define NUMERIC_IS_PINF(n)
Definition: numeric.c:206
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:7014
#define NUMERIC_IS_NINF(n)
Definition: numeric.c:207
static char * get_str_from_var(const NumericVar *var)
Definition: numeric.c:7057

◆ numeric_out_sci()

char* numeric_out_sci ( Numeric  num,
int  scale 
)

Definition at line 859 of file numeric.c.

References get_str_from_var_sci(), init_var_from_num(), NUMERIC_IS_NINF, NUMERIC_IS_PINF, NUMERIC_IS_SPECIAL, pstrdup(), and generate_unaccent_rules::str.

Referenced by int8_to_char(), and numeric_to_char().

860 {
861  NumericVar x;
862  char *str;
863 
864  /*
865  * Handle NaN and infinities
866  */
867  if (NUMERIC_IS_SPECIAL(num))
868  {
869  if (NUMERIC_IS_PINF(num))
870  return pstrdup("Infinity");
871  else if (NUMERIC_IS_NINF(num))
872  return pstrdup("-Infinity");
873  else
874  return pstrdup("NaN");
875  }
876 
877  init_var_from_num(num, &x);
878 
879  str = get_str_from_var_sci(&x, scale);
880 
881  return str;
882 }
char * pstrdup(const char *in)
Definition: mcxt.c:1299
int scale
Definition: pgbench.c:189
static char * get_str_from_var_sci(const NumericVar *var, int rscale)
Definition: numeric.c:7210
#define NUMERIC_IS_SPECIAL(n)
Definition: numeric.c:174
#define NUMERIC_IS_PINF(n)
Definition: numeric.c:206
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:7014
#define NUMERIC_IS_NINF(n)
Definition: numeric.c:207

◆ numeric_sub_opt_error()

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

Definition at line 2808 of file numeric.c.

References Assert, 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 sub_var().

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

2809 {
2810  NumericVar arg1;
2811  NumericVar arg2;
2812  NumericVar result;
2813  Numeric res;
2814 
2815  /*
2816  * Handle NaN and infinities
2817  */
2818  if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
2819  {
2820  if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2821  return make_result(&const_nan);
2822  if (NUMERIC_IS_PINF(num1))
2823  {
2824  if (NUMERIC_IS_PINF(num2))
2825  return make_result(&const_nan); /* Inf - Inf */
2826  else
2827  return make_result(&const_pinf);
2828  }
2829  if (NUMERIC_IS_NINF(num1))
2830  {
2831  if (NUMERIC_IS_NINF(num2))
2832  return make_result(&const_nan); /* -Inf - -Inf */
2833  else
2834  return make_result(&const_ninf);
2835  }
2836  /* by here, num1 must be finite, so num2 is not */
2837  if (NUMERIC_IS_PINF(num2))
2838  return make_result(&const_ninf);
2839  Assert(NUMERIC_IS_NINF(num2));
2840  return make_result(&const_pinf);
2841  }
2842 
2843  /*
2844  * Unpack the values, let sub_var() compute the result and return it.
2845  */
2846  init_var_from_num(num1, &arg1);
2847  init_var_from_num(num2, &arg2);
2848 
2849  init_var(&result);
2850  sub_var(&arg1, &arg2, &result);
2851 
2852  res = make_result_opt_error(&result, have_error);
2853 
2854  free_var(&result);
2855 
2856  return res;
2857 }
#define NUMERIC_IS_SPECIAL(n)
Definition: numeric.c:174
#define NUMERIC_IS_PINF(n)
Definition: numeric.c:206
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:7014
static const NumericVar const_ninf
Definition: numeric.c:466
static Numeric make_result_opt_error(const NumericVar *var, bool *error)
Definition: numeric.c:7314
static void free_var(NumericVar *var)
Definition: numeric.c:6781
static const NumericVar const_pinf
Definition: numeric.c:463
#define Assert(condition)
Definition: c.h:804
#define NUMERIC_IS_NINF(n)
Definition: numeric.c:207
static const NumericVar const_nan
Definition: numeric.c:460
static Numeric make_result(const NumericVar *var)
Definition: numeric.c:7423
#define NUMERIC_IS_NAN(n)
Definition: numeric.c:205
static void sub_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
Definition: numeric.c:8070
#define init_var(v)
Definition: numeric.c:495