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 2422 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().

2423 {
2424  NumericVar arg1;
2425  NumericVar arg2;
2426  NumericVar result;
2427  Numeric res;
2428 
2429  /*
2430  * Handle NaN
2431  */
2432  if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2433  return make_result(&const_nan);
2434 
2435  /*
2436  * Unpack the values, let add_var() compute the result and return it.
2437  */
2438  init_var_from_num(num1, &arg1);
2439  init_var_from_num(num2, &arg2);
2440 
2441  init_var(&result);
2442  add_var(&arg1, &arg2, &result);
2443 
2444  res = make_result_opt_error(&result, have_error);
2445 
2446  free_var(&result);
2447 
2448  return res;
2449 }
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:6154
static Numeric make_result_opt_error(const NumericVar *var, bool *error)
Definition: numeric.c:6438
static void free_var(NumericVar *var)
Definition: numeric.c:5921
static void add_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
Definition: numeric.c:6983
static const NumericVar const_nan
Definition: numeric.c:415
static Numeric make_result(const NumericVar *var)
Definition: numeric.c:6537
#define NUMERIC_IS_NAN(n)
Definition: numeric.c:173
#define init_var(v)
Definition: numeric.c:444

◆ numeric_div_opt_error()

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

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

2595 {
2596  NumericVar arg1;
2597  NumericVar arg2;
2598  NumericVar result;
2599  Numeric res;
2600  int rscale;
2601 
2602  if (have_error)
2603  *have_error = false;
2604 
2605  /*
2606  * Handle NaN
2607  */
2608  if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2609  return make_result(&const_nan);
2610 
2611  /*
2612  * Unpack the arguments
2613  */
2614  init_var_from_num(num1, &arg1);
2615  init_var_from_num(num2, &arg2);
2616 
2617  init_var(&result);
2618 
2619  /*
2620  * Select scale for division result
2621  */
2622  rscale = select_div_scale(&arg1, &arg2);
2623 
2624  /*
2625  * If "have_error" is provided, check for division by zero here
2626  */
2627  if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
2628  {
2629  *have_error = true;
2630  return NULL;
2631  }
2632 
2633  /*
2634  * Do the divide and return the result
2635  */
2636  div_var(&arg1, &arg2, &result, rscale, true);
2637 
2638  res = make_result_opt_error(&result, have_error);
2639 
2640  free_var(&result);
2641 
2642  return res;
2643 }
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:7418
static int select_div_scale(const NumericVar *var1, const NumericVar *var2)
Definition: numeric.c:8009
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:6154
static Numeric make_result_opt_error(const NumericVar *var, bool *error)
Definition: numeric.c:6438
static void free_var(NumericVar *var)
Definition: numeric.c:5921
NumericDigit * digits
Definition: numeric.c:279
static const NumericVar const_nan
Definition: numeric.c:415
static Numeric make_result(const NumericVar *var)
Definition: numeric.c:6537
#define NUMERIC_IS_NAN(n)
Definition: numeric.c:173
#define init_var(v)
Definition: numeric.c:444

◆ numeric_int4_opt_error()

int32 numeric_int4_opt_error ( Numeric  num,
bool error 
)

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

3398 {
3399  NumericVar x;
3400  int32 result;
3401 
3402  if (have_error)
3403  *have_error = false;
3404 
3405  /* XXX would it be better to return NULL? */
3406  if (NUMERIC_IS_NAN(num))
3407  {
3408  if (have_error)
3409  {
3410  *have_error = true;
3411  return 0;
3412  }
3413  else
3414  {
3415  ereport(ERROR,
3416  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3417  errmsg("cannot convert NaN to integer")));
3418  }
3419  }
3420 
3421  /* Convert to variable format, then convert to int4 */
3422  init_var_from_num(num, &x);
3423 
3424  if (!numericvar_to_int32(&x, &result))
3425  {
3426  if (have_error)
3427  {
3428  *have_error = true;
3429  return 0;
3430  }
3431  else
3432  {
3433  ereport(ERROR,
3434  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
3435  errmsg("integer out of range")));
3436  }
3437  }
3438 
3439  return result;
3440 }
int errcode(int sqlerrcode)
Definition: elog.c:610
signed int int32
Definition: c.h:355
#define ERROR
Definition: elog.h:43
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:6154
static bool numericvar_to_int32(const NumericVar *var, int32 *result)
Definition: numeric.c:3456
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define NUMERIC_IS_NAN(n)
Definition: numeric.c:173

◆ numeric_is_nan()

bool numeric_is_nan ( Numeric  num)

Definition at line 677 of file numeric.c.

References NUMERIC_IS_NAN.

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

678 {
679  return NUMERIC_IS_NAN(num);
680 }
#define NUMERIC_IS_NAN(n)
Definition: numeric.c:173

◆ numeric_maximum_size()

int32 numeric_maximum_size ( int32  typmod)

Definition at line 688 of file numeric.c.

References DEC_DIGITS, NUMERIC_HDRSZ, and VARHDRSZ.

Referenced by type_maximum_size().

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

2715 {
2716  Numeric res;
2717  NumericVar arg1;
2718  NumericVar arg2;
2719  NumericVar result;
2720 
2721  if (have_error)
2722  *have_error = false;
2723 
2724  if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2725  return make_result(&const_nan);
2726 
2727  init_var_from_num(num1, &arg1);
2728  init_var_from_num(num2, &arg2);
2729 
2730  init_var(&result);
2731 
2732  /*
2733  * If "have_error" is provided, check for division by zero here
2734  */
2735  if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
2736  {
2737  *have_error = true;
2738  return NULL;
2739  }
2740 
2741  mod_var(&arg1, &arg2, &result);
2742 
2743  res = make_result_opt_error(&result, NULL);
2744 
2745  free_var(&result);
2746 
2747  return res;
2748 }
int ndigits
Definition: numeric.c:274
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:6154
static void mod_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
Definition: numeric.c:8078
static Numeric make_result_opt_error(const NumericVar *var, bool *error)
Definition: numeric.c:6438
static void free_var(NumericVar *var)
Definition: numeric.c:5921
NumericDigit * digits
Definition: numeric.c:279
static const NumericVar const_nan
Definition: numeric.c:415
static Numeric make_result(const NumericVar *var)
Definition: numeric.c:6537
#define NUMERIC_IS_NAN(n)
Definition: numeric.c:173
#define init_var(v)
Definition: numeric.c:444

◆ numeric_mul_opt_error()

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

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

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

◆ numeric_normalize()

char* numeric_normalize ( Numeric  num)

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

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

◆ numeric_out_sci()

char* numeric_out_sci ( Numeric  num,
int  scale 
)

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

728 {
729  NumericVar x;
730  char *str;
731 
732  /*
733  * Handle NaN
734  */
735  if (NUMERIC_IS_NAN(num))
736  return pstrdup("NaN");
737 
738  init_var_from_num(num, &x);
739 
740  str = get_str_from_var_sci(&x, scale);
741 
742  return str;
743 }
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:6350
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:6154
#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 2478 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().

2479 {
2480  NumericVar arg1;
2481  NumericVar arg2;
2482  NumericVar result;
2483  Numeric res;
2484 
2485  /*
2486  * Handle NaN
2487  */
2488  if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2489  return make_result(&const_nan);
2490 
2491  /*
2492  * Unpack the values, let sub_var() compute the result and return it.
2493  */
2494  init_var_from_num(num1, &arg1);
2495  init_var_from_num(num2, &arg2);
2496 
2497  init_var(&result);
2498  sub_var(&arg1, &arg2, &result);
2499 
2500  res = make_result_opt_error(&result, have_error);
2501 
2502  free_var(&result);
2503 
2504  return res;
2505 }
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:6154
static Numeric make_result_opt_error(const NumericVar *var, bool *error)
Definition: numeric.c:6438
static void free_var(NumericVar *var)
Definition: numeric.c:5921
static const NumericVar const_nan
Definition: numeric.c:415
static Numeric make_result(const NumericVar *var)
Definition: numeric.c:6537
#define NUMERIC_IS_NAN(n)
Definition: numeric.c:173
static void sub_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
Definition: numeric.c:7100
#define init_var(v)
Definition: numeric.c:444