Re: BUG #5028: CASE returns ELSE value always when type is "char" - Mailing list pgsql-bugs

From Sam Mason
Subject Re: BUG #5028: CASE returns ELSE value always when type is "char"
Date
Msg-id 20090904170329.GD5407@samason.me.uk
Whole thread Raw
In response to Re: BUG #5028: CASE returns ELSE value always when type is "char"  ("Kevin Grittner" <Kevin.Grittner@wicourts.gov>)
Responses Re: BUG #5028: CASE returns ELSE value always when type is "char"  ("Kevin Grittner" <Kevin.Grittner@wicourts.gov>)
List pgsql-bugs
On Fri, Sep 04, 2009 at 10:59:48AM -0500, Kevin Grittner wrote:
> Tom Lane <tgl@sss.pgh.pa.us> wrote:
> > I certainly don't want to have "char" emulate the misbegotten
> > decision to have explicit and implicit coercions behave differently.
> > So it looks to me like the argument to make "char" work like char(1)
> > doesn't actually help us much to decide if an error should be thrown
> > here or not.  On the whole, throwing an error seems better from a
> > usability perspective.

I'm all for the error being thrown; no particular feelings about whether
it only happens during "explicit" casts or everywhere.  There's always
the substring() function if the user wants it.

> I feel that the behavior of "char" in at least this case should match
> char(1) (or just plain char):

Hum, I'm not sure if that's useful behavior.  As far as I can tell, you
seem to be wanting in-memory representations of "string like types"
to all use the same representation and only use the actual types when
saving to/from disk.  This would give behavior that is consistent with
what you're for asking below.

> test=# select case when true then 'xxx' else 'a'::"char" end from t;
>  case
> ------
>  x
> (1 row)

With the patch I gave, or something like it, this would throw an error
because 'xxx' is being used to initialize a value of "char" type.

> test=# select case when true then 'xxx' else 'a'::char(1) end from t;
>  case
> ------
>  xxx
> (1 row)

This gives back 'xxx' because the types character and bpchar have an
implicit cast defined between them.  The result is thus of type bpchar
which places no restrictions on the length (that would apply here
anyway), with 'a' being cast from character to bpchar implicitly.

> test=# select case when true then 'xxx' else 'a'::char end from t;
>  case
> ------
>  xxx
> (1 row)

This does the same as above.

> Much as the reason for the behavior of "char" may seem clear when
> inside the code looking out, it is astonishing for someone writing
> application code.

I think things would be clearer if an error was thrown in the
constructor of "char" types when the length wasn't correct.  Implicit
casts are muddying the waters as well, which doesn't aid understanding
of what's going on here.

--
  Sam  http://samason.me.uk/

pgsql-bugs by date:

Previous
From: Robert Haas
Date:
Subject: Re: BUG #5028: CASE returns ELSE value always when type is "char"
Next
From: Alvaro Herrera
Date:
Subject: Re: BUG #5035: cast 'text' to 'name' doesnt work in plpgsql function