On Tue, May 19, 2020 at 9:51 AM Tom Lane <t...@sss.pgh.pa.us> wrote: > Uh ... what exactly would be the point of that? The real reason to do > this at all is not that we have it in for '!', but that we want to > drop the possibility of postfix operators from the grammar altogether, > which will remove a boatload of ambiguity.
The ambiguity doesn't come from the mere existence of postfix operators. It comes from the fact that, when we lex the input, we can't tell whether a particular operator that we happen to encounter is prefix, infix, or postfix. So hard-coding, for example, a rule that '!' is always a postfix operator and anything else is never a postfix operator is sufficient to solve the key problems. Then "SELECT a ! b" can only be a postfix operator application followed by a column labeling, a "SELECT a + b" can only be the application of an infix operator. The parser ambiguities could also be removed if the source of the information where a GUC or a catalog lookup; there are good reasons not to go that way, but my point is that the problem is not that postfix operators are per se evil, but that the information we need is not available at the right phase of the process. We can only make use of the information in pg_operator after we start assigning type information, which has to happen after we parse, but to avoid the ambiguity here, we need the information before we parse - i.e. at the lexing stage. > In my non-caffeinated state, I don't recall exactly which things are > blocked by the existence of postfix ops; but I think for instance it might > become possible to remove the restriction of requiring AS before column > aliases that happen to be unreserved keywords. Right - which would be a huge win. > I would also argue that having a feature that is available to > built-in operators but not user-defined ones is pretty antithetical > to Postgres philosophy. That I think is the policy question before us. I believe that any rule that tells us which operators are postfix and which are not at the lexing stage is good enough. I think here you are arguing for the empty set, which will work, but I believe any other fixed set also works, such as { '!' }. I don't think we're going to break a ton of user code no matter which one we pick, but I do think that it's possible to pick either one and still achieve our goals here, so that's the issue that I wanted to raise. -- Robert Haas EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company