antlr / grammars-v4

Grammars written for ANTLR v4; expectation that the grammars are free of actions.
MIT License
10.18k stars 3.71k forks source link

[postgresql] Ambiguity in opt_analyze. #4302

Open kaby76 opened 5 hours ago

kaby76 commented 5 hours ago

Consider this input:

VACUUM ANALYZE brin_test;

This can be parsed in two ways:

The problem here is in opt_analyze in the context of a stmt.

stmtmulti
    : (stmt SEMI?)*
    ;

stmt
    : ...
    ;

opt_analyze
    : analyze_keyword
    |
    ;

The problem is that stmtmulti allows for an optional SEMI. This is a bad idea because it directly leads to this problem: Where does the VACUUM statement end?

This change was introduced with https://github.com/antlr/grammars-v4/pull/2365 (specifically https://github.com/antlr/grammars-v4/pull/2365/commits/e2d77e34395ae8b8b19a987714f6f9c28cd70e1e#diff-191019bcbd2ccd918ba1d7e6610ca830bc526d04af2ae6e6d3c5356e96274b76), deviating from the rule from in the official Bison grammar. Note in the official grammar, stmtmulti does not offer an optional semicolon! Really, you should be very, very careful in how to refactor from the official grammar gram.y!!

The fix is to change ';'? to ';'!

kaby76 commented 4 hours ago

postgresql has meta commands, but it is NOT part of the official gram.y grammar. So, the introduction of it as a stmt is wrong (i.e., it is not terminated by semi-colon, for example). (https://github.com/antlr/grammars-v4/blob/199a5121ece05d2f2e7eca330d0738220499e80c/sql/postgresql/PostgreSQLParser.g4#L179 https://github.com/antlr/grammars-v4/blob/199a5121ece05d2f2e7eca330d0738220499e80c/sql/postgresql/PostgreSQLParser.g4#L183)