Thread: [HACKERS] CAST vs ::

[HACKERS] CAST vs ::

From
Tom Lane
Date:
In most places, you can write CAST(x AS t) and x::t interchangeably.
But that doesn't work for function-in-FROM.  This is OK:

select * from cast(fdc() as complex);

but this is not:

select * from fdc()::complex;
ERROR:  syntax error at or near "::"

I just realized that this is a problem for ruleutils.c, which thinks
it can always use the short form:

regression=# create view vv as select * from cast(fdc() as complex);
CREATE VIEW
regression=# \d+ vv                                 View "public.vv"Column |       Type       | Collation | Nullable |
Default| Storage | Descript 
ion
--------+------------------+-----------+----------+---------+---------+---------
----r      | double precision |           |          |         | plain   | i      | double precision |           |
   |         | plain   |  
View definition:SELECT fdc.r,   fdc.i  FROM fdc()::complex fdc(r, i);

That view definition will not reload.

Not sure about the most reasonable fix.  It might be possible to tweak
the grammar to allow this case, but I'm not at all sure about that.
An easy fix would be to make ruleutils print casts as CAST() all the
time, but that would probably annoy a lot of people (it'd certainly
break a lot of regression tests).  Maybe we can hack ruleutils to use
the CAST syntax only in this specific context.
        regards, tom lane



Re: [HACKERS] CAST vs ::

From
"David G. Johnston"
Date:
On Thursday, July 13, 2017, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Maybe we can hack ruleutils to use
the CAST syntax only in this specific context.

Given the lack of complaints, and ubiquity of ::, this would seem ideal and sufficient. While there is something to be said for using standard compliant syntax changing just this like doesn't seem like it would move the goalposts meaningfully.

David J.

Re: [HACKERS] CAST vs ::

From
Tom Lane
Date:
"David G. Johnston" <david.g.johnston@gmail.com> writes:
> On Thursday, July 13, 2017, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>> Maybe we can hack ruleutils to use
>> the CAST syntax only in this specific context.

> Given the lack of complaints, and ubiquity of ::, this would seem ideal
> and sufficient. While there is something to be said for using standard
> compliant syntax changing just this like doesn't seem like it would move
> the goalposts meaningfully.

Hm, it's worse than I thought: the argument of the CAST expression
needn't be a function call at all, and on top of that, the parser
will throw away a no-op cast altogether.  So for example:

regression=# create view vvc as select * from cast(1+2 as int) c(x);
CREATE VIEW
regression=# \d+ vvc                            View "public.vvc"Column |  Type   | Collation | Nullable | Default |
Storage| Description 
 
--------+---------+-----------+----------+---------+---------+-------------x      | integer |           |          |
    | plain   | 
 
View definition:SELECT c.x  FROM 1 + 2 c(x);

To make the world safe for this behavior by extending the grammar,
we'd have to be prepared to accept an arbitrary a_expr, without even
surrounding parentheses, as a FROM item.  I don't think there's much
chance of making that work without grammar conflicts, and even if we
managed, the SQL committee would probably find a way to break it with
some future feature addition.

So what I'm now thinking is to make ruleutils.c look at the expression in
an RTE_FUNCTION FROM item and see if it will decompile as something with
the syntax of a function call.  If not, or if there's any doubt, emit a
dummy CAST(... AS sametype) around it.  That would cause the above example
to come out the way it went in.
        regards, tom lane