Re: Implicit casts with generic arrays

Tom Lane <tgl@sss.pgh.pa.us>

From: Tom Lane <tgl@sss.pgh.pa.us>
To: Alvaro Herrera <alvherre@commandprompt.com>
Cc: Joe Conway <mail@joeconway.com>, Peter Eisentraut <peter_e@gmx.net>, pgsql-hackers@postgresql.org
Date: 2007-06-06T21:03:52Z
Lists: pgsql-hackers
Alvaro Herrera <alvherre@commandprompt.com> writes:
> Tom Lane wrote:
>> It looks to me like we could eliminate the conflict if we invented a new
>> polymorphic pseudotype called "anynonarray" or some such, which would
>> act like anyelement *except* it would not match an array.
> ...
> On the contrary, I would think that it fits nicely to "close the loop"
> on the anyarray/anyelement feature set.

OK, I hacked this together and it seems to behave at least as reasonably
as 8.2 does.  "8.3" here means HEAD + anynonarray + capturing concat
operators.  I used integer as an example of a type for which 8.2 has an
implicit cast to text, and point as an example of a type for which it
doesn't:

Expression			8.3		8.2

text || text			text concat	text concat
text || 'unknown'		text concat	text concat
text || text[]			array concat	array concat
text || non-text array		error		error
text || non-text scalar		text concat	text concat [1]

integer || integer		error		text concat
integer || 'unknown'		text concat	text concat
integer || integer[]		array concat	array concat
integer || non-integer array	error		error
integer || non-integer scalar	error		text concat [1]

point || point			error		error
point || 'unknown'		text concat	'array value must start ...'
point || point[]		array concat	array concat
point || non-point array	error		error
point || non-point scalar	error		error

text[] || text[]		array concat	array concat
text[] || 'unknown'		error		error
text[] || non-text array	error		error
text[] || non-text scalar	error		error

[1] for types for which 8.2 has an implicit cast to text, else it fails.
These are:
 bigint
 smallint
 integer
 oid
 real
 double precision
 numeric
 date
 time without time zone
 time with time zone
 timestamp without time zone
 timestamp with time zone
 interval

(I was interested to find that there were cases where 8.2 would come out
with the dreaded "array value must start with "{" or dimension
information" error.)

I think that the above chart is pretty defensible; the only cases that
fail now where they worked before are concatenations where neither side
is either text or an unadorned string literal.  Frankly, I think this:

catany=# select 3 || 0.4;
ERROR:  operator does not exist: integer || numeric

is way preferable to this:

regression=# select 3 || 0.4;
 ?column?
----------
 30.4
(1 row)

which is what 8.2 does --- if you want text concatenation you should
make at least *some* effort to signal that, like casting one side to
text or at least quoting it.  Run-together concatenations like

catany=# select 'sin(' || 2 || ')';
 ?column?
----------
 sin(2)
(1 row)

will work as long as at least one of the first two concatenated items is
textual or an unadorned string literal.

Barring objections I'll clean this up and commit it.

			regards, tom lane