0
votes

Hey so i am trying to use 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.

1

1 Answers

0
votes

If you're looking to write a CQL parser today, then ANTLR4 would definitely be a better choice.

There's even a CQL3 grammar for ANTLR4 at https://github.com/antlr/grammars-v4/tree/master/cql3

It appears that you were trying to use the CQlParser that was already a part of that package. Since you also say you're trying to write your own parser, that's a bit confusing.

For writing your own parser, first work through a couple of ANTLR4 tutorials to familiarize yourself with ANTLR4 in general, then you should understand how to leverage the grammar referenced above.

BTW... the private vars etc. all seem to be an artifact of how the Cassandra team wrote their classes to interface with ANTLR3 (I got into ANTLR in V4 days, so I'm not well versed in ANTLR3, but I don't think the limitations had anything to do with ANTLR3 itself.). That said, I don't see why you'd not go with the ANTLR4 grammar and use ANTLR4. It's very nice and has a lot of improvements over ANTLR3.