Trying to parse CQL(Cassandra) query and convert it to an object using antlr


Author: Yogesh Sarma

Originally Sourced from: https://stackoverflow.com/questions/68484098/trying-to-parse-cqlcassandra-query-and-convert-it-to-an-object-using-antlr

Hey so i am trying to write a CQL(cassandra) Parser where i take a String CQL query and try to create a QueryClass Object out of it

QueryClass.java

public QueryClass{
    private List<String> select;
    private Map<String, Object> insert;
    private Map<String, Object> update;
    private Map<String, Object> where;
    private String keyspace;
    private String tablename;
    private Integer timeToLive;
    //different constructors for different statements..
}

This is the method where we send the string query and get the object back.

public QueryClass cqlParser(String query) {
        QueryClass queryObject;   
        ANTLRStringStream antlrStringStream= new ANTLRStringStream(query);
        CqlLexer cqlLexer = new CqlLexer(antlrStringStream);
        CommonTokenStream tokenStream = new CommonTokenStream(cqlLexer);
        CqlParser cqlParser = new CqlParser(tokenStream);
        ParsedStatement statement = cqlParser.query();
        
        System.out.println(statement.getClass().getDeclaringClass());
        if (statement.getClass().getDeclaringClass() == SelectStatement.class) 
        { 
            SelectStatement.RawStatement select= (SelectStatement.RawStatement) statement;
            String tableName= select.columnFamily();
            String keyspace= select.keyspace();
            List<RawSelector> selectColumns= select.selectClause;
            for (RawSelector rawSelector: selectColumns) {
                System.out.println(rawSelector.selectable); 
            }
            WhereClause whereClause= select.whereClause;
            List<Relation> whereClauseConditions = whereClause.relations;
            whereClauseConditions.forEach(System.out::println);
            Term.Raw limit= select.limit;
            queryObject = new QueryClass(tableName, keyspace, selectColumns, whereClause, limit);
        }
        else if(statement.getClass().getDeclaringClass() == UpdateStatement.class) 
        { 
            if(statement.getClass() == UpdateStatement.ParsedUpdate.class) 
            {
                UpdateStatement.ParsedUpdate update= (UpdateStatement.ParsedUpdate) statement;
                String tableName= update.columnFamily();
                String keyspace= update.keyspace();
                //need to get all the updates, whereclause and TimeToLive (TTL) 
            }
            else if(statement.getClass() == UpdateStatement.ParsedInsert.class) 
            {
                UpdateStatement.ParsedInsert insert = (UpdateStatement.ParsedInsert) statement;
                String tableName= insert.columnFamily(); 
                String keyspace=insert.keyspace(); 
                //need to get all columns and their values, whereclause and TimeToLive
            }
        }
        else if(statement.getClass().getDeclaringClass() == DeleteStatement.class) 
        {
            DeleteStatement.Parsed delete = (DeleteStatement.Parsed) statement;
            String tableName= delete.columnFamily();
            String keyspace= delete.keyspace();
            //need to get where clause
        }
        return queryObject;
    }

This works well with select statements. But doesn't work for Insert, Update and delete statements as the fields, whereclause, conditions, insert columnnames, columnvalues, timeToLive etc are all private fields and there are no getters and setters available to use.

So how do I go about getting them? Will I be able to get them using this approach? Should I be looking at this differently?

Btw I am using this dependency in my pom.xml-

<dependency>
    <groupId>org.apache.cassandra</groupId>
    <artifactId>cassandra-all</artifactId>
    <version>3.11.4</version>
</dependency>

which uses Antlr v3.5.2.(Does Antlrv4 have anything that is useful for my case?)

Any inputs are appreciated. Thanks.