Search code examples
t-sqlantlrsybaseantlr4sap-ase

Parse TSQL/Sybase *= conditional operator used to express outer join using ANTLR4


Sybase has that non-ANSI SQL conditional operator used to express outer join: *=.

It's being deprecated (http://dcx.sybase.com/1200/en/dbusage/apxa-transactsqlouter-joins-aspen.html).

As we are moving from Sybase ASE to MySQL I have started to use ANTLR4 to parse the Sybase SQL code to try to translate it into the MySQL code equivalent.

I have tried adding it to the TSqlParser.g4 grammar available here: https://github.com/antlr/grammars-v4/tree/master/sql/tsql. See '*' '=' at the end of the line below but it doesn't work

// https://msdn.microsoft.com/en-us/library/ms188074.aspx
// Spaces are allowed for comparison operators.
comparison_operator
    : '=' | '>' | '<' | '<' '=' | '>' '=' | '<' '>' | '!' '=' | '!' '>' | '!' '<' | '*' '='
    ;

I tried a few things to make it work like escaping \* and removing the *= assignment_operator but nothing works. It's probably a dumb question since I'm new to ANTLR. :-(

Please help.


Solution

  • The input *= is being tokenised as a MULT_ASSIGN by the lexer. You defined it as two separate tokens: '*' '=', which is not the same as '*='.

    If you parse following the input with your grammar:

    SELECT Q
    FROM T
    WHERE ID * = 42;
    

    it will go fine, but to parse this properly:

    SELECT Q
    FROM T
    WHERE ID *= 42;
    

    you need to do it like this:

    comparison_operator
        : ... | '*='
        ;
    

    and to support both, do this:

    comparison_operator
        : ... | '*' '=' | '*='
        ;