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 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_to_numeric()

Numeric int64_to_numeric ( int64  val)

Definition at line 4079 of file numeric.c.

References free_var(), init_var, int64_to_numericvar(), and make_result().

Referenced by cash_numeric(), executeItemOptUnwrapTarget(), executeKeyValueMethod(), gbt_numeric_penalty(), int2_accum(), int2_accum_inv(), int2_numeric(), int4_accum(), int4_accum_inv(), int4_numeric(), int8_accum(), int8_accum_inv(), int8_avg(), int8_avg_accum(), int8_avg_accum_inv(), int8_numeric(), int8_sum(), int8_to_char(), numeric_avg(), numeric_cash(), numeric_half_rounded(), numeric_poly_avg(), numeric_shift_right(), numeric_to_char(), numeric_to_number(), pg_size_bytes(), pg_size_pretty_numeric(), and SV_to_JsonbValue().

4080 {
4081  Numeric res;
4082  NumericVar result;
4083 
4084  init_var(&result);
4085 
4086  int64_to_numericvar(val, &result);
4087 
4088  res = make_result(&result);
4089 
4090  free_var(&result);
4091 
4092  return res;
4093 }
static void free_var(NumericVar *var)
Definition: numeric.c:6720
static Numeric make_result(const NumericVar *var)
Definition: numeric.c:7362
static void int64_to_numericvar(int64 val, NumericVar *var)
Definition: numeric.c:7565
long val
Definition: informix.c:664
#define init_var(v)
Definition: numeric.c:495

◆ 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(), and numeric_add().

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:6953
static const NumericVar const_ninf
Definition: numeric.c:466
static Numeric make_result_opt_error(const NumericVar *var, bool *error)
Definition: numeric.c:7253
static void free_var(NumericVar *var)
Definition: numeric.c:6720
static const NumericVar const_pinf
Definition: numeric.c:463
#define Assert(condition)
Definition: c.h:792
static void add_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
Definition: numeric.c:7892
#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:7362
#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(), and numeric_div().

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:696
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:8338
static int select_div_scale(const NumericVar *var1, const NumericVar *var2)
Definition: numeric.c:8929
#define NUMERIC_IS_SPECIAL(n)
Definition: numeric.c:174
#define ERROR
Definition: elog.h:45
#define NUMERIC_IS_PINF(n)
Definition: numeric.c:206
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:6953
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:7253
static void free_var(NumericVar *var)
Definition: numeric.c:6720
#define ereport(elevel,...)
Definition: elog.h:155
static const NumericVar const_pinf
Definition: numeric.c:463
#define Assert(condition)
Definition: c.h:792
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:7362
int errmsg(const char *fmt,...)
Definition: elog.c:907
#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 4104 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().

4105 {
4106  NumericVar x;
4107  int32 result;
4108 
4109  if (have_error)
4110  *have_error = false;
4111 
4112  if (NUMERIC_IS_SPECIAL(num))
4113  {
4114  if (have_error)
4115  {
4116  *have_error = true;
4117  return 0;
4118  }
4119  else
4120  {
4121  if (NUMERIC_IS_NAN(num))
4122  ereport(ERROR,
4123  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4124  errmsg("cannot convert NaN to integer")));
4125  else
4126  ereport(ERROR,
4127  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4128  errmsg("cannot convert infinity to integer")));
4129  }
4130  }
4131 
4132  /* Convert to variable format, then convert to int4 */
4133  init_var_from_num(num, &x);
4134 
4135  if (!numericvar_to_int32(&x, &result))
4136  {
4137  if (have_error)
4138  {
4139  *have_error = true;
4140  return 0;
4141  }
4142  else
4143  {
4144  ereport(ERROR,
4145  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4146  errmsg("integer out of range")));
4147  }
4148  }
4149 
4150  return result;
4151 }
int errcode(int sqlerrcode)
Definition: elog.c:696
signed int int32
Definition: c.h:417
#define NUMERIC_IS_SPECIAL(n)
Definition: numeric.c:174
#define ERROR
Definition: elog.h:45
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:6953
static bool numericvar_to_int32(const NumericVar *var, int32 *result)
Definition: numeric.c:4167
#define ereport(elevel,...)
Definition: elog.h:155
int errmsg(const char *fmt,...)
Definition: elog.c:907
#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:615
signed int int32
Definition: c.h:417
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:696
int ndigits
Definition: numeric.c:306
static Numeric duplicate_numeric(Numeric num)
Definition: numeric.c:7234
#define NUMERIC_IS_SPECIAL(n)
Definition: numeric.c:174
#define ERROR
Definition: elog.h:45
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:6953
#define NUMERIC_IS_INF(n)
Definition: numeric.c:208
static void mod_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
Definition: numeric.c:8998
static Numeric make_result_opt_error(const NumericVar *var, bool *error)
Definition: numeric.c:7253
static void free_var(NumericVar *var)
Definition: numeric.c:6720
#define ereport(elevel,...)
Definition: elog.h:155
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:7362
int errmsg(const char *fmt,...)
Definition: elog.c:907
#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:6953
static const NumericVar const_ninf
Definition: numeric.c:466
static Numeric make_result_opt_error(const NumericVar *var, bool *error)
Definition: numeric.c:7253
static void free_var(NumericVar *var)
Definition: numeric.c:6720
static const NumericVar const_pinf
Definition: numeric.c:463
#define Assert(condition)
Definition: c.h:792
static void mul_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result, int rscale)
Definition: numeric.c:8130
#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:7362
#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:1187
#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:6953
#define NUMERIC_IS_NINF(n)
Definition: numeric.c:207
static char * get_str_from_var(const NumericVar *var)
Definition: numeric.c:6996

◆ 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:1187
int scale
Definition: pgbench.c:154
static char * get_str_from_var_sci(const NumericVar *var, int rscale)
Definition: numeric.c:7149
#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:6953
#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(), and numeric_sub().

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:6953
static const NumericVar const_ninf
Definition: numeric.c:466
static Numeric make_result_opt_error(const NumericVar *var, bool *error)
Definition: numeric.c:7253
static void free_var(NumericVar *var)
Definition: numeric.c:6720
static const NumericVar const_pinf
Definition: numeric.c:463
#define Assert(condition)
Definition: c.h:792
#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:7362
#define NUMERIC_IS_NAN(n)
Definition: numeric.c:205
static void sub_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
Definition: numeric.c:8009
#define init_var(v)
Definition: numeric.c:495