Skip to content

Commit 2d4db36

Browse files
committed
Fix up text concatenation so that it accepts all the reasonable cases that
were accepted by prior Postgres releases. This takes care of the loose end left by the preceding patch to downgrade implicit casts-to-text. To avoid breaking desirable behavior for array concatenation, introduce a new polymorphic pseudo-type "anynonarray" --- the added concatenation operators are actually text || anynonarray and anynonarray || text.
1 parent 7dab4f7 commit 2d4db36

File tree

22 files changed

+301
-109
lines changed

22 files changed

+301
-109
lines changed

doc/src/sgml/datatype.sgml

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.203 2007/06/01 23:40:18 neilc Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.204 2007/06/06 23:00:35 tgl Exp $ -->
22

33
<chapter id="datatype">
44
<title id="datatype-title">Data Types</title>
@@ -3676,12 +3676,16 @@ SELECT * FROM pg_attribute
36763676
<primary>any</primary>
36773677
</indexterm>
36783678

3679+
<indexterm zone="datatype-pseudo">
3680+
<primary>anyelement</primary>
3681+
</indexterm>
3682+
36793683
<indexterm zone="datatype-pseudo">
36803684
<primary>anyarray</primary>
36813685
</indexterm>
36823686

36833687
<indexterm zone="datatype-pseudo">
3684-
<primary>anyelement</primary>
3688+
<primary>anynonarray</primary>
36853689
</indexterm>
36863690

36873691
<indexterm zone="datatype-pseudo">
@@ -3760,6 +3764,12 @@ SELECT * FROM pg_attribute
37603764
<xref linkend="datatype-enum">).</entry>
37613765
</row>
37623766

3767+
<row>
3768+
<entry><type>anynonarray</></entry>
3769+
<entry>Indicates that a function accepts any non-array data type
3770+
(see <xref linkend="extend-types-polymorphic">).</entry>
3771+
</row>
3772+
37633773
<row>
37643774
<entry><type>cstring</></entry>
37653775
<entry>Indicates that a function accepts or returns a null-terminated C string.</entry>
@@ -3813,7 +3823,7 @@ SELECT * FROM pg_attribute
38133823
only <type>void</> and <type>record</> as a result type (plus
38143824
<type>trigger</> when the function is used as a trigger). Some also
38153825
support polymorphic functions using the types <type>anyarray</>,
3816-
<type>anyelement</> and <type>anyenum</>.
3826+
<type>anyelement</>, <type>anyenum</>, and <type>anynonarray</>.
38173827
</para>
38183828

38193829
<para>

doc/src/sgml/extend.sgml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/extend.sgml,v 1.34 2007/04/02 03:49:36 tgl Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/extend.sgml,v 1.35 2007/06/06 23:00:35 tgl Exp $ -->
22

33
<chapter id="extend">
44
<title>Extending <acronym>SQL</acronym></title>
@@ -193,8 +193,8 @@
193193
</indexterm>
194194

195195
<para>
196-
Three pseudo-types of special interest are <type>anyelement</>,
197-
<type>anyarray</>, and <type>anyenum</>,
196+
Four pseudo-types of special interest are <type>anyelement</>,
197+
<type>anyarray</>, <type>anynonarray</>, and <type>anyenum</>,
198198
which are collectively called <firstterm>polymorphic types</>.
199199
Any function declared using these types is said to be
200200
a <firstterm>polymorphic function</>. A polymorphic function can
@@ -216,6 +216,9 @@
216216
<type>anyelement</type>, the actual array type in the
217217
<type>anyarray</type> positions must be an array whose elements are
218218
the same type appearing in the <type>anyelement</type> positions.
219+
<type>anynonarray</> is treated exactly the same as <type>anyelement</>,
220+
but adds the additional constraint that the actual type must not be
221+
an array type.
219222
<type>anyenum</> is treated exactly the same as <type>anyelement</>,
220223
but adds the additional constraint that the actual type must
221224
be an enum type.
@@ -242,6 +245,15 @@
242245
is that a function declared as <literal>f(anyarray) returns anyenum</>
243246
will only accept arrays of enum types.
244247
</para>
248+
249+
<para>
250+
Note that <type>anynonarray</> and <type>anyenum</> do not represent
251+
separate type variables; they are the same type as
252+
<type>anyelement</type>, just with an additional constraint. For
253+
example, declaring a function as <literal>f(anyelement, anyenum)</>
254+
is equivalent to declaring it as <literal>f(anyenum, anyenum)</>:
255+
both actual arguments have to be the same enum type.
256+
</para>
245257
</sect2>
246258
</sect1>
247259

doc/src/sgml/func.sgml

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.381 2007/05/30 18:13:29 momjian Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.382 2007/06/06 23:00:35 tgl Exp $ -->
22

33
<chapter id="functions">
44
<title>Functions and Operators</title>
@@ -986,24 +986,36 @@
986986
<para>
987987
This section describes functions and operators for examining and
988988
manipulating string values. Strings in this context include values
989-
of all the types <type>character</type>, <type>character
990-
varying</type>, and <type>text</type>. Unless otherwise noted, all
989+
of the types <type>character</type>, <type>character varying</type>,
990+
and <type>text</type>. Unless otherwise noted, all
991991
of the functions listed below work on all of these types, but be
992-
wary of potential effects of the automatic padding when using the
993-
<type>character</type> type. Generally, the functions described
994-
here also work on data of non-string types by converting that data
995-
to a string representation first. Some functions also exist
992+
wary of potential effects of automatic space-padding when using the
993+
<type>character</type> type. Some functions also exist
996994
natively for the bit-string types.
997995
</para>
998996

999997
<para>
1000-
<acronym>SQL</acronym> defines some string functions with a special syntax where
1001-
certain key words rather than commas are used to separate the
998+
<acronym>SQL</acronym> defines some string functions with a special syntax
999+
wherein certain key words rather than commas are used to separate the
10021000
arguments. Details are in <xref linkend="functions-string-sql">.
10031001
These functions are also implemented using the regular syntax for
10041002
function invocation. (See <xref linkend="functions-string-other">.)
10051003
</para>
10061004

1005+
<note>
1006+
<para>
1007+
Before <productname>PostgreSQL</productname> 8.3, these functions would
1008+
silently accept values of several non-string data types as well, due to
1009+
the presence of implicit coercions from those data types to
1010+
<type>text</>. Those coercions have been removed because they frequently
1011+
caused surprising behaviors. However, the string concatenation operator
1012+
(<literal>||</>) still accepts non-string input, so long as at least one
1013+
input is of a string type, as shown in <xref
1014+
linkend="functions-string-sql">. For other cases, insert an explicit
1015+
coercion to <type>text</> if you need to duplicate the previous behavior.
1016+
</para>
1017+
</note>
1018+
10071019
<indexterm>
10081020
<primary>bit_length</primary>
10091021
</indexterm>
@@ -1064,6 +1076,22 @@
10641076
<entry><literal>PostgreSQL</literal></entry>
10651077
</row>
10661078

1079+
<row>
1080+
<entry>
1081+
<literal><parameter>string</parameter> <literal>||</literal>
1082+
<parameter>non-string</parameter></literal>
1083+
or
1084+
<literal><parameter>non-string</parameter> <literal>||</literal>
1085+
<parameter>string</parameter></literal>
1086+
</entry>
1087+
<entry> <type>text</type> </entry>
1088+
<entry>
1089+
String concatenation with one non-string input
1090+
</entry>
1091+
<entry><literal>'Value: ' || 42</literal></entry>
1092+
<entry><literal>Value: 42</literal></entry>
1093+
</row>
1094+
10671095
<row>
10681096
<entry><literal><function>bit_length</function>(<parameter>string</parameter>)</literal></entry>
10691097
<entry><type>int</type></entry>

doc/src/sgml/plpgsql.sgml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.109 2007/04/29 01:21:08 neilc Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.110 2007/06/06 23:00:36 tgl Exp $ -->
22

33
<chapter id="plpgsql">
44
<title><application>PL/pgSQL</application> - <acronym>SQL</acronym> Procedural Language</title>
@@ -210,8 +210,8 @@ $$ LANGUAGE plpgsql;
210210
<para>
211211
<application>PL/pgSQL</> functions can also be declared to accept
212212
and return the polymorphic types
213-
<type>anyelement</type>, <type>anyarray</type>, and <type>anyenum</>.
214-
The actual
213+
<type>anyelement</type>, <type>anyarray</type>, <type>anynonarray</type>,
214+
and <type>anyenum</>. The actual
215215
data types handled by a polymorphic function can vary from call to
216216
call, as discussed in <xref linkend="extend-types-polymorphic">.
217217
An example is shown in <xref linkend="plpgsql-declaration-aliases">.
@@ -700,7 +700,7 @@ $$ LANGUAGE plpgsql;
700700
<para>
701701
When the return type of a <application>PL/pgSQL</application>
702702
function is declared as a polymorphic type (<type>anyelement</type>,
703-
<type>anyarray</type>, or <type>anyenum</>),
703+
<type>anyarray</type>, <type>anynonarray</type>, or <type>anyenum</>),
704704
a special parameter <literal>$0</literal>
705705
is created. Its data type is the actual return type of the function,
706706
as deduced from the actual input types (see <xref

doc/src/sgml/xfunc.sgml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.127 2007/04/02 03:49:37 tgl Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.128 2007/06/06 23:00:36 tgl Exp $ -->
22

33
<sect1 id="xfunc">
44
<title>User-Defined Functions</title>
@@ -718,7 +718,8 @@ SELECT name, listchildren(name) FROM nodes;
718718
<para>
719719
<acronym>SQL</acronym> functions can be declared to accept and
720720
return the polymorphic types <type>anyelement</type>,
721-
<type>anyarray</type>, and <type>anyenum</type>. See <xref
721+
<type>anyarray</type>, <type>anynonarray</type>, and
722+
<type>anyenum</type>. See <xref
722723
linkend="extend-types-polymorphic"> for a more detailed
723724
explanation of polymorphic functions. Here is a polymorphic
724725
function <function>make_array</function> that builds up an array
@@ -2831,7 +2832,8 @@ CREATE OR REPLACE FUNCTION retcomposite(IN integer, IN integer,
28312832
<para>
28322833
C-language functions can be declared to accept and
28332834
return the polymorphic types
2834-
<type>anyelement</type>, <type>anyarray</type>, and <type>anyenum</type>.
2835+
<type>anyelement</type>, <type>anyarray</type>, <type>anynonarray</type>,
2836+
and <type>anyenum</type>.
28352837
See <xref linkend="extend-types-polymorphic"> for a more detailed explanation
28362838
of polymorphic functions. When function arguments or return types
28372839
are defined as polymorphic types, the function author cannot know

src/backend/catalog/pg_proc.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.144 2007/04/02 03:49:37 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.145 2007/06/06 23:00:37 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -147,6 +147,7 @@ ProcedureCreate(const char *procedureName,
147147
{
148148
case ANYARRAYOID:
149149
case ANYELEMENTOID:
150+
case ANYNONARRAYOID:
150151
case ANYENUMOID:
151152
genericInParam = true;
152153
break;
@@ -170,6 +171,7 @@ ProcedureCreate(const char *procedureName,
170171
{
171172
case ANYARRAYOID:
172173
case ANYELEMENTOID:
174+
case ANYNONARRAYOID:
173175
case ANYENUMOID:
174176
genericOutParam = true;
175177
break;

src/backend/executor/functions.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.116 2007/04/27 22:05:47 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.117 2007/06/06 23:00:37 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -849,9 +849,9 @@ ShutdownSQLFunction(Datum arg)
849849
* to be sure that the user is returning the type he claims.
850850
*
851851
* For a polymorphic function the passed rettype must be the actual resolved
852-
* output type of the function; we should never see ANYARRAY, ANYENUM or
853-
* ANYELEMENT as rettype. (This means we can't check the type during function
854-
* definition of a polymorphic function.)
852+
* output type of the function; we should never see a polymorphic pseudotype
853+
* such as ANYELEMENT as rettype. (This means we can't check the type during
854+
* function definition of a polymorphic function.)
855855
*
856856
* This function returns true if the sql function returns the entire tuple
857857
* result of its final SELECT, and false otherwise. Note that because we
@@ -874,6 +874,8 @@ check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList,
874874
char fn_typtype;
875875
Oid restype;
876876

877+
AssertArg(!IsPolymorphicType(rettype));
878+
877879
if (junkFilter)
878880
*junkFilter = NULL; /* default result */
879881

src/backend/parser/parse_agg.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/parser/parse_agg.c,v 1.77 2007/02/01 19:10:27 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/parser/parse_agg.c,v 1.78 2007/06/06 23:00:37 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -363,7 +363,7 @@ check_ungrouped_columns_walker(Node *node,
363363
*
364364
* agg_input_types, agg_state_type, agg_result_type identify the input,
365365
* transition, and result types of the aggregate. These should all be
366-
* resolved to actual types (ie, none should ever be ANYARRAY or ANYELEMENT).
366+
* resolved to actual types (ie, none should ever be ANYELEMENT etc).
367367
*
368368
* transfn_oid and finalfn_oid identify the funcs to be called; the latter
369369
* may be InvalidOid.

0 commit comments

Comments
 (0)