2003-03-20 20:58:05 -05:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
|
*
|
1999-02-13 18:22:53 -05:00
|
|
|
* numeric.h
|
2003-03-20 20:58:05 -05:00
|
|
|
* Definitions for the exact numeric data type of Postgres
|
1998-12-30 14:56:35 -05:00
|
|
|
*
|
2003-03-20 20:58:05 -05:00
|
|
|
* Original coding 1998, Jan Wieck. Heavily revised 2003, Tom Lane.
|
1998-12-30 14:56:35 -05:00
|
|
|
*
|
2023-01-02 15:00:37 -05:00
|
|
|
* Copyright (c) 1998-2023, PostgreSQL Global Development Group
|
1998-12-30 14:56:35 -05:00
|
|
|
*
|
2010-09-20 16:08:53 -04:00
|
|
|
* src/include/utils/numeric.h
|
1998-12-30 14:56:35 -05:00
|
|
|
*
|
2003-03-20 20:58:05 -05:00
|
|
|
*-------------------------------------------------------------------------
|
1998-12-30 14:56:35 -05:00
|
|
|
*/
|
|
|
|
|
#ifndef _PG_NUMERIC_H_
|
|
|
|
|
#define _PG_NUMERIC_H_
|
|
|
|
|
|
2006-07-11 09:54:25 -04:00
|
|
|
#include "fmgr.h"
|
|
|
|
|
|
2002-10-02 15:21:26 -04:00
|
|
|
/*
|
Allow numeric scale to be negative or greater than precision.
Formerly, when specifying NUMERIC(precision, scale), the scale had to
be in the range [0, precision], which was per SQL spec. This commit
extends the range of allowed scales to [-1000, 1000], independent of
the precision (whose valid range remains [1, 1000]).
A negative scale implies rounding before the decimal point. For
example, a column might be declared with a scale of -3 to round values
to the nearest thousand. Note that the display scale remains
non-negative, so in this case the display scale will be zero, and all
digits before the decimal point will be displayed.
A scale greater than the precision supports fractional values with
zeros immediately after the decimal point.
Take the opportunity to tidy up the code that packs, unpacks and
validates the contents of a typmod integer, encapsulating it in a
small set of new inline functions.
Bump the catversion because the allowed contents of atttypmod have
changed for numeric columns. This isn't a change that requires a
re-initdb, but negative scale values in the typmod would confuse old
backends.
Dean Rasheed, with additional improvements by Tom Lane. Reviewed by
Tom Lane.
Discussion: https://postgr.es/m/CAEZATCWdNLgpKihmURF8nfofP0RFtAKJ7ktY6GcZOPnMfUoRqA@mail.gmail.com
2021-07-26 09:13:47 -04:00
|
|
|
* Limits on the precision and scale specifiable in a NUMERIC typmod. The
|
|
|
|
|
* precision is strictly positive, but the scale may be positive or negative.
|
|
|
|
|
* A negative scale implies rounding before the decimal point.
|
|
|
|
|
*
|
|
|
|
|
* Note that the minimum display scale defined below is zero --- we always
|
|
|
|
|
* display all digits before the decimal point, even when the scale is
|
|
|
|
|
* negative.
|
|
|
|
|
*
|
|
|
|
|
* Note that the implementation limits on the precision and display scale of a
|
|
|
|
|
* numeric value are much larger --- beware of what you use these for!
|
1998-12-30 14:56:35 -05:00
|
|
|
*/
|
1999-01-05 06:12:11 -05:00
|
|
|
#define NUMERIC_MAX_PRECISION 1000
|
1998-12-30 14:56:35 -05:00
|
|
|
|
Allow numeric scale to be negative or greater than precision.
Formerly, when specifying NUMERIC(precision, scale), the scale had to
be in the range [0, precision], which was per SQL spec. This commit
extends the range of allowed scales to [-1000, 1000], independent of
the precision (whose valid range remains [1, 1000]).
A negative scale implies rounding before the decimal point. For
example, a column might be declared with a scale of -3 to round values
to the nearest thousand. Note that the display scale remains
non-negative, so in this case the display scale will be zero, and all
digits before the decimal point will be displayed.
A scale greater than the precision supports fractional values with
zeros immediately after the decimal point.
Take the opportunity to tidy up the code that packs, unpacks and
validates the contents of a typmod integer, encapsulating it in a
small set of new inline functions.
Bump the catversion because the allowed contents of atttypmod have
changed for numeric columns. This isn't a change that requires a
re-initdb, but negative scale values in the typmod would confuse old
backends.
Dean Rasheed, with additional improvements by Tom Lane. Reviewed by
Tom Lane.
Discussion: https://postgr.es/m/CAEZATCWdNLgpKihmURF8nfofP0RFtAKJ7ktY6GcZOPnMfUoRqA@mail.gmail.com
2021-07-26 09:13:47 -04:00
|
|
|
#define NUMERIC_MIN_SCALE (-1000)
|
|
|
|
|
#define NUMERIC_MAX_SCALE 1000
|
|
|
|
|
|
2002-10-02 15:21:26 -04:00
|
|
|
/*
|
2000-01-15 18:42:49 -05:00
|
|
|
* Internal limits on the scales chosen for calculation results
|
|
|
|
|
*/
|
1998-12-30 14:56:35 -05:00
|
|
|
#define NUMERIC_MAX_DISPLAY_SCALE NUMERIC_MAX_PRECISION
|
2002-10-02 15:21:26 -04:00
|
|
|
#define NUMERIC_MIN_DISPLAY_SCALE 0
|
1998-12-30 14:56:35 -05:00
|
|
|
|
1998-12-30 15:46:06 -05:00
|
|
|
#define NUMERIC_MAX_RESULT_SCALE (NUMERIC_MAX_PRECISION * 2)
|
1998-12-30 14:56:35 -05:00
|
|
|
|
2002-10-02 15:21:26 -04:00
|
|
|
/*
|
|
|
|
|
* For inherently inexact calculations such as division and square root,
|
|
|
|
|
* we try to get at least this many significant digits; the idea is to
|
|
|
|
|
* deliver a result no worse than float8 would.
|
|
|
|
|
*/
|
|
|
|
|
#define NUMERIC_MIN_SIG_DIGITS 16
|
1998-12-30 14:56:35 -05:00
|
|
|
|
2010-07-30 00:30:23 -04:00
|
|
|
/* The actual contents of Numeric are private to numeric.c */
|
|
|
|
|
struct NumericData;
|
|
|
|
|
typedef struct NumericData *Numeric;
|
1998-12-30 14:56:35 -05:00
|
|
|
|
2000-06-13 03:35:40 -04:00
|
|
|
/*
|
|
|
|
|
* fmgr interface macros
|
|
|
|
|
*/
|
|
|
|
|
|
2022-09-27 14:47:07 -04:00
|
|
|
static inline Numeric
|
|
|
|
|
DatumGetNumeric(Datum X)
|
|
|
|
|
{
|
|
|
|
|
return (Numeric) PG_DETOAST_DATUM(X);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline Numeric
|
|
|
|
|
DatumGetNumericCopy(Datum X)
|
|
|
|
|
{
|
|
|
|
|
return (Numeric) PG_DETOAST_DATUM_COPY(X);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline Datum
|
|
|
|
|
NumericGetDatum(Numeric X)
|
|
|
|
|
{
|
|
|
|
|
return PointerGetDatum(X);
|
|
|
|
|
}
|
|
|
|
|
|
2000-07-16 23:05:41 -04:00
|
|
|
#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)
|
2001-10-28 01:26:15 -05:00
|
|
|
|
2009-08-10 14:29:27 -04:00
|
|
|
/*
|
|
|
|
|
* Utility functions in numeric.c
|
|
|
|
|
*/
|
2010-07-30 00:30:23 -04:00
|
|
|
extern bool numeric_is_nan(Numeric num);
|
2020-07-22 19:19:44 -04:00
|
|
|
extern bool numeric_is_inf(Numeric num);
|
2022-05-12 12:17:14 -04:00
|
|
|
extern int32 numeric_maximum_size(int32 typmod);
|
2009-08-10 14:29:27 -04:00
|
|
|
extern char *numeric_out_sci(Numeric num, int scale);
|
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 16:40:19 -04:00
|
|
|
extern char *numeric_normalize(Numeric num);
|
2009-08-10 14:29:27 -04:00
|
|
|
|
2020-09-09 14:16:28 -04:00
|
|
|
extern Numeric int64_to_numeric(int64 val);
|
Change return type of EXTRACT to numeric
The previous implementation of EXTRACT mapped internally to
date_part(), which returned type double precision (since it was
implemented long before the numeric type existed). This can lead to
imprecise output in some cases, so returning numeric would be
preferrable. Changing the return type of an existing function is a
bit risky, so instead we do the following: We implement a new set of
functions, which are now called "extract", in parallel to the existing
date_part functions. They work the same way internally but use
numeric instead of float8. The EXTRACT construct is now mapped by the
parser to these new extract functions. That way, dumps of views
etc. from old versions (which would use date_part) continue to work
unchanged, but new uses will map to the new extract functions.
Additionally, the reverse compilation of EXTRACT now reproduces the
original syntax, using the new mechanism introduced in
40c24bfef92530bd846e111c1742c2a54441c62c.
The following minor changes of behavior result from the new
implementation:
- The column name from an isolated EXTRACT call is now "extract"
instead of "date_part".
- Extract from date now rejects inappropriate field names such as
HOUR. It was previously mapped internally to extract from
timestamp, so it would silently accept everything appropriate for
timestamp.
- Return values when extracting fields with possibly fractional
values, such as second and epoch, now have the full scale that the
value has internally (so, for example, '1.000000' instead of just
'1').
Reported-by: Petr Fedorov <petr.fedorov@phystech.edu>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://www.postgresql.org/message-id/flat/42b73d2d-da12-ba9f-570a-420e0cce19d9@phystech.edu
2021-04-06 01:17:13 -04:00
|
|
|
extern Numeric int64_div_fast_to_numeric(int64 val1, int log10val2);
|
2020-09-09 14:16:28 -04:00
|
|
|
|
2019-03-16 05:21:19 -04:00
|
|
|
extern Numeric numeric_add_opt_error(Numeric num1, Numeric num2,
|
|
|
|
|
bool *have_error);
|
|
|
|
|
extern Numeric numeric_sub_opt_error(Numeric num1, Numeric num2,
|
|
|
|
|
bool *have_error);
|
|
|
|
|
extern Numeric numeric_mul_opt_error(Numeric num1, Numeric num2,
|
|
|
|
|
bool *have_error);
|
|
|
|
|
extern Numeric numeric_div_opt_error(Numeric num1, Numeric num2,
|
|
|
|
|
bool *have_error);
|
|
|
|
|
extern Numeric numeric_mod_opt_error(Numeric num1, Numeric num2,
|
|
|
|
|
bool *have_error);
|
2022-09-20 16:09:30 -04:00
|
|
|
extern int32 numeric_int4_opt_error(Numeric num, bool *have_error);
|
2019-03-16 05:21:19 -04:00
|
|
|
|
1998-12-30 14:56:35 -05:00
|
|
|
#endif /* _PG_NUMERIC_H_ */
|