Hello Tom,

ISTM that I've tried to suggest to work around that complexity by:
  - document that \if-related commands should only occur at line start
    (and extend to eol).
  - detect and complain when this is not the case.

I think this is a lousy definition, and would never be considered if we
were working in a green field.

Yes, sure. As you pointed out, the field is not green: there is no clean lexical convention, too bad. I'm trying to deal with that without too much fuss in the code.

Moreover, preventing such cases would be pretty darn ugly/messy as well.

I also fear that there are corner cases where the behavior would still
be inconsistent.  Consider

        \if ...
        \set foo `echo \endif should not appear here`

In this instance, ISTM that there is no problem. On "\if true", set is executed, all is well. On "\if false", the whole line would be skipped because the if-related commands are only expected on their own line, all is well again. No problem.

Another more interesting one would be:

  \if ...
    \unset foo \endif

On true, unset get its argument, then endif is detected as a backslash command, but it would see that it is not on its own line, so it would error out *and* be ignored. On false, the whole line would be ignored, it would just not complain, but it would be the same, i.e. it is *not* an \endif again. The drawback is only that the wrong \endif is not detected when under a false branch. That is why I added a third bullet "call border cases a feature".

ISTM that the proposed simple rules allow to deal with the situation without having to dive into each command lexing rules, and changing the existing code significantly. The drawback is that misplaced \endif are not detected in false branch, but they are ignored anyway, which is fine.

I'm imagining that instead of

[...] char       *envvar = psql_scan_slash_option(scan_state,

we'd write

[...] char       *envvar = args[0];

where the args array had been filled at the top of the function.
The top-of-function code would have to know all the cases where
commands didn't use basic OT_NORMAL processing, but there aren't
that many of those, I think.

Yep, I understood the idea. There are a few of those, about 49 OT_* in "command.c", including 34 OT_NORMAL, 1 OT_NO_EVAL, 3 OT_FILEPIPE, 9 OT_WHOLELINE, some OT_SQLHACKID & OT_SQLID. I'm not sure of the combinations.

It still means splitting command lexing knowledge in several places. I'm not convinced by the impact on the resulting code with regard to readability and maintainability, so if there could be a way to get something without taking that path that would be nice, hence my suggestions.


Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:

Reply via email to