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

2431 {
2432  NumericVar arg1;
2433  NumericVar arg2;
2434  NumericVar result;
2435  Numeric res;
2436 
2437  /*
2438  * Handle NaN
2439  */
2440  if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2441  return make_result(&const_nan);
2442 
2443  /*
2444  * Unpack the values, let add_var() compute the result and return it.
2445  */
2446  init_var_from_num(num1, &arg1);
2447  init_var_from_num(num2, &arg2);
2448 
2449  init_var(&result);
2450  add_var(&arg1, &arg2, &result);
2451 
2452  res = make_result_opt_error(&result, have_error);
2453 
2454  free_var(&result);
2455 
2456  return res;
2457 }
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:6162
static Numeric make_result_opt_error(const NumericVar *var, bool *error)
Definition: numeric.c:6446
static void free_var(NumericVar *var)
Definition: numeric.c:5929
static void add_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
Definition: numeric.c:6991
static const NumericVar const_nan
Definition: numeric.c:425
static Numeric make_result(const NumericVar *var)
Definition: numeric.c:6545
#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 2602 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().

2603 {
2604  NumericVar arg1;
2605  NumericVar arg2;
2606  NumericVar result;
2607  Numeric res;
2608  int rscale;
2609 
2610  if (have_error)
2611  *have_error = false;
2612 
2613  /*
2614  * Handle NaN
2615  */
2616  if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2617  return make_result(&const_nan);
2618 
2619  /*
2620  * Unpack the arguments
2621  */
2622  init_var_from_num(num1, &arg1);
2623  init_var_from_num(num2, &arg2);
2624 
2625  init_var(&result);
2626 
2627  /*
2628  * Select scale for division result
2629  */
2630  rscale = select_div_scale(&arg1, &arg2);
2631 
2632  /*
2633  * If "have_error" is provided, check for division by zero here
2634  */
2635  if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
2636  {
2637  *have_error = true;
2638  return NULL;
2639  }
2640 
2641  /*
2642  * Do the divide and return the result
2643  */
2644  div_var(&arg1, &arg2, &result, rscale, true);
2645 
2646  res = make_result_opt_error(&result, have_error);
2647 
2648  free_var(&result);
2649 
2650  return res;
2651 }
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:7426
static int select_div_scale(const NumericVar *var1, const NumericVar *var2)
Definition: numeric.c:8006
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:6162
static Numeric make_result_opt_error(const NumericVar *var, bool *error)
Definition: numeric.c:6446
static void free_var(NumericVar *var)
Definition: numeric.c:5929
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:6545
#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 3405 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().

3406 {
3407  NumericVar x;
3408  int32 result;
3409 
3410  if (have_error)
3411  *have_error = false;
3412 
3413  /* XXX would it be better to return NULL? */
3414  if (NUMERIC_IS_NAN(num))
3415  {
3416  if (have_error)
3417  {
3418  *have_error = true;
3419  return 0;
3420  }
3421  else
3422  {
3423  ereport(ERROR,
3424  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3425  errmsg("cannot convert NaN to integer")));
3426  }
3427  }
3428 
3429  /* Convert to variable format, then convert to int4 */
3430  init_var_from_num(num, &x);
3431 
3432  if (!numericvar_to_int32(&x, &result))
3433  {
3434  if (have_error)
3435  {
3436  *have_error = true;
3437  return 0;
3438  }
3439  else
3440  {
3441  ereport(ERROR,
3442  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
3443  errmsg("integer out of range")));
3444  }
3445  }
3446 
3447  return result;
3448 }
int errcode(int sqlerrcode)
Definition: elog.c:608
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:6162
#define ereport(elevel, rest)
Definition: elog.h:141
static bool numericvar_to_int32(const NumericVar *var, int32 *result)
Definition: numeric.c:3464
int errmsg(const char *fmt,...)
Definition: elog.c:822
#define NUMERIC_IS_NAN(n)
Definition: numeric.c:173

◆ numeric_is_nan()

bool numeric_is_nan ( Numeric  num)

Definition at line 685 of file numeric.c.

References NUMERIC_IS_NAN.

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

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

◆ numeric_maximum_size()

int32 numeric_maximum_size ( int32  typmod)

Definition at line 696 of file numeric.c.

References DEC_DIGITS, NUMERIC_HDRSZ, and VARHDRSZ.

Referenced by type_maximum_size().

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

2723 {
2724  Numeric res;
2725  NumericVar arg1;
2726  NumericVar arg2;
2727  NumericVar result;
2728 
2729  if (have_error)
2730  *have_error = false;
2731 
2732  if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2733  return make_result(&const_nan);
2734 
2735  init_var_from_num(num1, &arg1);
2736  init_var_from_num(num2, &arg2);
2737 
2738  init_var(&result);
2739 
2740  /*
2741  * If "have_error" is provided, check for division by zero here
2742  */
2743  if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
2744  {
2745  *have_error = true;
2746  return NULL;
2747  }
2748 
2749  mod_var(&arg1, &arg2, &result);
2750 
2751  res = make_result_opt_error(&result, NULL);
2752 
2753  free_var(&result);
2754 
2755  return res;
2756 }
int ndigits
Definition: numeric.c:274
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:6162
static void mod_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
Definition: numeric.c:8075
static Numeric make_result_opt_error(const NumericVar *var, bool *error)
Definition: numeric.c:6446
static void free_var(NumericVar *var)
Definition: numeric.c:5929
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:6545
#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 2542 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().

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

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

◆ numeric_out_sci()

char* numeric_out_sci ( Numeric  num,
int  scale 
)

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

736 {
737  NumericVar x;
738  char *str;
739 
740  /*
741  * Handle NaN
742  */
743  if (NUMERIC_IS_NAN(num))
744  return pstrdup("NaN");
745 
746  init_var_from_num(num, &x);
747 
748  str = get_str_from_var_sci(&x, scale);
749 
750  return str;
751 }
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:6358
static void init_var_from_num(Numeric num, NumericVar *dest)
Definition: numeric.c:6162
#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 2486 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().

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