KCK
KCK

Reputation: 2033

Parsing mysql using ANTLR4 simple example

I am using mysql grammar from here: https://github.com/antlr/grammars-v4/tree/master/mysql and have generated java files using Maven. Now, I was trying to parse a query but I am not getting how to do so.

I basically want to 'get' all the different components of a query, like the list columns selected, where conditions, sub queries, table names, etc. But I have no idea how to proceed. I have written below code as of now. Can someone please suggest with a simple example so that I can understand the usage and take up more complex tasks? Here is my code:

public static void main( String[] args )
{
    String sql="select cust_name from database..table where cust_name like 'Kash%'";
    ANTLRInputStream input = new ANTLRInputStream(sql);
    MySqlLexer mySqlLexer = new MySqlLexer(input);
    CommonTokenStream tokens = new CommonTokenStream(mySqlLexer);
    MySqlParser mySqlParser = new MySqlParser(tokens);

    ParseTree tree = mySqlParser.dmlStatement();
    ParseTreeWalker walker = new ParseTreeWalker();
    MySqlParserBaseListener listener=new MySqlParserBaseListener();
    ParseTreeWalker.DEFAULT.walk(listener, tree);


    System.out.println(?);
}  

Using the above code, I am getting the following output:

line 1:11 no viable alternative at input '_'
(dmlStatement _ . . _ 'Kash%')

Thanks For Help :)

Upvotes: 3

Views: 7908

Answers (1)

Bart Kiers
Bart Kiers

Reputation: 170178

I basically want to 'get' all the different components of a query, like the list columns selected, where conditions, sub queries, table names, etc.

Your tree variable holds all that data: ParseTree tree = mySqlParser.dmlStatement();

line 1:11 no viable alternative at input '_'

If you look at the lexer rules:

SELECT:                              'SELECT';

ID:                                  ID_LITERAL;

fragment ID_LITERAL:                 [A-Z_$0-9]*?[A-Z_$]+?[A-Z_$0-9]*;

it appears that keywords and identifiers cannot contain lowercase letters.

If you run it like this:

String sql = "SELECT CUST_NAME FROM CUSTOMERS WHERE CUST_NAME LIKE 'Kash%'";

MySqlLexer lexer = new MySqlLexer(CharStreams.fromString(sql));
MySqlParser parser = new MySqlParser(new CommonTokenStream(lexer));
ParseTree root = parser.dmlStatement();

System.out.println(root.toStringTree(parser));

you will see the following output (indented for easier reading):

(dmlStatement 
  (selectStatement 
    (querySpecification SELECT 
      (selectElements 
        (selectElement 
          (fullColumnName 
            (uid 
              (simpleId CUST_NAME))))) 
      (fromClause FROM 
        (tableSources 
          (tableSource 
            (tableSourceItem 
              (tableName 
                (fullId 
                  (uid 
                    (simpleId CUSTOMERS))))))) WHERE 
        (expression 
          (predicate 
            (predicate 
              (expressionAtom 
                (fullColumnName 
                  (uid 
                    (simpleId CUST_NAME))))) LIKE 
          (predicate 
            (expressionAtom 
              (constant 
                (stringLiteral 'Kash%'))))))))))

Upvotes: 3

Related Questions