Commit 8a4dc94c authored by Robert Haas's avatar Robert Haas

Make details of the Numeric representation private to numeric.c.

Review by Tom Lane.
parent f223bb7a
/* /*
* $PostgreSQL: pgsql/contrib/btree_gist/btree_numeric.c,v 1.13 2009/06/11 14:48:50 momjian Exp $ * $PostgreSQL: pgsql/contrib/btree_gist/btree_numeric.c,v 1.14 2010/07/30 04:30:23 rhaas Exp $
*/ */
#include "btree_gist.h" #include "btree_gist.h"
...@@ -185,9 +185,9 @@ gbt_numeric_penalty(PG_FUNCTION_ARGS) ...@@ -185,9 +185,9 @@ gbt_numeric_penalty(PG_FUNCTION_ARGS)
NumericGetDatum(os) NumericGetDatum(os)
)); ));
if (NUMERIC_IS_NAN(us)) if (numeric_is_nan(us))
{ {
if (NUMERIC_IS_NAN(os)) if (numeric_is_nan(os))
*result = 0.0; *result = 0.0;
else else
*result = 1.0; *result = 1.0;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/format_type.c,v 1.53 2010/02/14 18:42:16 rhaas Exp $ * $PostgreSQL: pgsql/src/backend/utils/adt/format_type.c,v 1.54 2010/07/30 04:30:23 rhaas Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -387,15 +387,7 @@ type_maximum_size(Oid type_oid, int32 typemod) ...@@ -387,15 +387,7 @@ type_maximum_size(Oid type_oid, int32 typemod)
+ VARHDRSZ; + VARHDRSZ;
case NUMERICOID: case NUMERICOID:
/* precision (ie, max # of digits) is in upper bits of typmod */ return numeric_maximum_size(typemod);
if (typemod > VARHDRSZ)
{
int precision = ((typemod - VARHDRSZ) >> 16) & 0xffff;
/* Numeric stores 2 decimal digits/byte, plus header */
return (precision + 1) / 2 + NUMERIC_HDRSZ;
}
break;
case VARBITOID: case VARBITOID:
case BITOID: case BITOID:
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* Copyright (c) 1998-2010, PostgreSQL Global Development Group * Copyright (c) 1998-2010, PostgreSQL Global Development Group
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.123 2010/02/26 02:01:09 momjian Exp $ * $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.124 2010/07/30 04:30:23 rhaas Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -35,6 +35,38 @@ ...@@ -35,6 +35,38 @@
#include "utils/int8.h" #include "utils/int8.h"
#include "utils/numeric.h" #include "utils/numeric.h"
/*
* Sign values and macros to deal with packing/unpacking n_sign_dscale
*/
#define NUMERIC_SIGN_MASK 0xC000
#define NUMERIC_POS 0x0000
#define NUMERIC_NEG 0x4000
#define NUMERIC_NAN 0xC000
#define NUMERIC_DSCALE_MASK 0x3FFF
#define NUMERIC_SIGN(n) ((n)->n_sign_dscale & NUMERIC_SIGN_MASK)
#define NUMERIC_DSCALE(n) ((n)->n_sign_dscale & NUMERIC_DSCALE_MASK)
#define NUMERIC_IS_NAN(n) (NUMERIC_SIGN(n) != NUMERIC_POS && \
NUMERIC_SIGN(n) != NUMERIC_NEG)
#define NUMERIC_HDRSZ (VARHDRSZ + sizeof(uint16) + sizeof(int16))
/*
* The Numeric data type stored in the database
*
* NOTE: by convention, values in the packed form have been stripped of
* all leading and trailing zero digits (where a "digit" is of base NBASE).
* In particular, if the value is zero, there will be no digits at all!
* The weight is arbitrary in that case, but we normally set it to zero.
*/
struct NumericData
{
int32 vl_len_; /* varlena header (do not touch directly!) */
uint16 n_sign_dscale; /* Sign + display scale */
int16 n_weight; /* Weight of 1st digit */
char n_data[1]; /* Digits (really array of NumericDigit) */
};
/* ---------- /* ----------
* Uncomment the following to enable compilation of dump_numeric() * Uncomment the following to enable compilation of dump_numeric()
* and dump_var() and to get a dump of any result produced by make_result(). * and dump_var() and to get a dump of any result produced by make_result().
...@@ -427,6 +459,37 @@ numeric_out(PG_FUNCTION_ARGS) ...@@ -427,6 +459,37 @@ numeric_out(PG_FUNCTION_ARGS)
PG_RETURN_CSTRING(str); PG_RETURN_CSTRING(str);
} }
/*
* numeric_is_nan() -
*
* Is Numeric value a NaN?
*/
bool
numeric_is_nan(Numeric num)
{
return NUMERIC_IS_NAN(num);
}
/*
* numeric_maximum_size() -
*
* Maximum size of a numeric with given typmod, or -1 if unlimited/unknown.
*/
int32
numeric_maximum_size(int32 typemod)
{
int precision;
if (typemod <= VARHDRSZ)
return -1;
/* precision (ie, max # of digits) is in upper bits of typmod */
precision = ((typemod - VARHDRSZ) >> 16) & 0xffff;
/* Numeric stores 2 decimal digits/byte, plus header */
return (precision + 1) / 2 + NUMERIC_HDRSZ;
}
/* /*
* numeric_out_sci() - * numeric_out_sci() -
* *
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* Copyright (c) 1998-2010, PostgreSQL Global Development Group * Copyright (c) 1998-2010, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/include/utils/numeric.h,v 1.29 2010/01/02 16:58:10 momjian Exp $ * $PostgreSQL: pgsql/src/include/utils/numeric.h,v 1.30 2010/07/30 04:30:23 rhaas Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -37,41 +37,9 @@ ...@@ -37,41 +37,9 @@
*/ */
#define NUMERIC_MIN_SIG_DIGITS 16 #define NUMERIC_MIN_SIG_DIGITS 16
/* The actual contents of Numeric are private to numeric.c */
/* struct NumericData;
* Sign values and macros to deal with packing/unpacking n_sign_dscale typedef struct NumericData *Numeric;
*/
#define NUMERIC_SIGN_MASK 0xC000
#define NUMERIC_POS 0x0000
#define NUMERIC_NEG 0x4000
#define NUMERIC_NAN 0xC000
#define NUMERIC_DSCALE_MASK 0x3FFF
#define NUMERIC_SIGN(n) ((n)->n_sign_dscale & NUMERIC_SIGN_MASK)
#define NUMERIC_DSCALE(n) ((n)->n_sign_dscale & NUMERIC_DSCALE_MASK)
#define NUMERIC_IS_NAN(n) (NUMERIC_SIGN(n) != NUMERIC_POS && \
NUMERIC_SIGN(n) != NUMERIC_NEG)
/*
* The Numeric data type stored in the database
*
* NOTE: by convention, values in the packed form have been stripped of
* all leading and trailing zero digits (where a "digit" is of base NBASE).
* In particular, if the value is zero, there will be no digits at all!
* The weight is arbitrary in that case, but we normally set it to zero.
*/
typedef struct NumericData
{
int32 vl_len_; /* varlena header (do not touch directly!) */
uint16 n_sign_dscale; /* Sign + display scale */
int16 n_weight; /* Weight of 1st digit */
char n_data[1]; /* Digits (really array of NumericDigit) */
} NumericData;
typedef NumericData *Numeric;
#define NUMERIC_HDRSZ (VARHDRSZ + sizeof(uint16) + sizeof(int16))
/* /*
* fmgr interface macros * fmgr interface macros
...@@ -87,6 +55,8 @@ typedef NumericData *Numeric; ...@@ -87,6 +55,8 @@ typedef NumericData *Numeric;
/* /*
* Utility functions in numeric.c * Utility functions in numeric.c
*/ */
extern bool numeric_is_nan(Numeric num);
int32 numeric_maximum_size(int32 typemod);
extern char *numeric_out_sci(Numeric num, int scale); extern char *numeric_out_sci(Numeric num, int scale);
#endif /* _PG_NUMERIC_H_ */ #endif /* _PG_NUMERIC_H_ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment