Commit d72f6c75 authored by Tom Lane's avatar Tom Lane

Reimplement NUMERIC datatype using base-10000 arithmetic; also improve

some of the algorithms for higher functions.  I see about a factor of ten
speedup on the 'numeric' regression test, but it's unlikely that that test
is representative of real-world applications.
initdb forced due to change of on-disk representation for NUMERIC.
parent 5ae42452
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.185 2003/02/05 17:41:32 tgl Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.186 2003/03/21 01:58:04 tgl Exp $
--> -->
<appendix id="release"> <appendix id="release">
...@@ -24,6 +24,7 @@ CDATA means the content is "SGML-free", so you can write without ...@@ -24,6 +24,7 @@ CDATA means the content is "SGML-free", so you can write without
worries about funny characters. worries about funny characters.
--> -->
<literallayout><![CDATA[ <literallayout><![CDATA[
Reimplementation of NUMERIC datatype for more speed
New regular expression package, many more regexp features (most of Perl5) New regular expression package, many more regexp features (most of Perl5)
Can now do EXPLAIN ... EXECUTE to see plan used for a prepared query Can now do EXPLAIN ... EXECUTE to see plan used for a prepared query
Explicit JOINs no longer constrain query plan, unless JOIN_COLLAPSE_LIMIT = 1 Explicit JOINs no longer constrain query plan, unless JOIN_COLLAPSE_LIMIT = 1
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: catversion.h,v 1.181 2003/03/20 03:34:56 momjian Exp $ * $Id: catversion.h,v 1.182 2003/03/21 01:58:04 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -53,6 +53,6 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200303191 #define CATALOG_VERSION_NO 200303201
#endif #endif
/* ---------- /*-------------------------------------------------------------------------
*
* numeric.h * numeric.h
* Definitions for the exact numeric data type of Postgres
* *
* Definitions for the exact numeric data type of Postgres * Original coding 1998, Jan Wieck. Heavily revised 2003, Tom Lane.
* *
* 1998 Jan Wieck * Copyright (c) 1998-2003, PostgreSQL Global Development Group
* *
* $Id: numeric.h,v 1.16 2002/10/02 19:21:26 tgl Exp $ * $Id: numeric.h,v 1.17 2003/03/21 01:58:05 tgl Exp $
* *
* ---------- *-------------------------------------------------------------------------
*/ */
#ifndef _PG_NUMERIC_H_ #ifndef _PG_NUMERIC_H_
#define _PG_NUMERIC_H_ #define _PG_NUMERIC_H_
...@@ -34,12 +35,6 @@ ...@@ -34,12 +35,6 @@
*/ */
#define NUMERIC_MIN_SIG_DIGITS 16 #define NUMERIC_MIN_SIG_DIGITS 16
/*
* Standard number of extra digits carried internally while doing
* inexact calculations.
*/
#define NUMERIC_EXTRA_DIGITS 4
/* /*
* Sign values and macros to deal with packing/unpacking n_sign_dscale * Sign values and macros to deal with packing/unpacking n_sign_dscale
...@@ -51,30 +46,29 @@ ...@@ -51,30 +46,29 @@
#define NUMERIC_DSCALE_MASK 0x3FFF #define NUMERIC_DSCALE_MASK 0x3FFF
#define NUMERIC_SIGN(n) ((n)->n_sign_dscale & NUMERIC_SIGN_MASK) #define NUMERIC_SIGN(n) ((n)->n_sign_dscale & NUMERIC_SIGN_MASK)
#define NUMERIC_DSCALE(n) ((n)->n_sign_dscale & NUMERIC_DSCALE_MASK) #define NUMERIC_DSCALE(n) ((n)->n_sign_dscale & NUMERIC_DSCALE_MASK)
#define NUMERIC_IS_NAN(n) (NUMERIC_SIGN(n) != NUMERIC_POS && \ #define NUMERIC_IS_NAN(n) (NUMERIC_SIGN(n) != NUMERIC_POS && \
NUMERIC_SIGN(n) != NUMERIC_NEG) NUMERIC_SIGN(n) != NUMERIC_NEG)
/* /*
* The Numeric data type stored in the database * The Numeric data type stored in the database
* *
* NOTE: by convention, values in the packed form have been stripped of * NOTE: by convention, values in the packed form have been stripped of
* all leading and trailing zeroes (except there will be a trailing zero * all leading and trailing zero digits (where a "digit" is of base NBASE).
* in the last byte, if the number of digits is odd). In particular, * In particular, if the value is zero, there will be no digits at all!
* if the value is zero, there will be no digits at all! The weight is * The weight is arbitrary in that case, but we normally set it to zero.
* arbitrary in that case, but we normally set it to zero.
*/ */
typedef struct NumericData typedef struct NumericData
{ {
int32 varlen; /* Variable size */ int32 varlen; /* Variable size (std varlena header) */
int16 n_weight; /* Weight of 1st digit */ int16 n_weight; /* Weight of 1st digit */
uint16 n_rscale; /* Result scale */
uint16 n_sign_dscale; /* Sign + display scale */ uint16 n_sign_dscale; /* Sign + display scale */
unsigned char n_data[1]; /* Digit data (2 decimal digits/byte) */ char n_data[1]; /* Digits (really array of NumericDigit) */
} NumericData; } NumericData;
typedef NumericData *Numeric; typedef NumericData *Numeric;
#define NUMERIC_HDRSZ (sizeof(int32) + sizeof(uint16) * 3) #define NUMERIC_HDRSZ (sizeof(int32) + sizeof(int16) + sizeof(uint16))
/* /*
......
...@@ -2,15 +2,15 @@ ...@@ -2,15 +2,15 @@
-- AGGREGATES -- AGGREGATES
-- --
SELECT avg(four) AS avg_1 FROM onek; SELECT avg(four) AS avg_1 FROM onek;
avg_1 avg_1
--------------------- --------------------
1.50000000000000000 1.5000000000000000
(1 row) (1 row)
SELECT avg(a) AS avg_32 FROM aggtest WHERE a < 100; SELECT avg(a) AS avg_32 FROM aggtest WHERE a < 100;
avg_32 avg_32
-------------------- ---------------------
32.666666666666667 32.6666666666666667
(1 row) (1 row)
-- In 7.1, avg(float4) is computed using float8 arithmetic. -- In 7.1, avg(float4) is computed using float8 arithmetic.
...@@ -120,9 +120,9 @@ group by ten order by ten; ...@@ -120,9 +120,9 @@ group by ten order by ten;
(10 rows) (10 rows)
SELECT newavg(four) AS avg_1 FROM onek; SELECT newavg(four) AS avg_1 FROM onek;
avg_1 avg_1
--------------------- --------------------
1.50000000000000000 1.5000000000000000
(1 row) (1 row)
SELECT newsum(four) AS sum_1500 FROM onek; SELECT newsum(four) AS sum_1500 FROM onek;
......
...@@ -665,9 +665,9 @@ SELECT t1.id1, t1.result, t2.expected ...@@ -665,9 +665,9 @@ SELECT t1.id1, t1.result, t2.expected
-- ****************************** -- ******************************
-- numeric AVG used to fail on some platforms -- numeric AVG used to fail on some platforms
SELECT AVG(val) FROM num_data; SELECT AVG(val) FROM num_data;
avg avg
---------------------- ------------------------
-13430913.5922423207 -13430913.592242320700
(1 row) (1 row)
-- Check for appropriate rounding and overflow -- Check for appropriate rounding and overflow
......
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