Skip to content

Commit 9e38c2b

Browse files
committed
Declare assorted array functions using anycompatible not anyelement.
Convert array_append, array_prepend, array_cat, array_position, array_positions, array_remove, array_replace, and width_bucket to use anycompatiblearray. This is a simple extension of commit 5c292e6 to hit some other places where there's a pretty obvious gain in usability from doing so. Ideally we'd also modify other functions taking multiple old-style polymorphic arguments. But most of the remainder are tied into one or more operator classes, making any such change a much larger can of worms than I desire to open right now. Discussion: https://postgr.es/m/77675130-89da-dab1-51dd-492c93dcf5d1@postgresfriends.org
1 parent 5c292e6 commit 9e38c2b

File tree

9 files changed

+86
-57
lines changed

9 files changed

+86
-57
lines changed

doc/src/sgml/func.sgml

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1756,7 +1756,7 @@ repeat('Pg', 4) <returnvalue>PgPgPgPg</returnvalue>
17561756

17571757
<row>
17581758
<entry role="func_table_entry"><para role="func_signature">
1759-
<function>width_bucket</function> ( <parameter>operand</parameter> <type>anyelement</type>, <parameter>thresholds</parameter> <type>anyarray</type> )
1759+
<function>width_bucket</function> ( <parameter>operand</parameter> <type>anycompatible</type>, <parameter>thresholds</parameter> <type>anycompatiblearray</type> )
17601760
<returnvalue>integer</returnvalue>
17611761
</para>
17621762
<para>
@@ -17448,29 +17448,31 @@ SELECT NULLIF(value, '(none)') ...
1744817448

1744917449
<row>
1745017450
<entry role="func_table_entry"><para role="func_signature">
17451-
<type>anyarray</type> <literal>||</literal> <type>anyarray</type>
17452-
<returnvalue>anyarray</returnvalue>
17451+
<type>anycompatiblearray</type> <literal>||</literal> <type>anycompatiblearray</type>
17452+
<returnvalue>anycompatiblearray</returnvalue>
1745317453
</para>
1745417454
<para>
1745517455
Concatenates the two arrays. Concatenating a null or empty array is a
1745617456
no-op; otherwise the arrays must have the same number of dimensions
1745717457
(as illustrated by the first example) or differ in number of
1745817458
dimensions by one (as illustrated by the second).
17459+
If the arrays are not of identical element types, they will be coerced
17460+
to a common type (see <xref linkend="typeconv-union-case"/>).
1745917461
</para>
1746017462
<para>
1746117463
<literal>ARRAY[1,2,3] || ARRAY[4,5,6,7]</literal>
1746217464
<returnvalue>{1,2,3,4,5,6,7}</returnvalue>
1746317465
</para>
1746417466
<para>
17465-
<literal>ARRAY[1,2,3] || ARRAY[[4,5,6],[7,8,9]]</literal>
17466-
<returnvalue>{{1,2,3},{4,5,6},{7,8,9}}</returnvalue>
17467+
<literal>ARRAY[1,2,3] || ARRAY[[4,5,6],[7,8,9.9]]</literal>
17468+
<returnvalue>{{1,2,3},{4,5,6},{7,8,9.9}}</returnvalue>
1746717469
</para></entry>
1746817470
</row>
1746917471

1747017472
<row>
1747117473
<entry role="func_table_entry"><para role="func_signature">
17472-
<type>anyelement</type> <literal>||</literal> <type>anyarray</type>
17473-
<returnvalue>anyarray</returnvalue>
17474+
<type>anycompatible</type> <literal>||</literal> <type>anycompatiblearray</type>
17475+
<returnvalue>anycompatiblearray</returnvalue>
1747417476
</para>
1747517477
<para>
1747617478
Concatenates an element onto the front of an array (which must be
@@ -17484,8 +17486,8 @@ SELECT NULLIF(value, '(none)') ...
1748417486

1748517487
<row>
1748617488
<entry role="func_table_entry"><para role="func_signature">
17487-
<type>anyarray</type> <literal>||</literal> <type>anyelement</type>
17488-
<returnvalue>anyarray</returnvalue>
17489+
<type>anycompatiblearray</type> <literal>||</literal> <type>anycompatible</type>
17490+
<returnvalue>anycompatiblearray</returnvalue>
1748917491
</para>
1749017492
<para>
1749117493
Concatenates an element onto the end of an array (which must be
@@ -17535,12 +17537,12 @@ SELECT NULLIF(value, '(none)') ...
1753517537
<indexterm>
1753617538
<primary>array_append</primary>
1753717539
</indexterm>
17538-
<function>array_append</function> ( <type>anyarray</type>, <type>anyelement</type> )
17539-
<returnvalue>anyarray</returnvalue>
17540+
<function>array_append</function> ( <type>anycompatiblearray</type>, <type>anycompatible</type> )
17541+
<returnvalue>anycompatiblearray</returnvalue>
1754017542
</para>
1754117543
<para>
1754217544
Appends an element to the end of an array (same as
17543-
the <type>anyarray</type> <literal>||</literal> <type>anyelement</type>
17545+
the <type>anycompatiblearray</type> <literal>||</literal> <type>anycompatible</type>
1754417546
operator).
1754517547
</para>
1754617548
<para>
@@ -17554,12 +17556,12 @@ SELECT NULLIF(value, '(none)') ...
1755417556
<indexterm>
1755517557
<primary>array_cat</primary>
1755617558
</indexterm>
17557-
<function>array_cat</function> ( <type>anyarray</type>, <type>anyarray</type> )
17558-
<returnvalue>anyarray</returnvalue>
17559+
<function>array_cat</function> ( <type>anycompatiblearray</type>, <type>anycompatiblearray</type> )
17560+
<returnvalue>anycompatiblearray</returnvalue>
1755917561
</para>
1756017562
<para>
1756117563
Concatenates two arrays (same as
17562-
the <type>anyarray</type> <literal>||</literal> <type>anyarray</type>
17564+
the <type>anycompatiblearray</type> <literal>||</literal> <type>anycompatiblearray</type>
1756317565
operator).
1756417566
</para>
1756517567
<para>
@@ -17666,7 +17668,7 @@ SELECT NULLIF(value, '(none)') ...
1766617668
<indexterm>
1766717669
<primary>array_position</primary>
1766817670
</indexterm>
17669-
<function>array_position</function> ( <type>anyarray</type>, <type>anyelement</type> <optional>, <type>integer</type> </optional> )
17671+
<function>array_position</function> ( <type>anycompatiblearray</type>, <type>anycompatible</type> <optional>, <type>integer</type> </optional> )
1767017672
<returnvalue>integer</returnvalue>
1767117673
</para>
1767217674
<para>
@@ -17688,7 +17690,7 @@ SELECT NULLIF(value, '(none)') ...
1768817690
<indexterm>
1768917691
<primary>array_positions</primary>
1769017692
</indexterm>
17691-
<function>array_positions</function> ( <type>anyarray</type>, <type>anyelement</type> )
17693+
<function>array_positions</function> ( <type>anycompatiblearray</type>, <type>anycompatible</type> )
1769217694
<returnvalue>integer[]</returnvalue>
1769317695
</para>
1769417696
<para>
@@ -17712,12 +17714,12 @@ SELECT NULLIF(value, '(none)') ...
1771217714
<indexterm>
1771317715
<primary>array_prepend</primary>
1771417716
</indexterm>
17715-
<function>array_prepend</function> ( <type>anyelement</type>, <type>anyarray</type> )
17716-
<returnvalue>anyarray</returnvalue>
17717+
<function>array_prepend</function> ( <type>anycompatible</type>, <type>anycompatiblearray</type> )
17718+
<returnvalue>anycompatiblearray</returnvalue>
1771717719
</para>
1771817720
<para>
1771917721
Prepends an element to the beginning of an array (same as
17720-
the <type>anyelement</type> <literal>||</literal> <type>anyarray</type>
17722+
the <type>anycompatible</type> <literal>||</literal> <type>anycompatiblearray</type>
1772117723
operator).
1772217724
</para>
1772317725
<para>
@@ -17731,8 +17733,8 @@ SELECT NULLIF(value, '(none)') ...
1773117733
<indexterm>
1773217734
<primary>array_remove</primary>
1773317735
</indexterm>
17734-
<function>array_remove</function> ( <type>anyarray</type>, <type>anyelement</type> )
17735-
<returnvalue>anyarray</returnvalue>
17736+
<function>array_remove</function> ( <type>anycompatiblearray</type>, <type>anycompatible</type> )
17737+
<returnvalue>anycompatiblearray</returnvalue>
1773617738
</para>
1773717739
<para>
1773817740
Removes all elements equal to the given value from the array.
@@ -17751,8 +17753,8 @@ SELECT NULLIF(value, '(none)') ...
1775117753
<indexterm>
1775217754
<primary>array_replace</primary>
1775317755
</indexterm>
17754-
<function>array_replace</function> ( <type>anyarray</type>, <type>anyelement</type>, <type>anyelement</type> )
17755-
<returnvalue>anyarray</returnvalue>
17756+
<function>array_replace</function> ( <type>anycompatiblearray</type>, <type>anycompatible</type>, <type>anycompatible</type> )
17757+
<returnvalue>anycompatiblearray</returnvalue>
1775617758
</para>
1775717759
<para>
1775817760
Replaces each array element equal to the second argument with the

doc/src/sgml/xaggr.sgml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,10 +298,10 @@ FROM (VALUES (1, 1.0e20::float8),
298298
Here is an example of a polymorphic aggregate:
299299

300300
<programlisting>
301-
CREATE AGGREGATE array_accum (anyelement)
301+
CREATE AGGREGATE array_accum (anycompatible)
302302
(
303303
sfunc = array_append,
304-
stype = anyarray,
304+
stype = anycompatiblearray,
305305
initcond = '{}'
306306
);
307307
</programlisting>

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-
#define CATALOG_VERSION_NO 202011043
56+
#define CATALOG_VERSION_NO 202011044
5757

5858
#endif

src/include/catalog/pg_operator.dat

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -168,14 +168,15 @@
168168
oprcode => 'textnename', oprrest => 'neqsel', oprjoin => 'neqjoinsel' },
169169

170170
{ oid => '349', descr => 'append element onto end of array',
171-
oprname => '||', oprleft => 'anyarray', oprright => 'anyelement',
172-
oprresult => 'anyarray', oprcode => 'array_append' },
171+
oprname => '||', oprleft => 'anycompatiblearray', oprright => 'anycompatible',
172+
oprresult => 'anycompatiblearray', oprcode => 'array_append' },
173173
{ oid => '374', descr => 'prepend element onto front of array',
174-
oprname => '||', oprleft => 'anyelement', oprright => 'anyarray',
175-
oprresult => 'anyarray', oprcode => 'array_prepend' },
174+
oprname => '||', oprleft => 'anycompatible', oprright => 'anycompatiblearray',
175+
oprresult => 'anycompatiblearray', oprcode => 'array_prepend' },
176176
{ oid => '375', descr => 'concatenate',
177-
oprname => '||', oprleft => 'anyarray', oprright => 'anyarray',
178-
oprresult => 'anyarray', oprcode => 'array_cat' },
177+
oprname => '||', oprleft => 'anycompatiblearray',
178+
oprright => 'anycompatiblearray', oprresult => 'anycompatiblearray',
179+
oprcode => 'array_cat' },
179180

180181
{ oid => '352', descr => 'equal',
181182
oprname => '=', oprcanhash => 't', oprleft => 'xid', oprright => 'xid',

src/include/catalog/pg_proc.dat

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1548,14 +1548,19 @@
15481548
proname => 'cardinality', prorettype => 'int4', proargtypes => 'anyarray',
15491549
prosrc => 'array_cardinality' },
15501550
{ oid => '378', descr => 'append element onto end of array',
1551-
proname => 'array_append', proisstrict => 'f', prorettype => 'anyarray',
1552-
proargtypes => 'anyarray anyelement', prosrc => 'array_append' },
1551+
proname => 'array_append', proisstrict => 'f',
1552+
prorettype => 'anycompatiblearray',
1553+
proargtypes => 'anycompatiblearray anycompatible', prosrc => 'array_append' },
15531554
{ oid => '379', descr => 'prepend element onto front of array',
1554-
proname => 'array_prepend', proisstrict => 'f', prorettype => 'anyarray',
1555-
proargtypes => 'anyelement anyarray', prosrc => 'array_prepend' },
1555+
proname => 'array_prepend', proisstrict => 'f',
1556+
prorettype => 'anycompatiblearray',
1557+
proargtypes => 'anycompatible anycompatiblearray',
1558+
prosrc => 'array_prepend' },
15561559
{ oid => '383',
1557-
proname => 'array_cat', proisstrict => 'f', prorettype => 'anyarray',
1558-
proargtypes => 'anyarray anyarray', prosrc => 'array_cat' },
1560+
proname => 'array_cat', proisstrict => 'f',
1561+
prorettype => 'anycompatiblearray',
1562+
proargtypes => 'anycompatiblearray anycompatiblearray',
1563+
prosrc => 'array_cat' },
15591564
{ oid => '394', descr => 'split delimited text',
15601565
proname => 'string_to_array', proisstrict => 'f', prorettype => '_text',
15611566
proargtypes => 'text text', prosrc => 'text_to_array' },
@@ -1587,15 +1592,18 @@
15871592
proargtypes => 'anyarray anyarray', prosrc => 'array_smaller' },
15881593
{ oid => '3277', descr => 'returns an offset of value in array',
15891594
proname => 'array_position', proisstrict => 'f', prorettype => 'int4',
1590-
proargtypes => 'anyarray anyelement', prosrc => 'array_position' },
1595+
proargtypes => 'anycompatiblearray anycompatible',
1596+
prosrc => 'array_position' },
15911597
{ oid => '3278',
15921598
descr => 'returns an offset of value in array with start index',
15931599
proname => 'array_position', proisstrict => 'f', prorettype => 'int4',
1594-
proargtypes => 'anyarray anyelement int4', prosrc => 'array_position_start' },
1600+
proargtypes => 'anycompatiblearray anycompatible int4',
1601+
prosrc => 'array_position_start' },
15951602
{ oid => '3279',
15961603
descr => 'returns an array of offsets of some value in array',
15971604
proname => 'array_positions', proisstrict => 'f', prorettype => '_int4',
1598-
proargtypes => 'anyarray anyelement', prosrc => 'array_positions' },
1605+
proargtypes => 'anycompatiblearray anycompatible',
1606+
prosrc => 'array_positions' },
15991607
{ oid => '1191', descr => 'array subscripts generator',
16001608
proname => 'generate_subscripts', prorows => '1000', proretset => 't',
16011609
prorettype => 'int4', proargtypes => 'anyarray int4 bool',
@@ -1620,11 +1628,14 @@
16201628
proargtypes => 'internal', prosrc => 'array_unnest_support' },
16211629
{ oid => '3167',
16221630
descr => 'remove any occurrences of an element from an array',
1623-
proname => 'array_remove', proisstrict => 'f', prorettype => 'anyarray',
1624-
proargtypes => 'anyarray anyelement', prosrc => 'array_remove' },
1631+
proname => 'array_remove', proisstrict => 'f',
1632+
prorettype => 'anycompatiblearray',
1633+
proargtypes => 'anycompatiblearray anycompatible', prosrc => 'array_remove' },
16251634
{ oid => '3168', descr => 'replace any occurrences of an element in an array',
1626-
proname => 'array_replace', proisstrict => 'f', prorettype => 'anyarray',
1627-
proargtypes => 'anyarray anyelement anyelement', prosrc => 'array_replace' },
1635+
proname => 'array_replace', proisstrict => 'f',
1636+
prorettype => 'anycompatiblearray',
1637+
proargtypes => 'anycompatiblearray anycompatible anycompatible',
1638+
prosrc => 'array_replace' },
16281639
{ oid => '2333', descr => 'aggregate transition function',
16291640
proname => 'array_agg_transfn', proisstrict => 'f', prorettype => 'internal',
16301641
proargtypes => 'internal anynonarray', prosrc => 'array_agg_transfn' },
@@ -1650,7 +1661,8 @@
16501661
{ oid => '3218',
16511662
descr => 'bucket number of operand given a sorted array of bucket lower bounds',
16521663
proname => 'width_bucket', prorettype => 'int4',
1653-
proargtypes => 'anyelement anyarray', prosrc => 'width_bucket_array' },
1664+
proargtypes => 'anycompatible anycompatiblearray',
1665+
prosrc => 'width_bucket_array' },
16541666
{ oid => '3816', descr => 'array typanalyze',
16551667
proname => 'array_typanalyze', provolatile => 's', prorettype => 'bool',
16561668
proargtypes => 'internal', prosrc => 'array_typanalyze' },

src/test/regress/expected/arrays.out

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,12 @@ SELECT 0 || ARRAY[1,2] || 3 AS "{0,1,2,3}";
726726
{0,1,2,3}
727727
(1 row)
728728

729+
SELECT ARRAY[1.1] || ARRAY[2,3,4];
730+
?column?
731+
-------------
732+
{1.1,2,3,4}
733+
(1 row)
734+
729735
SELECT * FROM array_op_test WHERE i @> '{32}' ORDER BY seqno;
730736
seqno | i | t
731737
-------+---------------------------------+------------------------------------------------------------------------------------------------------------------------------------
@@ -2146,6 +2152,12 @@ select array_remove(array['A','CC','D','C','RR'], 'RR');
21462152
{A,CC,D,C}
21472153
(1 row)
21482154

2155+
select array_remove(array[1.0, 2.1, 3.3], 1);
2156+
array_remove
2157+
--------------
2158+
{2.1,3.3}
2159+
(1 row)
2160+
21492161
select array_remove('{{1,2,2},{1,4,3}}', 2); -- not allowed
21502162
ERROR: removing elements from multidimensional arrays is not supported
21512163
select array_remove(array['X','X','X'], 'X') = '{}';

src/test/regress/expected/polymorphism.out

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -729,10 +729,10 @@ select q2, sql_if(q2 > 0, q2, q2 + 1) from int8_tbl;
729729
(5 rows)
730730

731731
-- another sort of polymorphic aggregate
732-
CREATE AGGREGATE array_cat_accum (anyarray)
732+
CREATE AGGREGATE array_cat_accum (anycompatiblearray)
733733
(
734734
sfunc = array_cat,
735-
stype = anyarray,
735+
stype = anycompatiblearray,
736736
initcond = '{}'
737737
);
738738
SELECT array_cat_accum(i)
@@ -786,16 +786,16 @@ create aggregate build_group(int8, integer) (
786786
STYPE = int8[]
787787
);
788788
-- check proper resolution of data types for polymorphic transfn/finalfn
789-
create function first_el(anyarray) returns anyelement as
789+
create function first_el(anycompatiblearray) returns anycompatible as
790790
'select $1[1]' language sql strict immutable;
791791
create aggregate first_el_agg_f8(float8) (
792792
SFUNC = array_append,
793793
STYPE = float8[],
794794
FINALFUNC = first_el
795795
);
796-
create aggregate first_el_agg_any(anyelement) (
796+
create aggregate first_el_agg_any(anycompatible) (
797797
SFUNC = array_append,
798-
STYPE = anyarray,
798+
STYPE = anycompatiblearray,
799799
FINALFUNC = first_el
800800
);
801801
select first_el_agg_f8(x::float8) from generate_series(1,10) x;

src/test/regress/sql/arrays.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ SELECT ARRAY[[['hello','world']]] || ARRAY[[['happy','birthday']]] AS "ARRAY";
311311
SELECT ARRAY[[1,2],[3,4]] || ARRAY[5,6] AS "{{1,2},{3,4},{5,6}}";
312312
SELECT ARRAY[0,0] || ARRAY[1,1] || ARRAY[2,2] AS "{0,0,1,1,2,2}";
313313
SELECT 0 || ARRAY[1,2] || 3 AS "{0,1,2,3}";
314+
SELECT ARRAY[1.1] || ARRAY[2,3,4];
314315

315316
SELECT * FROM array_op_test WHERE i @> '{32}' ORDER BY seqno;
316317
SELECT * FROM array_op_test WHERE i && '{32}' ORDER BY seqno;
@@ -616,6 +617,7 @@ select array_remove(array[1,2,2,3], 2);
616617
select array_remove(array[1,2,2,3], 5);
617618
select array_remove(array[1,NULL,NULL,3], NULL);
618619
select array_remove(array['A','CC','D','C','RR'], 'RR');
620+
select array_remove(array[1.0, 2.1, 3.3], 1);
619621
select array_remove('{{1,2,2},{1,4,3}}', 2); -- not allowed
620622
select array_remove(array['X','X','X'], 'X') = '{}';
621623
select array_replace(array[1,2,5,4],5,3);

src/test/regress/sql/polymorphism.sql

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -498,10 +498,10 @@ select q2, sql_if(q2 > 0, q2, q2 + 1) from int8_tbl;
498498

499499
-- another sort of polymorphic aggregate
500500

501-
CREATE AGGREGATE array_cat_accum (anyarray)
501+
CREATE AGGREGATE array_cat_accum (anycompatiblearray)
502502
(
503503
sfunc = array_cat,
504-
stype = anyarray,
504+
stype = anycompatiblearray,
505505
initcond = '{}'
506506
);
507507

@@ -549,7 +549,7 @@ create aggregate build_group(int8, integer) (
549549

550550
-- check proper resolution of data types for polymorphic transfn/finalfn
551551

552-
create function first_el(anyarray) returns anyelement as
552+
create function first_el(anycompatiblearray) returns anycompatible as
553553
'select $1[1]' language sql strict immutable;
554554

555555
create aggregate first_el_agg_f8(float8) (
@@ -558,9 +558,9 @@ create aggregate first_el_agg_f8(float8) (
558558
FINALFUNC = first_el
559559
);
560560

561-
create aggregate first_el_agg_any(anyelement) (
561+
create aggregate first_el_agg_any(anycompatible) (
562562
SFUNC = array_append,
563-
STYPE = anyarray,
563+
STYPE = anycompatiblearray,
564564
FINALFUNC = first_el
565565
);
566566

0 commit comments

Comments
 (0)