Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit7ae1619

Browse files
committed
Add range_agg with multirange inputs
range_agg for normal ranges already existed. A lot of code can beshared.Author: Paul Jungwirth <pj@illuminatedcomputing.com>Reviewed-by: Chapman Flack <chap@anastigmatix.net>Discussion:https://www.postgresql.org/message-id/flat/007ef255-35ef-fd26-679c-f97e7a7f30c2@illuminatedcomputing.com
1 parentff50bae commit7ae1619

File tree

8 files changed

+156
-2
lines changed

8 files changed

+156
-2
lines changed

‎doc/src/sgml/func.sgml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20007,6 +20007,11 @@ SELECT NULLIF(value, '(none)') ...
2000720007
<type>anyrange</type> )
2000820008
<returnvalue>anymultirange</returnvalue>
2000920009
</para>
20010+
<para role="func_signature">
20011+
<function>range_agg</function> ( <parameter>value</parameter>
20012+
<type>anymultirange</type> )
20013+
<returnvalue>anymultirange</returnvalue>
20014+
</para>
2001020015
<para>
2001120016
Computes the union of the non-null input values.
2001220017
</para></entry>

‎src/backend/utils/adt/multirangetypes.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1361,6 +1361,9 @@ range_agg_transfn(PG_FUNCTION_ARGS)
13611361

13621362
/*
13631363
* range_agg_finalfn: use our internal array to merge touching ranges.
1364+
*
1365+
* Shared by range_agg_finalfn(anyrange) and
1366+
* multirange_agg_finalfn(anymultirange).
13641367
*/
13651368
Datum
13661369
range_agg_finalfn(PG_FUNCTION_ARGS)
@@ -1396,6 +1399,64 @@ range_agg_finalfn(PG_FUNCTION_ARGS)
13961399
PG_RETURN_MULTIRANGE_P(make_multirange(mltrngtypoid,typcache->rngtype,range_count,ranges));
13971400
}
13981401

1402+
/*
1403+
* multirange_agg_transfn: combine adjacent/overlapping multiranges.
1404+
*
1405+
* All we do here is gather the input multiranges' ranges into an array so
1406+
* that the finalfn can sort and combine them.
1407+
*/
1408+
Datum
1409+
multirange_agg_transfn(PG_FUNCTION_ARGS)
1410+
{
1411+
MemoryContextaggContext;
1412+
Oidmltrngtypoid;
1413+
TypeCacheEntry*typcache;
1414+
TypeCacheEntry*rngtypcache;
1415+
ArrayBuildState*state;
1416+
1417+
if (!AggCheckCallContext(fcinfo,&aggContext))
1418+
elog(ERROR,"multirange_agg_transfn called in non-aggregate context");
1419+
1420+
mltrngtypoid=get_fn_expr_argtype(fcinfo->flinfo,1);
1421+
if (!type_is_multirange(mltrngtypoid))
1422+
elog(ERROR,"range_agg must be called with a multirange");
1423+
1424+
typcache=multirange_get_typcache(fcinfo,mltrngtypoid);
1425+
rngtypcache=typcache->rngtype;
1426+
1427+
if (PG_ARGISNULL(0))
1428+
state=initArrayResult(rngtypcache->type_id,aggContext, false);
1429+
else
1430+
state= (ArrayBuildState*)PG_GETARG_POINTER(0);
1431+
1432+
/* skip NULLs */
1433+
if (!PG_ARGISNULL(1))
1434+
{
1435+
MultirangeType*current;
1436+
int32range_count;
1437+
RangeType**ranges;
1438+
1439+
current=PG_GETARG_MULTIRANGE_P(1);
1440+
multirange_deserialize(rngtypcache,current,&range_count,&ranges);
1441+
if (range_count==0)
1442+
{
1443+
/*
1444+
* Add an empty range so we get an empty result (not a null result).
1445+
*/
1446+
accumArrayResult(state,
1447+
RangeTypePGetDatum(make_empty_range(rngtypcache)),
1448+
false,rngtypcache->type_id,aggContext);
1449+
}
1450+
else
1451+
{
1452+
for (int32i=0;i<range_count;i++)
1453+
accumArrayResult(state,RangeTypePGetDatum(ranges[i]), false,rngtypcache->type_id,aggContext);
1454+
}
1455+
}
1456+
1457+
PG_RETURN_POINTER(state);
1458+
}
1459+
13991460
Datum
14001461
multirange_intersect_agg_transfn(PG_FUNCTION_ARGS)
14011462
{

‎src/include/catalog/catversion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/*yyyymmddN */
56-
#defineCATALOG_VERSION_NO202203291
56+
#defineCATALOG_VERSION_NO202203301
5757

5858
#endif

‎src/include/catalog/pg_aggregate.dat

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,9 @@
563563
{ aggfnoid => 'range_agg(anyrange)', aggtransfn => 'range_agg_transfn',
564564
aggfinalfn => 'range_agg_finalfn', aggfinalextra => 't',
565565
aggtranstype => 'internal' },
566+
{ aggfnoid => 'range_agg(anymultirange)', aggtransfn => 'multirange_agg_transfn',
567+
aggfinalfn => 'multirange_agg_finalfn', aggfinalextra => 't',
568+
aggtranstype => 'internal' },
566569

567570
# json
568571
{ aggfnoid => 'json_agg', aggtransfn => 'json_agg_transfn',

‎src/include/catalog/pg_proc.dat

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10688,6 +10688,17 @@
1068810688
proname => 'range_agg', prokind => 'a', proisstrict => 'f',
1068910689
prorettype => 'anymultirange', proargtypes => 'anyrange',
1069010690
prosrc => 'aggregate_dummy' },
10691+
{ oid => '8205', descr => 'aggregate transition function',
10692+
proname => 'multirange_agg_transfn', proisstrict => 'f', prorettype => 'internal',
10693+
proargtypes => 'internal anymultirange', prosrc => 'multirange_agg_transfn' },
10694+
{ oid => '8206', descr => 'aggregate final function',
10695+
proname => 'multirange_agg_finalfn', proisstrict => 'f',
10696+
prorettype => 'anymultirange', proargtypes => 'internal anymultirange',
10697+
prosrc => 'range_agg_finalfn' },
10698+
{ oid => '8207', descr => 'combine aggregate input into a multirange',
10699+
proname => 'range_agg', prokind => 'a', proisstrict => 'f',
10700+
prorettype => 'anymultirange', proargtypes => 'anymultirange',
10701+
prosrc => 'aggregate_dummy' },
1069110702
{ oid => '4388', descr => 'range aggregate by intersecting',
1069210703
proname => 'multirange_intersect_agg_transfn', prorettype => 'anymultirange',
1069310704
proargtypes => 'anymultirange anymultirange',

‎src/test/regress/expected/multirangetypes.out

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2784,6 +2784,67 @@ FROM (VALUES
27842784
{[a,f],[g,j)}
27852785
(1 row)
27862786

2787+
-- range_agg with multirange inputs
2788+
select range_agg(nmr) from nummultirange_test;
2789+
range_agg
2790+
-----------
2791+
{(,)}
2792+
(1 row)
2793+
2794+
select range_agg(nmr) from nummultirange_test where false;
2795+
range_agg
2796+
-----------
2797+
2798+
(1 row)
2799+
2800+
select range_agg(null::nummultirange) from nummultirange_test;
2801+
range_agg
2802+
-----------
2803+
2804+
(1 row)
2805+
2806+
select range_agg(nmr) from (values ('{}'::nummultirange)) t(nmr);
2807+
range_agg
2808+
-----------
2809+
{}
2810+
(1 row)
2811+
2812+
select range_agg(nmr) from (values ('{}'::nummultirange), ('{}'::nummultirange)) t(nmr);
2813+
range_agg
2814+
-----------
2815+
{}
2816+
(1 row)
2817+
2818+
select range_agg(nmr) from (values ('{[1,2]}'::nummultirange)) t(nmr);
2819+
range_agg
2820+
-----------
2821+
{[1,2]}
2822+
(1 row)
2823+
2824+
select range_agg(nmr) from (values ('{[1,2], [5,6]}'::nummultirange)) t(nmr);
2825+
range_agg
2826+
---------------
2827+
{[1,2],[5,6]}
2828+
(1 row)
2829+
2830+
select range_agg(nmr) from (values ('{[1,2], [2,3]}'::nummultirange)) t(nmr);
2831+
range_agg
2832+
-----------
2833+
{[1,3]}
2834+
(1 row)
2835+
2836+
select range_agg(nmr) from (values ('{[1,2]}'::nummultirange), ('{[5,6]}'::nummultirange)) t(nmr);
2837+
range_agg
2838+
---------------
2839+
{[1,2],[5,6]}
2840+
(1 row)
2841+
2842+
select range_agg(nmr) from (values ('{[1,2]}'::nummultirange), ('{[2,3]}'::nummultirange)) t(nmr);
2843+
range_agg
2844+
-----------
2845+
{[1,3]}
2846+
(1 row)
2847+
27872848
--
27882849
-- range_intersect_agg function
27892850
--

‎src/test/regress/expected/opr_sanity.out

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,8 @@ ORDER BY 1, 2;
201201
timestamp without time zone | timestamp with time zone
202202
bit | bit varying
203203
txid_snapshot | pg_snapshot
204-
(4 rows)
204+
anyrange | anymultirange
205+
(5 rows)
205206

206207
SELECT DISTINCT p1.proargtypes[2]::regtype, p2.proargtypes[2]::regtype
207208
FROM pg_proc AS p1, pg_proc AS p2

‎src/test/regress/sql/multirangetypes.sql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,18 @@ FROM (VALUES
572572
('[h,j)'::textrange)
573573
) t(r);
574574

575+
-- range_agg with multirange inputs
576+
select range_agg(nmr)from nummultirange_test;
577+
select range_agg(nmr)from nummultirange_testwhere false;
578+
select range_agg(null::nummultirange)from nummultirange_test;
579+
select range_agg(nmr)from (values ('{}'::nummultirange)) t(nmr);
580+
select range_agg(nmr)from (values ('{}'::nummultirange), ('{}'::nummultirange)) t(nmr);
581+
select range_agg(nmr)from (values ('{[1,2]}'::nummultirange)) t(nmr);
582+
select range_agg(nmr)from (values ('{[1,2], [5,6]}'::nummultirange)) t(nmr);
583+
select range_agg(nmr)from (values ('{[1,2], [2,3]}'::nummultirange)) t(nmr);
584+
select range_agg(nmr)from (values ('{[1,2]}'::nummultirange), ('{[5,6]}'::nummultirange)) t(nmr);
585+
select range_agg(nmr)from (values ('{[1,2]}'::nummultirange), ('{[2,3]}'::nummultirange)) t(nmr);
586+
575587
--
576588
-- range_intersect_agg function
577589
--

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp