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

References add_var(), free_var(), init_var, init_var_from_num(), make_result(), make_result_opt_error(), and NUMERIC_IS_NAN.

Referenced by executeItemOptUnwrapTarget(), and numeric_add().

2429 {
2430  NumericVar arg1;
2431  NumericVar arg2;
2432  NumericVar result;
2433  Numeric res;
2434 
2435  /*
2436  * Handle NaN
2437  */
2438  if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2439  return make_result(&const_nan);
2440 
2441  /*
2442  * Unpack the values, let add_var() compute the result and return it.
2443  */
2444  init_var_from_num(num1, &arg1);
2445  init_var_from_num(num2, &arg2);
2446 
2447  init_var(&result);
2448  add_var(&arg1, &arg2, &result);
2449 
2450  res = make_result_opt_error(&result, have_error);
2451 
2452  free_var(&result);
2453 
2454  return res;
2455 }
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:5968
static Numeric make_result_opt_error(const NumericVar *var, bool *error)
Definition: numeric.c:6252
static void free_var(NumericVar *var)
Definition: numeric.c:5735
static void add_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
Definition: numeric.c:6797
static const NumericVar const_nan
Definition: numeric.c:425
static Numeric make_result(const NumericVar *var)
Definition: numeric.c:6351
#define NUMERIC_IS_NAN(n)
Definition: numeric.c:173
#define init_var(v)
Definition: numeric.c:454

◆ numeric_div_opt_error()

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

Definition at line 2600 of file numeric.c.

References NumericVar::digits, div_var(), free_var(), init_var, init_var_from_num(), make_result(), make_result_opt_error(), NumericVar::ndigits, NUMERIC_IS_NAN, and select_div_scale().

Referenced by executeItemOptUnwrapTarget(), and numeric_div().

2601 {
2602  NumericVar arg1;
2603  NumericVar arg2;
2604  NumericVar result;
2605  Numeric res;
2606  int rscale;
2607 
2608  if (have_error)
2609  *have_error = false;
2610 
2611  /*
2612  * Handle NaN
2613  */
2614  if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2615  return make_result(&const_nan);
2616 
2617  /*
2618  * Unpack the arguments
2619  */
2620  init_var_from_num(num1, &arg1);
2621  init_var_from_num(num2, &arg2);
2622 
2623  init_var(&result);
2624 
2625  /*
2626  * Select scale for division result
2627  */
2628  rscale = select_div_scale(&arg1, &arg2);
2629 
2630  /*
2631  * If "have_error" is provided, check for division by zero here
2632  */
2633  if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
2634  {
2635  *have_error = true;
2636  return NULL;
2637  }
2638 
2639  /*
2640  * Do the divide and return the result
2641  */
2642  div_var(&arg1, &arg2, &result, rscale, true);
2643 
2644  res = make_result_opt_error(&result, have_error);
2645 
2646  free_var(&result);
2647 
2648  return res;
2649 }
int ndigits
Definition: numeric.c:274
static void div_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result, int rscale, bool round)
Definition: numeric.c:7232
static int select_div_scale(const NumericVar *var1, const NumericVar *var2)
Definition: numeric.c:7812
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:5968
static Numeric make_result_opt_error(const NumericVar *var, bool *error)
Definition: numeric.c:6252
static void free_var(NumericVar *var)
Definition: numeric.c:5735
NumericDigit * digits
Definition: numeric.c:279
static const NumericVar const_nan
Definition: numeric.c:425
static Numeric make_result(const NumericVar *var)
Definition: numeric.c:6351
#define NUMERIC_IS_NAN(n)
Definition: numeric.c:173
#define init_var(v)
Definition: numeric.c:454

◆ numeric_int4_opt_error()

int32 numeric_int4_opt_error ( Numeric  num,
bool error 
)

Definition at line 3211 of file numeric.c.

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

Referenced by getArrayIndex(), and numeric_int4().

3212 {
3213  NumericVar x;
3214  int32 result;
3215 
3216  if (have_error)
3217  *have_error = false;
3218 
3219  /* XXX would it be better to return NULL? */
3220  if (NUMERIC_IS_NAN(num))
3221  {
3222  if (have_error)
3223  {
3224  *have_error = true;
3225  return 0;
3226  }
3227  else
3228  {
3229  ereport(ERROR,
3230  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3231  errmsg("cannot convert NaN to integer")));
3232  }
3233  }
3234 
3235  /* Convert to variable format, then convert to int4 */
3236  init_var_from_num(num, &x);
3237 
3238  if (!numericvar_to_int32(&x, &result))
3239  {
3240  if (have_error)
3241  {
3242  *have_error = true;
3243  return 0;
3244  }
3245  else
3246  {
3247  ereport(ERROR,
3248  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
3249  errmsg("integer out of range")));
3250  }
3251  }
3252 
3253  return result;
3254 }
int errcode(int sqlerrcode)
Definition: elog.c:570
signed int int32
Definition: c.h:346
#define ERROR
Definition: elog.h:43
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:5968
#define ereport(elevel, rest)
Definition: elog.h:141
static bool numericvar_to_int32(const NumericVar *var, int32 *result)
Definition: numeric.c:3270
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define NUMERIC_IS_NAN(n)
Definition: numeric.c:173

◆ numeric_is_nan()

bool numeric_is_nan ( Numeric  num)

Definition at line 683 of file numeric.c.

References NUMERIC_IS_NAN.

Referenced by convertJsonbScalar(), gbt_numeric_penalty(), and PLyNumber_ToJsonbValue().

684 {
685  return NUMERIC_IS_NAN(num);
686 }
#define NUMERIC_IS_NAN(n)
Definition: numeric.c:173

◆ numeric_maximum_size()

int32 numeric_maximum_size ( int32  typmod)

Definition at line 694 of file numeric.c.

References DEC_DIGITS, NUMERIC_HDRSZ, and VARHDRSZ.

Referenced by type_maximum_size().

695 {
696  int precision;
697  int numeric_digits;
698 
699  if (typmod < (int32) (VARHDRSZ))
700  return -1;
701 
702  /* precision (ie, max # of digits) is in upper bits of typmod */
703  precision = ((typmod - VARHDRSZ) >> 16) & 0xffff;
704 
705  /*
706  * This formula computes the maximum number of NumericDigits we could need
707  * in order to store the specified number of decimal digits. Because the
708  * weight is stored as a number of NumericDigits rather than a number of
709  * decimal digits, it's possible that the first NumericDigit will contain
710  * only a single decimal digit. Thus, the first two decimal digits can
711  * require two NumericDigits to store, but it isn't until we reach
712  * DEC_DIGITS + 2 decimal digits that we potentially need a third
713  * NumericDigit.
714  */
715  numeric_digits = (precision + 2 * (DEC_DIGITS - 1)) / DEC_DIGITS;
716 
717  /*
718  * In most cases, the size of a numeric will be smaller than the value
719  * computed below, because the varlena header will typically get toasted
720  * down to a single byte before being stored on disk, and it may also be
721  * possible to use a short numeric header. But our job here is to compute
722  * the worst case.
723  */
724  return NUMERIC_HDRSZ + (numeric_digits * sizeof(NumericDigit));
725 }
#define NUMERIC_HDRSZ
Definition: numeric.c:176
#define VARHDRSZ
Definition: c.h:555
signed int int32
Definition: c.h:346
int16 NumericDigit
Definition: numeric.c:102
#define DEC_DIGITS
Definition: numeric.c:98

◆ numeric_mod_opt_error()

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

Definition at line 2720 of file numeric.c.

References NumericVar::digits, free_var(), init_var, init_var_from_num(), make_result(), make_result_opt_error(), mod_var(), NumericVar::ndigits, and NUMERIC_IS_NAN.

Referenced by executeItemOptUnwrapTarget(), and numeric_mod().

2721 {
2722  Numeric res;
2723  NumericVar arg1;
2724  NumericVar arg2;
2725  NumericVar result;
2726 
2727  if (have_error)
2728  *have_error = false;
2729 
2730  if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2731  return make_result(&const_nan);
2732 
2733  init_var_from_num(num1, &arg1);
2734  init_var_from_num(num2, &arg2);
2735 
2736  init_var(&result);
2737 
2738  /*
2739  * If "have_error" is provided, check for division by zero here
2740  */
2741  if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
2742  {
2743  *have_error = true;
2744  return NULL;
2745  }
2746 
2747  mod_var(&arg1, &arg2, &result);
2748 
2749  res = make_result_opt_error(&result, NULL);
2750 
2751  free_var(&result);
2752 
2753  return res;
2754 }
int ndigits
Definition: numeric.c:274
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:5968
static void mod_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
Definition: numeric.c:7881
static Numeric make_result_opt_error(const NumericVar *var, bool *error)
Definition: numeric.c:6252
static void free_var(NumericVar *var)
Definition: numeric.c:5735
NumericDigit * digits
Definition: numeric.c:279
static const NumericVar const_nan
Definition: numeric.c:425
static Numeric make_result(const NumericVar *var)
Definition: numeric.c:6351
#define NUMERIC_IS_NAN(n)
Definition: numeric.c:173
#define init_var(v)
Definition: numeric.c:454

◆ numeric_mul_opt_error()

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

Definition at line 2540 of file numeric.c.

References NumericVar::dscale, free_var(), init_var, init_var_from_num(), make_result(), make_result_opt_error(), mul_var(), and NUMERIC_IS_NAN.

Referenced by executeItemOptUnwrapTarget(), and numeric_mul().

2541 {
2542  NumericVar arg1;
2543  NumericVar arg2;
2544  NumericVar result;
2545  Numeric res;
2546 
2547  /*
2548  * Handle NaN
2549  */
2550  if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2551  return make_result(&const_nan);
2552 
2553  /*
2554  * Unpack the values, let mul_var() compute the result and return it.
2555  * Unlike add_var() and sub_var(), mul_var() will round its result. In the
2556  * case of numeric_mul(), which is invoked for the * operator on numerics,
2557  * we request exact representation for the product (rscale = sum(dscale of
2558  * arg1, dscale of arg2)).
2559  */
2560  init_var_from_num(num1, &arg1);
2561  init_var_from_num(num2, &arg2);
2562 
2563  init_var(&result);
2564  mul_var(&arg1, &arg2, &result, arg1.dscale + arg2.dscale);
2565 
2566  res = make_result_opt_error(&result, have_error);
2567 
2568  free_var(&result);
2569 
2570  return res;
2571 }
int dscale
Definition: numeric.c:277
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:5968
static Numeric make_result_opt_error(const NumericVar *var, bool *error)
Definition: numeric.c:6252
static void free_var(NumericVar *var)
Definition: numeric.c:5735
static void mul_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result, int rscale)
Definition: numeric.c:7035
static const NumericVar const_nan
Definition: numeric.c:425
static Numeric make_result(const NumericVar *var)
Definition: numeric.c:6351
#define NUMERIC_IS_NAN(n)
Definition: numeric.c:173
#define init_var(v)
Definition: numeric.c:454

◆ numeric_normalize()

char* numeric_normalize ( Numeric  num)

Definition at line 760 of file numeric.c.

References get_str_from_var(), init_var_from_num(), NUMERIC_IS_NAN, pstrdup(), and generate_unaccent_rules::str.

Referenced by make_scalar_key().

761 {
762  NumericVar x;
763  char *str;
764  int last;
765 
766  /*
767  * Handle NaN
768  */
769  if (NUMERIC_IS_NAN(num))
770  return pstrdup("NaN");
771 
772  init_var_from_num(num, &x);
773 
774  str = get_str_from_var(&x);
775 
776  /* If there's no decimal point, there's certainly nothing to remove. */
777  if (strchr(str, '.') != NULL)
778  {
779  /*
780  * Back up over trailing fractional zeroes. Since there is a decimal
781  * point, this loop will terminate safely.
782  */
783  last = strlen(str) - 1;
784  while (str[last] == '0')
785  last--;
786 
787  /* We want to get rid of the decimal point too, if it's now last. */
788  if (str[last] == '.')
789  last--;
790 
791  /* Delete whatever we backed up over. */
792  str[last + 1] = '\0';
793  }
794 
795  return str;
796 }
char * pstrdup(const char *in)
Definition: mcxt.c:1161
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:5968
static char * get_str_from_var(const NumericVar *var)
Definition: numeric.c:6011
#define NUMERIC_IS_NAN(n)
Definition: numeric.c:173

◆ numeric_out_sci()

char* numeric_out_sci ( Numeric  num,
int  scale 
)

Definition at line 733 of file numeric.c.

References get_str_from_var_sci(), init_var_from_num(), NUMERIC_IS_NAN, pstrdup(), and generate_unaccent_rules::str.

Referenced by int8_to_char(), and numeric_to_char().

734 {
735  NumericVar x;
736  char *str;
737 
738  /*
739  * Handle NaN
740  */
741  if (NUMERIC_IS_NAN(num))
742  return pstrdup("NaN");
743 
744  init_var_from_num(num, &x);
745 
746  str = get_str_from_var_sci(&x, scale);
747 
748  return str;
749 }
char * pstrdup(const char *in)
Definition: mcxt.c:1161
int scale
Definition: pgbench.c:151
static char * get_str_from_var_sci(const NumericVar *var, int rscale)
Definition: numeric.c:6164
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:5968
#define NUMERIC_IS_NAN(n)
Definition: numeric.c:173

◆ numeric_sub_opt_error()

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

Definition at line 2484 of file numeric.c.

References free_var(), init_var, init_var_from_num(), make_result(), make_result_opt_error(), NUMERIC_IS_NAN, and sub_var().

Referenced by executeItemOptUnwrapTarget(), and numeric_sub().

2485 {
2486  NumericVar arg1;
2487  NumericVar arg2;
2488  NumericVar result;
2489  Numeric res;
2490 
2491  /*
2492  * Handle NaN
2493  */
2494  if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2495  return make_result(&const_nan);
2496 
2497  /*
2498  * Unpack the values, let sub_var() compute the result and return it.
2499  */
2500  init_var_from_num(num1, &arg1);
2501  init_var_from_num(num2, &arg2);
2502 
2503  init_var(&result);
2504  sub_var(&arg1, &arg2, &result);
2505 
2506  res = make_result_opt_error(&result, have_error);
2507 
2508  free_var(&result);
2509 
2510  return res;
2511 }
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:5968
static Numeric make_result_opt_error(const NumericVar *var, bool *error)
Definition: numeric.c:6252
static void free_var(NumericVar *var)
Definition: numeric.c:5735
static const NumericVar const_nan
Definition: numeric.c:425
static Numeric make_result(const NumericVar *var)
Definition: numeric.c:6351
#define NUMERIC_IS_NAN(n)
Definition: numeric.c:173
static void sub_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
Definition: numeric.c:6914
#define init_var(v)
Definition: numeric.c:454