pg.ddx.io  pgsql-bugs@postgresql.org mailing list archive  
help / color / mirror / Atom feed
Inconsistent cast to "char"
5+ messages / 2 participants
[nested] [flat]

* Inconsistent cast to "char"
@ 2021-12-02 16:24  Ian R. Campbell <ian.campbell@thepathcentral.com>
  0 siblings, 1 reply; 5+ messages in thread

From: Ian R. Campbell @ 2021-12-02 16:24 UTC (permalink / raw)
  To: pgsql-bugs@lists.postgresql.org

I noticed that the following does not produce consistent cast results:

select 1::int8::"char", 1::int4::"char", 1::int2::"char"

The following yields 49, 1, 49 respectively:

select 1::int8::"char"::int, 1::int4::"char"::int, 1::int2::"char"::int

regards,
Ian Campbell

^ permalink  raw  reply  [nested|flat] 5+ messages in thread

* Re: Inconsistent cast to "char"
@ 2021-12-02 18:50  Tom Lane <tgl@sss.pgh.pa.us>
  parent: Ian R. Campbell <ian.campbell@thepathcentral.com>
  0 siblings, 1 reply; 5+ messages in thread

From: Tom Lane @ 2021-12-02 18:50 UTC (permalink / raw)
  To: Ian R. Campbell <ian.campbell@thepathcentral.com>; +Cc: pgsql-bugs@lists.postgresql.org

"Ian R. Campbell" <ian.campbell@thepathcentral.com> writes:
> I noticed that the following does not produce consistent cast results:
> select 1::int8::"char", 1::int4::"char", 1::int2::"char"

Concretely, that gives:

regression=# select 1::int8::"char", 1::int4::"char", 1::int2::"char";
 char | char | char 
------+------+------
 1    | \x01 | 1
(1 row)

The reason for this is that there's a bespoke int4-to-"char" cast,
which just produces the character with that code point; this is
documented as the "char"(int) function.  However, there are no
such bespoke casts for int2 or int8, so those go via cast-via-I/O,
much as if you were casting to/from text.  The same happens with
numeric, or indeed other types.

One possible answer to this is to reclassify "char" as not being
a member of the "string" category, so that the implicit-I/O-cast
rule wouldn't be applied to it.  I'm not sure if that'd have
any downsides, but it seems like in principle it might be all
right.  "char" is so restricted that treating it as a general-
purpose string type doesn't seem very sane.

(Now that I look, I see that somebody thought that it'd be cool
to assign category S to various special-purpose types like
pg_mcv_list.  That seems downright dangerous.)

			regards, tom lane





^ permalink  raw  reply  [nested|flat] 5+ messages in thread

* Re: Inconsistent cast to "char"
@ 2021-12-02 18:53  Ian R. Campbell <ian.campbell@thepathcentral.com>
  parent: Tom Lane <tgl@sss.pgh.pa.us>
  0 siblings, 1 reply; 5+ messages in thread

From: Ian R. Campbell @ 2021-12-02 18:53 UTC (permalink / raw)
  To: Tom Lane <tgl@sss.pgh.pa.us>; +Cc: pgsql-bugs@lists.postgresql.org

It makes sense that "char" is not part of the string family. After all,
"char" != char.

In the scenarios I give, one would expect the same output for all integer
width casting inputs, so you have my vote on the change you suggested.

On Thu, 2 Dec 2021 at 20:50, Tom Lane <tgl@sss.pgh.pa.us> wrote:

> "Ian R. Campbell" <ian.campbell@thepathcentral.com> writes:
> > I noticed that the following does not produce consistent cast results:
> > select 1::int8::"char", 1::int4::"char", 1::int2::"char"
>
> Concretely, that gives:
>
> regression=# select 1::int8::"char", 1::int4::"char", 1::int2::"char";
>  char | char | char
> ------+------+------
>  1    | \x01 | 1
> (1 row)
>
> The reason for this is that there's a bespoke int4-to-"char" cast,
> which just produces the character with that code point; this is
> documented as the "char"(int) function.  However, there are no
> such bespoke casts for int2 or int8, so those go via cast-via-I/O,
> much as if you were casting to/from text.  The same happens with
> numeric, or indeed other types.
>
> One possible answer to this is to reclassify "char" as not being
> a member of the "string" category, so that the implicit-I/O-cast
> rule wouldn't be applied to it.  I'm not sure if that'd have
> any downsides, but it seems like in principle it might be all
> right.  "char" is so restricted that treating it as a general-
> purpose string type doesn't seem very sane.
>
> (Now that I look, I see that somebody thought that it'd be cool
> to assign category S to various special-purpose types like
> pg_mcv_list.  That seems downright dangerous.)
>
>                         regards, tom lane
>

^ permalink  raw  reply  [nested|flat] 5+ messages in thread

* Re: Inconsistent cast to "char"
@ 2021-12-02 19:27  Tom Lane <tgl@sss.pgh.pa.us>
  parent: Ian R. Campbell <ian.campbell@thepathcentral.com>
  0 siblings, 1 reply; 5+ messages in thread

From: Tom Lane @ 2021-12-02 19:27 UTC (permalink / raw)
  To: Ian R. Campbell <ian.campbell@thepathcentral.com>; +Cc: pgsql-bugs@lists.postgresql.org

"Ian R. Campbell" <ian.campbell@thepathcentral.com> writes:
> It makes sense that "char" is not part of the string family. After all,
> "char" != char.

If it allowed more than one byte, maybe you could call it a "string",
but it seems hard to justify without that.

> In the scenarios I give, one would expect the same output for all integer
> width casting inputs, so you have my vote on the change you suggested.

To be clear, the change I'm thinking of would result in errors, not in
silently applying the int4 cast.  As a quick-n-dirty test:

regression=# update pg_type set typcategory = 'x' where typname = 'char';
UPDATE 1
regression=# select 1::int8::"char", 1::int4::"char", 1::int2::"char";
ERROR:  cannot cast type bigint to "char"
LINE 1: select 1::int8::"char", 1::int4::"char", 1::int2::"char";
                      ^

			regards, tom lane





^ permalink  raw  reply  [nested|flat] 5+ messages in thread

* Re: Inconsistent cast to "char"
@ 2021-12-02 21:31  Tom Lane <tgl@sss.pgh.pa.us>
  parent: Tom Lane <tgl@sss.pgh.pa.us>
  0 siblings, 0 replies; 5+ messages in thread

From: Tom Lane @ 2021-12-02 21:31 UTC (permalink / raw)
  To: Ian R. Campbell <ian.campbell@thepathcentral.com>; +Cc: pgsql-bugs@lists.postgresql.org

I wrote:
> To be clear, the change I'm thinking of would result in errors, not in
> silently applying the int4 cast.  As a quick-n-dirty test:

> regression=# update pg_type set typcategory = 'x' where typname = 'char';
> UPDATE 1
> regression=# select 1::int8::"char", 1::int4::"char", 1::int2::"char";
> ERROR:  cannot cast type bigint to "char"
> LINE 1: select 1::int8::"char", 1::int4::"char", 1::int2::"char";
>                       ^

It turns out that changing the typcategory does have some undesirable
side-effects, but I found another possible workaround.  Patch
posted at [1].

			regards, tom lane

[1] https://www.postgresql.org/message-id/2216388.1638480141%40sss.pgh.pa.us





^ permalink  raw  reply  [nested|flat] 5+ messages in thread


end of thread, other threads:[~2021-12-02 21:31 UTC | newest]

Thread overview: 5+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2021-12-02 16:24 Inconsistent cast to "char" Ian R. Campbell <ian.campbell@thepathcentral.com>
2021-12-02 18:50 ` Tom Lane <tgl@sss.pgh.pa.us>
2021-12-02 18:53   ` Ian R. Campbell <ian.campbell@thepathcentral.com>
2021-12-02 19:27     ` Tom Lane <tgl@sss.pgh.pa.us>
2021-12-02 21:31       ` Tom Lane <tgl@sss.pgh.pa.us>

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox