Skip to content

Commit eec01fe

Browse files
committed
contrib/fixeddecimal: add support for Cloudberry
Add fixeddecimal to contrib recursive targets so it is built and tested with the rest of contrib modules. Rework contrib/fixeddecimal/Makefile to support both in-tree and PGXS builds: - use standard contrib in-tree includes (src/Makefile.global + contrib-global.mk) - keep USE_PGXS path for out-of-tree usage - remove hard dependency on pg_config for in-tree builds - fix generated SQL dependency path handling when srcdir is empty Fix fixeddecimal runtime issues seen in distributed aggregate execution: - avoid MAXINT8LEN macro conflict with core headers - switch int64 overflow checks to pg_add_s64_overflow/pg_sub_s64_overflow - harden aggregate state serialize/deserialize against NULL states - restore memory context before early return in aggregate combine Update fixeddecimal regression expected files for Cloudberry behavior (distribution-key NOTICEs, GPORCA plans, and distributed index semantics). With these changes, fixeddecimal builds, installs, and passes installcheck as a regular contrib extension in Cloudberry.
1 parent d959bdf commit eec01fe

11 files changed

Lines changed: 111 additions & 101 deletions

File tree

.github/workflows/build-cloudberry-rocky8.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ jobs:
305305
"contrib/formatter_fixedwidth:installcheck",
306306
"contrib/hstore:installcheck",
307307
"contrib/indexscan:installcheck",
308+
"contrib/fixeddecimal:installcheck",
308309
"contrib/pg_trgm:installcheck",
309310
"contrib/indexscan:installcheck",
310311
"contrib/pgcrypto:installcheck",

.github/workflows/build-cloudberry.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,7 @@ jobs:
298298
"contrib/formatter_fixedwidth:installcheck",
299299
"contrib/hstore:installcheck",
300300
"contrib/indexscan:installcheck",
301+
"contrib/fixeddecimal:installcheck",
301302
"contrib/pg_trgm:installcheck",
302303
"contrib/indexscan:installcheck",
303304
"contrib/pgcrypto:installcheck",

.github/workflows/build-deb-cloudberry.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ jobs:
237237
"contrib/formatter_fixedwidth:installcheck",
238238
"contrib/hstore:installcheck",
239239
"contrib/indexscan:installcheck",
240+
"contrib/fixeddecimal:installcheck",
240241
"contrib/pg_trgm:installcheck",
241242
"contrib/indexscan:installcheck",
242243
"contrib/pgcrypto:installcheck",

contrib/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ SUBDIRS += \
6060
formatter \
6161
formatter_fixedwidth \
6262
extprotocol \
63-
indexscan
63+
indexscan \
64+
fixeddecimal
6465

6566
ifeq ($(with_ssl),openssl)
6667
SUBDIRS += sslinfo

contrib/fixeddecimal/Makefile

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,33 +6,57 @@ EXTENSION = fixeddecimal
66
DATA = fixeddecimal--1.0.0--1.1.0.sql
77
DATA_built = fixeddecimal--1.1.0.sql
88

9-
CFLAGS = `pg_config --includedir-server`
10-
11-
TESTS = $(wildcard test/sql/*.sql)
12-
13-
REGRESS_BRIN := $(shell pg_config --version | grep -qE "XL 9\.[5-9]| 10\.0| 11\.[0-9]| 12\.[0-9]" && echo brin-xl)
14-
REGRESS_BRIN += $(shell pg_config --version | grep -E "9\.[5-9]| 10\.0| 11\.[0-9]| 12\.[0-9]" | grep -qEv "XL" && echo brin)
15-
REGRESS_VERSION_SPECIFIC := $(shell pg_config --version | grep -qE "XL" && echo index-xl || echo index)
16-
REGRESS = $(shell echo aggregate cast comparison overflow $(REGRESS_BRIN) $(REGRESS_VERSION_SPECIFIC))
17-
189
REGRESS_OPTS = --inputdir=test --outputdir=test --load-extension=fixeddecimal
1910

11+
ifdef USE_PGXS
2012
PG_CONFIG = pg_config
2113
PGXS := $(shell $(PG_CONFIG) --pgxs)
22-
include $(PGXS)
23-
24-
AGGSTATESQL := $(shell pg_config --version | grep -qE "XL" && echo fixeddecimalaggstate.sql)
25-
AGGFUNCSSQL := $(shell pg_config --version | grep -qE "XL" && echo fixeddecimal--xlaggs.sql)
2614

27-
AGGFUNCSSQL := $(shell pg_config --version | grep -qE "9\.[6-9]| 10\.[0-9]| 11\.[0-9]| 12\.[0-9]" && echo fixeddecimal--parallelaggs.sql || echo fixeddecimal--aggs.sql)
28-
29-
BRINSQL := $(shell pg_config --version | grep -qE "9\.[5-9]| 10\.[0-9]| 11\.[0-9]| 12\.[0-9]" && echo fixeddecimal--brin.sql)
30-
31-
# 9.6 was the dawn of parallel query, so we'll use the parallel enabled .sql file from then on.
32-
BASESQL := $(shell pg_config --version | grep -qE "9\.[6-9]| 10\.[0-9]| 11\.[0-9]| 12\.[0-9]" && echo fixeddecimal--1.1.0_base_parallel.sql || echo fixeddecimal--1.1.0_base.sql)
33-
34-
OBJECTS := $(addprefix $(srcdir)/, $(AGGSTATESQL) $(BASESQL) $(AGGFUNCSSQL) $(BRINSQL))
15+
PG_VERSION_STR := $(shell $(PG_CONFIG) --version)
16+
ifeq (,$(findstring XL,$(PG_VERSION_STR)))
17+
REGRESS_BRIN := brin
18+
REGRESS_VERSION_SPECIFIC := index
19+
AGGSTATESQL :=
20+
AGGFUNCSSQL := fixeddecimal--parallelaggs.sql
21+
BRINSQL := fixeddecimal--brin.sql
22+
BASESQL := fixeddecimal--1.1.0_base_parallel.sql
23+
else
24+
REGRESS_BRIN := brin-xl
25+
REGRESS_VERSION_SPECIFIC := index-xl
26+
AGGSTATESQL := fixeddecimalaggstate.sql
27+
AGGFUNCSSQL := fixeddecimal--xlaggs.sql
28+
BRINSQL :=
29+
BASESQL := fixeddecimal--1.1.0_base.sql
30+
endif
31+
else
32+
subdir = contrib/fixeddecimal
33+
top_builddir = ../..
34+
35+
# Cloudberry in-tree builds are non-XL and support parallel/BRIN paths.
36+
REGRESS_BRIN := brin
37+
REGRESS_VERSION_SPECIFIC := index
38+
AGGSTATESQL :=
39+
AGGFUNCSSQL := fixeddecimal--parallelaggs.sql
40+
BRINSQL := fixeddecimal--brin.sql
41+
BASESQL := fixeddecimal--1.1.0_base_parallel.sql
42+
endif
43+
44+
REGRESS = aggregate cast comparison overflow $(REGRESS_BRIN) $(REGRESS_VERSION_SPECIFIC)
45+
46+
ifeq ($(srcdir),)
47+
FD_SRC_PREFIX :=
48+
else
49+
FD_SRC_PREFIX := $(srcdir)/
50+
endif
51+
52+
OBJECTS := $(addprefix $(FD_SRC_PREFIX), $(AGGSTATESQL) $(BASESQL) $(AGGFUNCSSQL) $(BRINSQL))
3553

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

57+
ifdef USE_PGXS
58+
include $(PGXS)
59+
else
60+
include $(top_builddir)/src/Makefile.global
61+
include $(top_srcdir)/contrib/contrib-global.mk
62+
endif

contrib/fixeddecimal/fixeddecimal.c

Lines changed: 19 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,15 @@
2222
#include "funcapi.h"
2323
#include "libpq/pqformat.h"
2424
#include "access/hash.h"
25+
#include "common/int.h"
2526
#include "utils/array.h"
2627
#include "utils/builtins.h"
2728

2829
#include "utils/int8.h"
2930

3031
#include "utils/numeric.h"
3132

32-
#define MAXINT8LEN 25
33+
#define FIXEDDECIMAL_INT64STRLEN 25
3334

3435
/*
3536
* The scale which the number is actually stored.
@@ -681,7 +682,7 @@ Datum
681682
fixeddecimalout(PG_FUNCTION_ARGS)
682683
{
683684
int64 val = PG_GETARG_INT64(0);
684-
char buf[MAXINT8LEN + 1];
685+
char buf[FIXEDDECIMAL_INT64STRLEN + 1];
685686
char *end = fixeddecimal2str(val, buf);
686687
PG_RETURN_CSTRING(pnstrdup(buf, end - buf));
687688
}
@@ -1258,21 +1259,11 @@ fixeddecimalum(PG_FUNCTION_ARGS)
12581259
int64 arg = PG_GETARG_INT64(0);
12591260
int64 result;
12601261

1261-
#ifdef HAVE_BUILTIN_OVERFLOW
1262-
int64 zero = 0;
1263-
1264-
if (__builtin_sub_overflow(zero, arg, &result))
1265-
ereport(ERROR,
1266-
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1267-
errmsg("fixeddecimal out of range")));
1268-
#else
1269-
result = -arg;
1270-
/* overflow check (needed for INT64_MIN) */
1271-
if (arg != 0 && SAMESIGN(result, arg))
1262+
if (pg_sub_s64_overflow(0, arg, &result))
12721263
ereport(ERROR,
12731264
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
12741265
errmsg("fixeddecimal out of range")));
1275-
#endif /* HAVE_BUILTIN_OVERFLOW */
1266+
12761267
PG_RETURN_INT64(result);
12771268
}
12781269

@@ -1291,24 +1282,10 @@ fixeddecimalpl(PG_FUNCTION_ARGS)
12911282
int64 arg2 = PG_GETARG_INT64(1);
12921283
int64 result;
12931284

1294-
#ifdef HAVE_BUILTIN_OVERFLOW
1295-
if (__builtin_add_overflow(arg1, arg2, &result))
1285+
if (pg_add_s64_overflow(arg1, arg2, &result))
12961286
ereport(ERROR,
12971287
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
12981288
errmsg("fixeddecimal out of range")));
1299-
#else
1300-
result = arg1 + arg2;
1301-
1302-
/*
1303-
* Overflow check. If the inputs are of different signs then their sum
1304-
* cannot overflow. If the inputs are of the same sign, their sum had
1305-
* better be that sign too.
1306-
*/
1307-
if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
1308-
ereport(ERROR,
1309-
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1310-
errmsg("fixeddecimal out of range")));
1311-
#endif /* HAVE_BUILTIN_OVERFLOW */
13121289

13131290
PG_RETURN_INT64(result);
13141291
}
@@ -1320,24 +1297,10 @@ fixeddecimalmi(PG_FUNCTION_ARGS)
13201297
int64 arg2 = PG_GETARG_INT64(1);
13211298
int64 result;
13221299

1323-
#ifdef HAVE_BUILTIN_OVERFLOW
1324-
if (__builtin_sub_overflow(arg1, arg2, &result))
1300+
if (pg_sub_s64_overflow(arg1, arg2, &result))
13251301
ereport(ERROR,
13261302
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
13271303
errmsg("fixeddecimal out of range")));
1328-
#else
1329-
result = arg1 - arg2;
1330-
1331-
/*
1332-
* Overflow check. If the inputs are of the same sign then their
1333-
* difference cannot overflow. If they are of different signs then the
1334-
* result should be of the same sign as the first input.
1335-
*/
1336-
if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
1337-
ereport(ERROR,
1338-
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1339-
errmsg("fixeddecimal out of range")));
1340-
#endif /* HAVE_BUILTIN_OVERFLOW */
13411304

13421305
PG_RETURN_INT64(result);
13431306
}
@@ -2163,18 +2126,11 @@ makeFixedDecimalAggState(FunctionCallInfo fcinfo)
21632126
static void
21642127
fixeddecimal_accum(FixedDecimalAggState *state, int64 newval)
21652128
{
2166-
#ifdef HAVE_BUILTIN_OVERFLOW
2167-
if (__builtin_add_overflow(state->sumX, newval, &state->sumX))
2168-
ereport(ERROR,
2169-
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
2170-
errmsg("fixeddecimal out of range")));
2171-
state->N++;
2172-
#else
21732129
if (state->N++ > 0)
21742130
{
2175-
int64 result = state->sumX + newval;
2131+
int64 result;
21762132

2177-
if (SAMESIGN(state->sumX, newval) && !SAMESIGN(result, state->sumX))
2133+
if (pg_add_s64_overflow(state->sumX, newval, &result))
21782134
ereport(ERROR,
21792135
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
21802136
errmsg("fixeddecimal out of range")));
@@ -2183,7 +2139,6 @@ fixeddecimal_accum(FixedDecimalAggState *state, int64 newval)
21832139
}
21842140
else
21852141
state->sumX = newval;
2186-
#endif /* HAVE_BUILTIN_OVERFLOW */
21872142
}
21882143

21892144
Datum
@@ -2264,7 +2219,7 @@ Datum
22642219
fixeddecimalaggstateout(PG_FUNCTION_ARGS)
22652220
{
22662221
FixedDecimalAggState *state = (FixedDecimalAggState *) PG_GETARG_POINTER(0);
2267-
char buf[MAXINT8LEN + 1 + MAXINT8LEN + 1];
2222+
char buf[FIXEDDECIMAL_INT64STRLEN + 1 + FIXEDDECIMAL_INT64STRLEN + 1];
22682223
char *p;
22692224

22702225
p = fixeddecimal2str(state->sumX, buf);
@@ -2318,6 +2273,9 @@ fixeddecimalaggstateserialize(PG_FUNCTION_ARGS)
23182273
if (!AggCheckCallContext(fcinfo, NULL))
23192274
elog(ERROR, "aggregate function called in non-aggregate context");
23202275

2276+
if (PG_ARGISNULL(0))
2277+
PG_RETURN_NULL();
2278+
23212279
state = (FixedDecimalAggState *) PG_GETARG_POINTER(0);
23222280

23232281
pq_begintypsend(&buf);
@@ -2343,6 +2301,9 @@ fixeddecimalaggstatedeserialize(PG_FUNCTION_ARGS)
23432301
if (!AggCheckCallContext(fcinfo, NULL))
23442302
elog(ERROR, "aggregate function called in non-aggregate context");
23452303

2304+
if (PG_ARGISNULL(0))
2305+
PG_RETURN_NULL();
2306+
23462307
sstate = PG_GETARG_BYTEA_P(0);
23472308

23482309
/*
@@ -2395,7 +2356,10 @@ fixeddecimalaggstatecombine(PG_FUNCTION_ARGS)
23952356
PG_GETARG_POINTER(1);
23962357

23972358
if (transstate == NULL)
2359+
{
2360+
MemoryContextSwitchTo(old_context);
23982361
PG_RETURN_POINTER(collectstate);
2362+
}
23992363

24002364
collectstate->sumX = DatumGetInt64(DirectFunctionCall2(fixeddecimalpl,
24012365
Int64GetDatum(collectstate->sumX), Int64GetDatum(transstate->sumX)));
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
comment = 'fixeddecimal'
1+
comment = 'Exact fixed-point decimal type with operators, aggregates, and index support'
22
default_version = '1.1.0'
33
relocatable = false
44
module_pathname = '$libdir/fixeddecimal'

contrib/fixeddecimal/test/expected/aggregate.out

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
CREATE TABLE fixed_decimal(a FIXEDDECIMAL NOT NULL);
2+
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table.
23
INSERT INTO fixed_decimal VALUES('92233720368547758.07'),('0.01'),('-92233720368547758.08'),('-0.01');
34
SELECT SUM(a) FROM fixed_decimal WHERE a > 0;
45
ERROR: fixeddecimal out of range

contrib/fixeddecimal/test/expected/brin.out

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
-- Test BRIN indexes
22
SET enable_seqscan = off;
33
CREATE TABLE fixdec (d FIXEDDECIMAL, txt TEXT);
4+
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'd' as the Apache Cloudberry data distribution key for this table.
45
INSERT INTO fixdec SELECT s.i,REPEAT('0',64) FROM generate_series(1,10000) s(i);
56
CREATE INDEX fixdec_d_idx ON fixdec USING BRIN (d);
67
EXPLAIN (COSTS OFF) SELECT * FROM fixdec WHERE d > '9999'::FIXEDDECIMAL;
7-
QUERY PLAN
8-
---------------------------------------------------
9-
Bitmap Heap Scan on fixdec
10-
Recheck Cond: (d > '9999.00'::fixeddecimal)
11-
-> Bitmap Index Scan on fixdec_d_idx
12-
Index Cond: (d > '9999.00'::fixeddecimal)
13-
(4 rows)
8+
QUERY PLAN
9+
---------------------------------------------------------------
10+
Gather Motion 3:1 (slice1; segments: 3)
11+
-> Bitmap Heap Scan on fixdec
12+
Recheck Cond: (d > '9999.00'::fixeddecimal)
13+
-> Bitmap Index Scan on fixdec_d_idx
14+
Index Cond: (d > '9999.00'::fixeddecimal)
15+
Optimizer: GPORCA
16+
(6 rows)
1417

1518
SELECT * FROM fixdec WHERE d > '9999'::FIXEDDECIMAL;
1619
d | txt

0 commit comments

Comments
 (0)