Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
f6ecfba
Initial workings of a fixeddecimal type
david-rowley Aug 31, 2015
4beaa0a
Remove the deadly temp-instance=.
david-rowley Aug 31, 2015
1c78f9d
Add missing overflow.sql
david-rowley Aug 31, 2015
fcfbf30
Fixed regression test expected results
david-rowley Aug 31, 2015
9763af3
Add regression test for comparision operators
david-rowley Aug 31, 2015
a871ebb
Add regression tests for casts
david-rowley Aug 31, 2015
3757de0
Add aggregate regression test and fix problem with EOLs
david-rowley Aug 31, 2015
363f3be
Fix more problems with windows EOLs
david-rowley Aug 31, 2015
c7a0431
Change multiply and divide to use int128 as an intermediate number
david-rowley Sep 4, 2015
678049e
Add casts to and from numeric
david-rowley Sep 4, 2015
93dd2e4
Add README file
david-rowley Sep 10, 2015
23df8d2
Various changes to fixeddecimal
david-rowley Sep 16, 2015
686d8d5
Add fastpath for fixeddecimal to fixeddecimal cast
david-rowley Sep 16, 2015
e9f9e01
Add support for BRIN indexes
david-rowley Sep 17, 2015
33e8cb7
Improve README file and format as .md
david-rowley Sep 17, 2015
6e60e25
Fix .md formatting for examples
david-rowley Sep 17, 2015
12d87dd
Fix various spelling mistakes in README.md
david-rowley Sep 17, 2015
f4cb852
Allow fixed decimal to work in earlier postgres versions
david-rowley Sep 19, 2015
3ef9f06
Add installation nodes to README.md
david-rowley Sep 20, 2015
565c862
Add support for Postgres-XL
david-rowley Oct 1, 2015
8aba3d0
Remove incorrect STRICT properties from aggregate final functions
david-rowley Oct 2, 2015
48cd864
Various fixes for aggregates for Postgres-XL
david-rowley Oct 2, 2015
344f928
Create Postgres-XL specific regression tests
david-rowley Oct 2, 2015
1945c49
Remove unused CFLAGS in Makefile
david-rowley Oct 8, 2015
19baef0
Re-add CFLAGS. This time without the bogus -UXCP
david-rowley Oct 8, 2015
425de05
Final wording prior to release
Dec 23, 2015
2eb7c43
Add parallel aggregate support
david-rowley Jun 24, 2016
9e5f5dd
Fix typo
simonat2ndQuadrant Oct 1, 2019
eafd44f
Update README.md
simonat2ndQuadrant Oct 1, 2019
d959bdf
Bump to version 12.
irionr Oct 1, 2019
eec01fe
contrib/fixeddecimal: add support for Cloudberry
tuhaihe Feb 28, 2026
3bfd28a
ASF: add fixeddecimal license and RAT exclusions
tuhaihe Feb 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/build-cloudberry-rocky8.yml
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ jobs:
"contrib/formatter_fixedwidth:installcheck",
"contrib/hstore:installcheck",
"contrib/indexscan:installcheck",
"contrib/fixeddecimal:installcheck",
"contrib/pg_trgm:installcheck",
"contrib/indexscan:installcheck",
"contrib/pgcrypto:installcheck",
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/build-cloudberry.yml
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ jobs:
"contrib/formatter_fixedwidth:installcheck",
"contrib/hstore:installcheck",
"contrib/indexscan:installcheck",
"contrib/fixeddecimal:installcheck",
"contrib/pg_trgm:installcheck",
"contrib/indexscan:installcheck",
"contrib/pgcrypto:installcheck",
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/build-deb-cloudberry.yml
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ jobs:
"contrib/formatter_fixedwidth:installcheck",
"contrib/hstore:installcheck",
"contrib/indexscan:installcheck",
"contrib/fixeddecimal:installcheck",
"contrib/pg_trgm:installcheck",
"contrib/indexscan:installcheck",
"contrib/pgcrypto:installcheck",
Expand Down
6 changes: 6 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,12 @@ Apache Cloudberry includes codes from

see licenses/LICENSE-citusdata.txt

----------------------------
PostgreSQL License

contrib/fixeddecimal/*
see licenses/LICENSE-fixeddecimal.txt

----------------------------
Apache License - Version 2.0

Expand Down
3 changes: 2 additions & 1 deletion contrib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ SUBDIRS += \
formatter \
formatter_fixedwidth \
extprotocol \
indexscan
indexscan \
fixeddecimal

ifeq ($(with_ssl),openssl)
SUBDIRS += sslinfo
Expand Down
62 changes: 62 additions & 0 deletions contrib/fixeddecimal/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
MODULE_big = fixeddecimal
OBJS = fixeddecimal.o

EXTENSION = fixeddecimal

DATA = fixeddecimal--1.0.0--1.1.0.sql
DATA_built = fixeddecimal--1.1.0.sql

REGRESS_OPTS = --inputdir=test --outputdir=test --load-extension=fixeddecimal

ifdef USE_PGXS
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)

PG_VERSION_STR := $(shell $(PG_CONFIG) --version)
ifeq (,$(findstring XL,$(PG_VERSION_STR)))
REGRESS_BRIN := brin
REGRESS_VERSION_SPECIFIC := index
AGGSTATESQL :=
AGGFUNCSSQL := fixeddecimal--parallelaggs.sql
BRINSQL := fixeddecimal--brin.sql
BASESQL := fixeddecimal--1.1.0_base_parallel.sql
else
REGRESS_BRIN := brin-xl
REGRESS_VERSION_SPECIFIC := index-xl
AGGSTATESQL := fixeddecimalaggstate.sql
AGGFUNCSSQL := fixeddecimal--xlaggs.sql
BRINSQL :=
BASESQL := fixeddecimal--1.1.0_base.sql
endif
else
subdir = contrib/fixeddecimal
top_builddir = ../..

# Cloudberry in-tree builds are non-XL and support parallel/BRIN paths.
REGRESS_BRIN := brin
REGRESS_VERSION_SPECIFIC := index
AGGSTATESQL :=
AGGFUNCSSQL := fixeddecimal--parallelaggs.sql
BRINSQL := fixeddecimal--brin.sql
BASESQL := fixeddecimal--1.1.0_base_parallel.sql
endif

REGRESS = aggregate cast comparison overflow $(REGRESS_BRIN) $(REGRESS_VERSION_SPECIFIC)

ifeq ($(srcdir),)
FD_SRC_PREFIX :=
else
FD_SRC_PREFIX := $(srcdir)/
endif

OBJECTS := $(addprefix $(FD_SRC_PREFIX), $(AGGSTATESQL) $(BASESQL) $(AGGFUNCSSQL) $(BRINSQL))

fixeddecimal--1.1.0.sql: $(OBJECTS)
cat $^ > $@

ifdef USE_PGXS
include $(PGXS)
else
include $(top_builddir)/src/Makefile.global
include $(top_srcdir)/contrib/contrib-global.mk
endif
162 changes: 162 additions & 0 deletions contrib/fixeddecimal/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
FIXEDDECIMAL
============

Works with PostgreSQL 9.5 or higher.
The latest test was executed on version 12.

Overview
--------

FixedDecimal is a fixed precision decimal type which provides a subset of the
features of PostgreSQL's builtin NUMERIC type, but with vastly increased
performance. Fixeddecimal is targeted to cases where performance and disk space
are a critical.

Just use FIXEDDECIMAL(n, 2) rather than NUMERIC(n, 2) for n=3..17

Often there are data storage requirements where the built in REAL and
DOUBLE PRECISION types cannot be used due to the non-exact representation of
numbers using these types, e.g. where monetary values need to be stored. In many
of these cases NUMERIC is an almost perfect type, although with NUMERIC
performance is no match for the performance of REAL or DOUBLE PRECISION, as
these use CPU native processor types.

FixedDecimal delivers performance advantages over NUMERIC with full precision for
addition and subtraction. Just as occurs with REAL and DOUBLE PRECISION, there
are some caveats for multiplication and division.

Behavioural differences between FIXEDDECIMAL and NUMERIC
--------------------------------------------------------

It should be noted that there are cases were FIXEDDECIMAL behaves differently
from NUMERIC.

1. FIXEDDECIMAL has a much more limited range of values than NUMERIC. By
default this type can represent a maximum range of FIXEDDECIMAL(17,2),
although the underlying type is unable to represent the full range of
of the 17th significant digit.

2. FIXEDDECIMAL always rounds towards zero.

3. FIXEDDECIMAL does not support NaN.

4. Any attempt to use a numerical scale other than the default fixed scale
will result in an error. e.g. SELECT '123.223'::FIXEDDECIMAL(4,1) will fail
by default, as the default scale is 2, not 1.

Internals
---------

FIXEDDECIMAL internally uses a 64bit integer type for its underlying storage.
This is what gives the type the performance advantage over NUMERIC, as most
calculations are performed as native processor operations rather than software
implementations as in the case with NUMERIC.

FIXEDDECIMAL has a fixed scale value, which by default is 2. Internally numbers
are stores as the actual value multiplied by 100. e.g. 50 would be stored as
5000, and 1.23 would be stored as 123. This internal representation allows very
fast and accurate addition and subtraction between two fixeddecimal types.

Multiplication between two fixeddecimal types is slightly more complex. If we
perform 2.00 * 3.00 in fixeddecimal, internally these numbers would be 200 and
300 respectively, so internally 200 * 300 becomes 60000, which must be divided
by 100 in order to obtain the correct internal result of 600, which of course
externally is 6.00. This method of multiplication is hazard to overflowing the
internal 64bit integer type, for this reason all multiplication and division is
performed using 128bit integer types.

Internally, by default, FIXEDDECIMAL is limited to a maximum value of
92233720368547758.07 and a minimum value of -92233720368547758.08. If any of
these limits are exceeded the query will fail with an error.

By default the scale of FIXEDDECIMAL is 2 decimal digits after the decimal
point. This value may be changed only by recompiling FIXEDDECIMAL from source,
which is done by altering the FIXEDDECIMAL_MULTIPLIER and FIXEDDECIMAL_SCALE
constants. If the FIXEDDECIMAL_SCALE was set to 4, then the
FIXEDDECIMAL_MULTIPLIER should be set to 10000. Doing this will mean that the
absolute limits of the type decrease to a range of -922337203685477.5808 to
922337203685477.5807.

Caution
-------

FIXEDDECIMAL is mainly intended as a fast and efficient data type which will
suit a limited set numerical data storage and retrieval needs. Complex
arithmetic could be said to be one of fixeddecimal's limits. As stated above
division always rounds towards zero. Please observe the following example:

```
test=# select '2.00'::fixeddecimal / '3.00'::fixeddecimal;
?column?
----------
0.66
(1 row)
```

A workaround of this would be to perform all calculations in NUMERIC, and
ROUND() the result into the maximum scale of FIXEDDECIMAL:

```
test=# select round('2.00'::numeric / '3.00'::numeric, 2)::fixeddecimal;
?column?
----------
0.67
(1 row)
```

It should also be noted that excess precision is ignored by fixeddecimal.
With a FIXEDDECIMAL_PRECISION of 2, any value after the 2nd digit following
the decimal point is completely ignored rather than rounded. The following
example demonstrates this:

```
test=# select '1.239'::fixeddecimal;
fixeddecimal
--------------
1.23
(1 row)
```

It is especially important to remember that this truncation also occurs during
arithmetic. Notice in the following example the result is 1120 rather than
1129, since 1.129 is immediately rounded to 1.12 on input.

```
test=# select '1000'::fixeddecimal * '1.129'::fixeddecimal;
?column?
----------
1120.00
(1 row)
```

Installation
------------

To install fixeddecimal you must build the extension from source code.

First ensure that your PATH environment variable is setup to find the correct
PostgreSQL installation first. You can check this by typing running the
pg_config command and checking the paths listed.

Once you are confident your PATH variable is set correctly

```
make
make install
make installcheck
```

From psql, in order to create the extension you must type:

```
CREATE EXTENSION fixeddecimal;
```

Credits
-------

fixeddecimal is open source using The PostgreSQL Licence, copyright is novated to the PostgreSQL Global Development Group.

Source code developed by 2ndQuadrant, as part of the AXLE project (http://axleproject.eu) which received funding from the European Union’s Seventh Framework Programme (FP7/2007-2015) under grant agreement n° 318633

Lead Developer - David Rowley
Loading
Loading