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

◆ numeric_add_opt_error()

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

Definition at line 2728 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(), and numeric_add().

2729 {
2730  NumericVar arg1;
2731  NumericVar arg2;
2732  NumericVar result;
2733  Numeric res;
2734 
2735  /*
2736  * Handle NaN and infinities
2737  */
2738  if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
2739  {
2740  if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2741  return make_result(&const_nan);
2742  if (NUMERIC_IS_PINF(num1))
2743  {
2744  if (NUMERIC_IS_NINF(num2))
2745  return make_result(&const_nan); /* Inf + -Inf */
2746  else
2747  return make_result(&const_pinf);
2748  }
2749  if (NUMERIC_IS_NINF(num1))
2750  {
2751  if (NUMERIC_IS_PINF(num2))
2752  return make_result(&const_nan); /* -Inf + Inf */
2753  else
2754  return make_result(&const_ninf);
2755  }
2756  /* by here, num1 must be finite, so num2 is not */
2757  if (NUMERIC_IS_PINF(num2))
2758  return make_result(&const_pinf);
2759  Assert(NUMERIC_IS_NINF(num2));
2760  return make_result(&const_ninf);
2761  }
2762 
2763  /*
2764  * Unpack the values, let add_var() compute the result and return it.
2765  */
2766  init_var_from_num(num1, &arg1);
2767  init_var_from_num(num2, &arg2);
2768 
2769  init_var(&result);
2770  add_var(&arg1, &arg2, &result);
2771 
2772  res = make_result_opt_error(&result, have_error);
2773 
2774  free_var(&result);
2775 
2776  return res;
2777 }
#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:7009
static const NumericVar const_ninf
Definition: numeric.c:466
static Numeric make_result_opt_error(const NumericVar *var, bool *error)
Definition: numeric.c:7309
static void free_var(NumericVar *var)
Definition: numeric.c:6776
static const NumericVar const_pinf
Definition: numeric.c:463
#define Assert(condition)
Definition: c.h:745
static void add_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
Definition: numeric.c:7948
#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:7418
#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 2998 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(), and numeric_div().

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

◆ numeric_int4_opt_error()

int32 numeric_int4_opt_error ( Numeric  num,
bool error 
)

Definition at line 4096 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().

4097 {
4098  NumericVar x;
4099  int32 result;
4100 
4101  if (have_error)
4102  *have_error = false;
4103 
4104  if (NUMERIC_IS_SPECIAL(num))
4105  {
4106  if (have_error)
4107  {
4108  *have_error = true;
4109  return 0;
4110  }
4111  else
4112  {
4113  if (NUMERIC_IS_NAN(num))
4114  ereport(ERROR,
4115  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4116  errmsg("cannot convert NaN to integer")));
4117  else
4118  ereport(ERROR,
4119  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4120  errmsg("cannot convert infinity to integer")));
4121  }
4122  }
4123 
4124  /* Convert to variable format, then convert to int4 */
4125  init_var_from_num(num, &x);
4126 
4127  if (!numericvar_to_int32(&x, &result))
4128  {
4129  if (have_error)
4130  {
4131  *have_error = true;
4132  return 0;
4133  }
4134  else
4135  {
4136  ereport(ERROR,
4137  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4138  errmsg("integer out of range")));
4139  }
4140  }
4141 
4142  return result;
4143 }
int errcode(int sqlerrcode)
Definition: elog.c:610
signed int int32
Definition: c.h:362
#define NUMERIC_IS_SPECIAL(n)
Definition: numeric.c:174
#define ERROR
Definition: elog.h:43
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:7009
static bool numericvar_to_int32(const NumericVar *var, int32 *result)
Definition: numeric.c:4159
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define NUMERIC_IS_NAN(n)
Definition: numeric.c:205

◆ numeric_is_inf()

bool numeric_is_inf ( Numeric  num)

Definition at line 784 of file numeric.c.

References NUMERIC_IS_INF.

Referenced by PLyNumber_ToJsonbValue().

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

◆ numeric_is_nan()

bool numeric_is_nan ( Numeric  num)

Definition at line 773 of file numeric.c.

References NUMERIC_IS_NAN.

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

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

◆ numeric_maximum_size()

int32 numeric_maximum_size ( int32  typmod)

Definition at line 819 of file numeric.c.

References DEC_DIGITS, NUMERIC_HDRSZ, and VARHDRSZ.

Referenced by type_maximum_size().

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

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

◆ numeric_mul_opt_error()

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

Definition at line 2884 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().

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

◆ numeric_normalize()

char* numeric_normalize ( Numeric  num)

Definition at line 892 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().

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

◆ numeric_out_sci()

char* numeric_out_sci ( Numeric  num,
int  scale 
)

Definition at line 858 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().

859 {
860  NumericVar x;
861  char *str;
862 
863  /*
864  * Handle NaN and infinities
865  */
866  if (NUMERIC_IS_SPECIAL(num))
867  {
868  if (NUMERIC_IS_PINF(num))
869  return pstrdup("Infinity");
870  else if (NUMERIC_IS_NINF(num))
871  return pstrdup("-Infinity");
872  else
873  return pstrdup("NaN");
874  }
875 
876  init_var_from_num(num, &x);
877 
878  str = get_str_from_var_sci(&x, scale);
879 
880  return str;
881 }
char * pstrdup(const char *in)
Definition: mcxt.c:1186
int scale
Definition: pgbench.c:153
static char * get_str_from_var_sci(const NumericVar *var, int rscale)
Definition: numeric.c:7205
#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:7009
#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 2806 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(), and numeric_sub().

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