mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 00:03:57 -04:00 
			
		
		
		
	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 5c292e6b9 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
This commit is contained in:
		
							parent
							
								
									5c292e6b90
								
							
						
					
					
						commit
						9e38c2bb50
					
				| @ -1756,7 +1756,7 @@ repeat('Pg', 4) <returnvalue>PgPgPgPg</returnvalue> | ||||
| 
 | ||||
|       <row> | ||||
|        <entry role="func_table_entry"><para role="func_signature"> | ||||
|         <function>width_bucket</function> ( <parameter>operand</parameter> <type>anyelement</type>, <parameter>thresholds</parameter> <type>anyarray</type> ) | ||||
|         <function>width_bucket</function> ( <parameter>operand</parameter> <type>anycompatible</type>, <parameter>thresholds</parameter> <type>anycompatiblearray</type> ) | ||||
|        <returnvalue>integer</returnvalue> | ||||
|        </para> | ||||
|        <para> | ||||
| @ -17448,29 +17448,31 @@ SELECT NULLIF(value, '(none)') ... | ||||
| 
 | ||||
|       <row> | ||||
|        <entry role="func_table_entry"><para role="func_signature"> | ||||
|         <type>anyarray</type> <literal>||</literal> <type>anyarray</type> | ||||
|         <returnvalue>anyarray</returnvalue> | ||||
|         <type>anycompatiblearray</type> <literal>||</literal> <type>anycompatiblearray</type> | ||||
|         <returnvalue>anycompatiblearray</returnvalue> | ||||
|        </para> | ||||
|        <para> | ||||
|         Concatenates the two arrays.  Concatenating a null or empty array is a | ||||
|         no-op; otherwise the arrays must have the same number of dimensions | ||||
|         (as illustrated by the first example) or differ in number of | ||||
|         dimensions by one (as illustrated by the second). | ||||
|         If the arrays are not of identical element types, they will be coerced | ||||
|         to a common type (see <xref linkend="typeconv-union-case"/>). | ||||
|        </para> | ||||
|        <para> | ||||
|         <literal>ARRAY[1,2,3] || ARRAY[4,5,6,7]</literal> | ||||
|         <returnvalue>{1,2,3,4,5,6,7}</returnvalue> | ||||
|        </para> | ||||
|        <para> | ||||
|         <literal>ARRAY[1,2,3] || ARRAY[[4,5,6],[7,8,9]]</literal> | ||||
|         <returnvalue>{{1,2,3},{4,5,6},{7,8,9}}</returnvalue> | ||||
|         <literal>ARRAY[1,2,3] || ARRAY[[4,5,6],[7,8,9.9]]</literal> | ||||
|         <returnvalue>{{1,2,3},{4,5,6},{7,8,9.9}}</returnvalue> | ||||
|        </para></entry> | ||||
|       </row> | ||||
| 
 | ||||
|       <row> | ||||
|        <entry role="func_table_entry"><para role="func_signature"> | ||||
|         <type>anyelement</type> <literal>||</literal> <type>anyarray</type> | ||||
|         <returnvalue>anyarray</returnvalue> | ||||
|         <type>anycompatible</type> <literal>||</literal> <type>anycompatiblearray</type> | ||||
|         <returnvalue>anycompatiblearray</returnvalue> | ||||
|        </para> | ||||
|        <para> | ||||
|         Concatenates an element onto the front of an array (which must be | ||||
| @ -17484,8 +17486,8 @@ SELECT NULLIF(value, '(none)') ... | ||||
| 
 | ||||
|       <row> | ||||
|        <entry role="func_table_entry"><para role="func_signature"> | ||||
|         <type>anyarray</type> <literal>||</literal> <type>anyelement</type> | ||||
|         <returnvalue>anyarray</returnvalue> | ||||
|         <type>anycompatiblearray</type> <literal>||</literal> <type>anycompatible</type> | ||||
|         <returnvalue>anycompatiblearray</returnvalue> | ||||
|        </para> | ||||
|        <para> | ||||
|         Concatenates an element onto the end of an array (which must be | ||||
| @ -17535,12 +17537,12 @@ SELECT NULLIF(value, '(none)') ... | ||||
|         <indexterm> | ||||
|          <primary>array_append</primary> | ||||
|         </indexterm> | ||||
|         <function>array_append</function> ( <type>anyarray</type>, <type>anyelement</type> ) | ||||
|         <returnvalue>anyarray</returnvalue> | ||||
|         <function>array_append</function> ( <type>anycompatiblearray</type>, <type>anycompatible</type> ) | ||||
|         <returnvalue>anycompatiblearray</returnvalue> | ||||
|        </para> | ||||
|        <para> | ||||
|         Appends an element to the end of an array (same as | ||||
|         the <type>anyarray</type> <literal>||</literal> <type>anyelement</type> | ||||
|         the <type>anycompatiblearray</type> <literal>||</literal> <type>anycompatible</type> | ||||
|         operator). | ||||
|        </para> | ||||
|        <para> | ||||
| @ -17554,12 +17556,12 @@ SELECT NULLIF(value, '(none)') ... | ||||
|         <indexterm> | ||||
|          <primary>array_cat</primary> | ||||
|         </indexterm> | ||||
|         <function>array_cat</function> ( <type>anyarray</type>, <type>anyarray</type> ) | ||||
|         <returnvalue>anyarray</returnvalue> | ||||
|         <function>array_cat</function> ( <type>anycompatiblearray</type>, <type>anycompatiblearray</type> ) | ||||
|         <returnvalue>anycompatiblearray</returnvalue> | ||||
|        </para> | ||||
|        <para> | ||||
|         Concatenates two arrays (same as | ||||
|         the <type>anyarray</type> <literal>||</literal> <type>anyarray</type> | ||||
|         the <type>anycompatiblearray</type> <literal>||</literal> <type>anycompatiblearray</type> | ||||
|         operator). | ||||
|        </para> | ||||
|        <para> | ||||
| @ -17666,7 +17668,7 @@ SELECT NULLIF(value, '(none)') ... | ||||
|         <indexterm> | ||||
|          <primary>array_position</primary> | ||||
|         </indexterm> | ||||
|         <function>array_position</function> ( <type>anyarray</type>, <type>anyelement</type> <optional>, <type>integer</type> </optional> ) | ||||
|         <function>array_position</function> ( <type>anycompatiblearray</type>, <type>anycompatible</type> <optional>, <type>integer</type> </optional> ) | ||||
|         <returnvalue>integer</returnvalue> | ||||
|        </para> | ||||
|        <para> | ||||
| @ -17688,7 +17690,7 @@ SELECT NULLIF(value, '(none)') ... | ||||
|         <indexterm> | ||||
|          <primary>array_positions</primary> | ||||
|         </indexterm> | ||||
|         <function>array_positions</function> ( <type>anyarray</type>, <type>anyelement</type> ) | ||||
|         <function>array_positions</function> ( <type>anycompatiblearray</type>, <type>anycompatible</type> ) | ||||
|         <returnvalue>integer[]</returnvalue> | ||||
|        </para> | ||||
|        <para> | ||||
| @ -17712,12 +17714,12 @@ SELECT NULLIF(value, '(none)') ... | ||||
|         <indexterm> | ||||
|          <primary>array_prepend</primary> | ||||
|         </indexterm> | ||||
|         <function>array_prepend</function> ( <type>anyelement</type>, <type>anyarray</type> ) | ||||
|         <returnvalue>anyarray</returnvalue> | ||||
|         <function>array_prepend</function> ( <type>anycompatible</type>, <type>anycompatiblearray</type> ) | ||||
|         <returnvalue>anycompatiblearray</returnvalue> | ||||
|        </para> | ||||
|        <para> | ||||
|         Prepends an element to the beginning of an array (same as | ||||
|         the <type>anyelement</type> <literal>||</literal> <type>anyarray</type> | ||||
|         the <type>anycompatible</type> <literal>||</literal> <type>anycompatiblearray</type> | ||||
|         operator). | ||||
|        </para> | ||||
|        <para> | ||||
| @ -17731,8 +17733,8 @@ SELECT NULLIF(value, '(none)') ... | ||||
|         <indexterm> | ||||
|          <primary>array_remove</primary> | ||||
|         </indexterm> | ||||
|         <function>array_remove</function> ( <type>anyarray</type>, <type>anyelement</type> ) | ||||
|         <returnvalue>anyarray</returnvalue> | ||||
|         <function>array_remove</function> ( <type>anycompatiblearray</type>, <type>anycompatible</type> ) | ||||
|         <returnvalue>anycompatiblearray</returnvalue> | ||||
|        </para> | ||||
|        <para> | ||||
|         Removes all elements equal to the given value from the array. | ||||
| @ -17751,8 +17753,8 @@ SELECT NULLIF(value, '(none)') ... | ||||
|         <indexterm> | ||||
|          <primary>array_replace</primary> | ||||
|         </indexterm> | ||||
|         <function>array_replace</function> ( <type>anyarray</type>, <type>anyelement</type>, <type>anyelement</type> ) | ||||
|         <returnvalue>anyarray</returnvalue> | ||||
|         <function>array_replace</function> ( <type>anycompatiblearray</type>, <type>anycompatible</type>, <type>anycompatible</type> ) | ||||
|         <returnvalue>anycompatiblearray</returnvalue> | ||||
|        </para> | ||||
|        <para> | ||||
|         Replaces each array element equal to the second argument with the | ||||
|  | ||||
| @ -298,10 +298,10 @@ FROM (VALUES (1, 1.0e20::float8), | ||||
|    Here is an example of a polymorphic aggregate: | ||||
| 
 | ||||
| <programlisting> | ||||
| CREATE AGGREGATE array_accum (anyelement) | ||||
| CREATE AGGREGATE array_accum (anycompatible) | ||||
| ( | ||||
|     sfunc = array_append, | ||||
|     stype = anyarray, | ||||
|     stype = anycompatiblearray, | ||||
|     initcond = '{}' | ||||
| ); | ||||
| </programlisting> | ||||
|  | ||||
| @ -53,6 +53,6 @@ | ||||
|  */ | ||||
| 
 | ||||
| /*							yyyymmddN */ | ||||
| #define CATALOG_VERSION_NO	202011043 | ||||
| #define CATALOG_VERSION_NO	202011044 | ||||
| 
 | ||||
| #endif | ||||
|  | ||||
| @ -168,14 +168,15 @@ | ||||
|   oprcode => 'textnename', oprrest => 'neqsel', oprjoin => 'neqjoinsel' }, | ||||
| 
 | ||||
| { oid => '349', descr => 'append element onto end of array', | ||||
|   oprname => '||', oprleft => 'anyarray', oprright => 'anyelement', | ||||
|   oprresult => 'anyarray', oprcode => 'array_append' }, | ||||
|   oprname => '||', oprleft => 'anycompatiblearray', oprright => 'anycompatible', | ||||
|   oprresult => 'anycompatiblearray', oprcode => 'array_append' }, | ||||
| { oid => '374', descr => 'prepend element onto front of array', | ||||
|   oprname => '||', oprleft => 'anyelement', oprright => 'anyarray', | ||||
|   oprresult => 'anyarray', oprcode => 'array_prepend' }, | ||||
|   oprname => '||', oprleft => 'anycompatible', oprright => 'anycompatiblearray', | ||||
|   oprresult => 'anycompatiblearray', oprcode => 'array_prepend' }, | ||||
| { oid => '375', descr => 'concatenate', | ||||
|   oprname => '||', oprleft => 'anyarray', oprright => 'anyarray', | ||||
|   oprresult => 'anyarray', oprcode => 'array_cat' }, | ||||
|   oprname => '||', oprleft => 'anycompatiblearray', | ||||
|   oprright => 'anycompatiblearray', oprresult => 'anycompatiblearray', | ||||
|   oprcode => 'array_cat' }, | ||||
| 
 | ||||
| { oid => '352', descr => 'equal', | ||||
|   oprname => '=', oprcanhash => 't', oprleft => 'xid', oprright => 'xid', | ||||
|  | ||||
| @ -1548,14 +1548,19 @@ | ||||
|   proname => 'cardinality', prorettype => 'int4', proargtypes => 'anyarray', | ||||
|   prosrc => 'array_cardinality' }, | ||||
| { oid => '378', descr => 'append element onto end of array', | ||||
|   proname => 'array_append', proisstrict => 'f', prorettype => 'anyarray', | ||||
|   proargtypes => 'anyarray anyelement', prosrc => 'array_append' }, | ||||
|   proname => 'array_append', proisstrict => 'f', | ||||
|   prorettype => 'anycompatiblearray', | ||||
|   proargtypes => 'anycompatiblearray anycompatible', prosrc => 'array_append' }, | ||||
| { oid => '379', descr => 'prepend element onto front of array', | ||||
|   proname => 'array_prepend', proisstrict => 'f', prorettype => 'anyarray', | ||||
|   proargtypes => 'anyelement anyarray', prosrc => 'array_prepend' }, | ||||
|   proname => 'array_prepend', proisstrict => 'f', | ||||
|   prorettype => 'anycompatiblearray', | ||||
|   proargtypes => 'anycompatible anycompatiblearray', | ||||
|   prosrc => 'array_prepend' }, | ||||
| { oid => '383', | ||||
|   proname => 'array_cat', proisstrict => 'f', prorettype => 'anyarray', | ||||
|   proargtypes => 'anyarray anyarray', prosrc => 'array_cat' }, | ||||
|   proname => 'array_cat', proisstrict => 'f', | ||||
|   prorettype => 'anycompatiblearray', | ||||
|   proargtypes => 'anycompatiblearray anycompatiblearray', | ||||
|   prosrc => 'array_cat' }, | ||||
| { oid => '394', descr => 'split delimited text', | ||||
|   proname => 'string_to_array', proisstrict => 'f', prorettype => '_text', | ||||
|   proargtypes => 'text text', prosrc => 'text_to_array' }, | ||||
| @ -1587,15 +1592,18 @@ | ||||
|   proargtypes => 'anyarray anyarray', prosrc => 'array_smaller' }, | ||||
| { oid => '3277', descr => 'returns an offset of value in array', | ||||
|   proname => 'array_position', proisstrict => 'f', prorettype => 'int4', | ||||
|   proargtypes => 'anyarray anyelement', prosrc => 'array_position' }, | ||||
|   proargtypes => 'anycompatiblearray anycompatible', | ||||
|   prosrc => 'array_position' }, | ||||
| { oid => '3278', | ||||
|   descr => 'returns an offset of value in array with start index', | ||||
|   proname => 'array_position', proisstrict => 'f', prorettype => 'int4', | ||||
|   proargtypes => 'anyarray anyelement int4', prosrc => 'array_position_start' }, | ||||
|   proargtypes => 'anycompatiblearray anycompatible int4', | ||||
|   prosrc => 'array_position_start' }, | ||||
| { oid => '3279', | ||||
|   descr => 'returns an array of offsets of some value in array', | ||||
|   proname => 'array_positions', proisstrict => 'f', prorettype => '_int4', | ||||
|   proargtypes => 'anyarray anyelement', prosrc => 'array_positions' }, | ||||
|   proargtypes => 'anycompatiblearray anycompatible', | ||||
|   prosrc => 'array_positions' }, | ||||
| { oid => '1191', descr => 'array subscripts generator', | ||||
|   proname => 'generate_subscripts', prorows => '1000', proretset => 't', | ||||
|   prorettype => 'int4', proargtypes => 'anyarray int4 bool', | ||||
| @ -1620,11 +1628,14 @@ | ||||
|   proargtypes => 'internal', prosrc => 'array_unnest_support' }, | ||||
| { oid => '3167', | ||||
|   descr => 'remove any occurrences of an element from an array', | ||||
|   proname => 'array_remove', proisstrict => 'f', prorettype => 'anyarray', | ||||
|   proargtypes => 'anyarray anyelement', prosrc => 'array_remove' }, | ||||
|   proname => 'array_remove', proisstrict => 'f', | ||||
|   prorettype => 'anycompatiblearray', | ||||
|   proargtypes => 'anycompatiblearray anycompatible', prosrc => 'array_remove' }, | ||||
| { oid => '3168', descr => 'replace any occurrences of an element in an array', | ||||
|   proname => 'array_replace', proisstrict => 'f', prorettype => 'anyarray', | ||||
|   proargtypes => 'anyarray anyelement anyelement', prosrc => 'array_replace' }, | ||||
|   proname => 'array_replace', proisstrict => 'f', | ||||
|   prorettype => 'anycompatiblearray', | ||||
|   proargtypes => 'anycompatiblearray anycompatible anycompatible', | ||||
|   prosrc => 'array_replace' }, | ||||
| { oid => '2333', descr => 'aggregate transition function', | ||||
|   proname => 'array_agg_transfn', proisstrict => 'f', prorettype => 'internal', | ||||
|   proargtypes => 'internal anynonarray', prosrc => 'array_agg_transfn' }, | ||||
| @ -1650,7 +1661,8 @@ | ||||
| { oid => '3218', | ||||
|   descr => 'bucket number of operand given a sorted array of bucket lower bounds', | ||||
|   proname => 'width_bucket', prorettype => 'int4', | ||||
|   proargtypes => 'anyelement anyarray', prosrc => 'width_bucket_array' }, | ||||
|   proargtypes => 'anycompatible anycompatiblearray', | ||||
|   prosrc => 'width_bucket_array' }, | ||||
| { oid => '3816', descr => 'array typanalyze', | ||||
|   proname => 'array_typanalyze', provolatile => 's', prorettype => 'bool', | ||||
|   proargtypes => 'internal', prosrc => 'array_typanalyze' }, | ||||
|  | ||||
| @ -726,6 +726,12 @@ SELECT 0 || ARRAY[1,2] || 3 AS "{0,1,2,3}"; | ||||
|  {0,1,2,3} | ||||
| (1 row) | ||||
| 
 | ||||
| SELECT ARRAY[1.1] || ARRAY[2,3,4]; | ||||
|   ?column?    | ||||
| ------------- | ||||
|  {1.1,2,3,4} | ||||
| (1 row) | ||||
| 
 | ||||
| SELECT * FROM array_op_test WHERE i @> '{32}' ORDER BY seqno; | ||||
|  seqno |                i                |                                                                 t                                                                   | ||||
| -------+---------------------------------+------------------------------------------------------------------------------------------------------------------------------------ | ||||
| @ -2146,6 +2152,12 @@ select array_remove(array['A','CC','D','C','RR'], 'RR'); | ||||
|  {A,CC,D,C} | ||||
| (1 row) | ||||
| 
 | ||||
| select array_remove(array[1.0, 2.1, 3.3], 1); | ||||
|  array_remove  | ||||
| -------------- | ||||
|  {2.1,3.3} | ||||
| (1 row) | ||||
| 
 | ||||
| select array_remove('{{1,2,2},{1,4,3}}', 2); -- not allowed | ||||
| ERROR:  removing elements from multidimensional arrays is not supported | ||||
| select array_remove(array['X','X','X'], 'X') = '{}'; | ||||
|  | ||||
| @ -729,10 +729,10 @@ select q2, sql_if(q2 > 0, q2, q2 + 1) from int8_tbl; | ||||
| (5 rows) | ||||
| 
 | ||||
| -- another sort of polymorphic aggregate | ||||
| CREATE AGGREGATE array_cat_accum (anyarray) | ||||
| CREATE AGGREGATE array_cat_accum (anycompatiblearray) | ||||
| ( | ||||
|     sfunc = array_cat, | ||||
|     stype = anyarray, | ||||
|     stype = anycompatiblearray, | ||||
|     initcond = '{}' | ||||
| ); | ||||
| SELECT array_cat_accum(i) | ||||
| @ -786,16 +786,16 @@ create aggregate build_group(int8, integer) ( | ||||
|   STYPE = int8[] | ||||
| ); | ||||
| -- check proper resolution of data types for polymorphic transfn/finalfn | ||||
| create function first_el(anyarray) returns anyelement as | ||||
| create function first_el(anycompatiblearray) returns anycompatible as | ||||
| 'select $1[1]' language sql strict immutable; | ||||
| create aggregate first_el_agg_f8(float8) ( | ||||
|   SFUNC = array_append, | ||||
|   STYPE = float8[], | ||||
|   FINALFUNC = first_el | ||||
| ); | ||||
| create aggregate first_el_agg_any(anyelement) ( | ||||
| create aggregate first_el_agg_any(anycompatible) ( | ||||
|   SFUNC = array_append, | ||||
|   STYPE = anyarray, | ||||
|   STYPE = anycompatiblearray, | ||||
|   FINALFUNC = first_el | ||||
| ); | ||||
| select first_el_agg_f8(x::float8) from generate_series(1,10) x; | ||||
|  | ||||
| @ -311,6 +311,7 @@ SELECT ARRAY[[['hello','world']]] || ARRAY[[['happy','birthday']]] AS "ARRAY"; | ||||
| SELECT ARRAY[[1,2],[3,4]] || ARRAY[5,6] AS "{{1,2},{3,4},{5,6}}"; | ||||
| SELECT ARRAY[0,0] || ARRAY[1,1] || ARRAY[2,2] AS "{0,0,1,1,2,2}"; | ||||
| SELECT 0 || ARRAY[1,2] || 3 AS "{0,1,2,3}"; | ||||
| SELECT ARRAY[1.1] || ARRAY[2,3,4]; | ||||
| 
 | ||||
| SELECT * FROM array_op_test WHERE i @> '{32}' ORDER BY seqno; | ||||
| SELECT * FROM array_op_test WHERE i && '{32}' ORDER BY seqno; | ||||
| @ -616,6 +617,7 @@ select array_remove(array[1,2,2,3], 2); | ||||
| select array_remove(array[1,2,2,3], 5); | ||||
| select array_remove(array[1,NULL,NULL,3], NULL); | ||||
| select array_remove(array['A','CC','D','C','RR'], 'RR'); | ||||
| select array_remove(array[1.0, 2.1, 3.3], 1); | ||||
| select array_remove('{{1,2,2},{1,4,3}}', 2); -- not allowed | ||||
| select array_remove(array['X','X','X'], 'X') = '{}'; | ||||
| select array_replace(array[1,2,5,4],5,3); | ||||
|  | ||||
| @ -498,10 +498,10 @@ select q2, sql_if(q2 > 0, q2, q2 + 1) from int8_tbl; | ||||
| 
 | ||||
| -- another sort of polymorphic aggregate | ||||
| 
 | ||||
| CREATE AGGREGATE array_cat_accum (anyarray) | ||||
| CREATE AGGREGATE array_cat_accum (anycompatiblearray) | ||||
| ( | ||||
|     sfunc = array_cat, | ||||
|     stype = anyarray, | ||||
|     stype = anycompatiblearray, | ||||
|     initcond = '{}' | ||||
| ); | ||||
| 
 | ||||
| @ -549,7 +549,7 @@ create aggregate build_group(int8, integer) ( | ||||
| 
 | ||||
| -- check proper resolution of data types for polymorphic transfn/finalfn | ||||
| 
 | ||||
| create function first_el(anyarray) returns anyelement as | ||||
| create function first_el(anycompatiblearray) returns anycompatible as | ||||
| 'select $1[1]' language sql strict immutable; | ||||
| 
 | ||||
| create aggregate first_el_agg_f8(float8) ( | ||||
| @ -558,9 +558,9 @@ create aggregate first_el_agg_f8(float8) ( | ||||
|   FINALFUNC = first_el | ||||
| ); | ||||
| 
 | ||||
| create aggregate first_el_agg_any(anyelement) ( | ||||
| create aggregate first_el_agg_any(anycompatible) ( | ||||
|   SFUNC = array_append, | ||||
|   STYPE = anyarray, | ||||
|   STYPE = anycompatiblearray, | ||||
|   FINALFUNC = first_el | ||||
| ); | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user