is there any api I can use to parse create table statement?

8 views
Skip to first unread message

Kant Kodali

unread,
Feb 4, 2018, 5:42:33 AM2/4/18
to DataStax Java Driver for Apache Cassandra User Mailing List
Hi All,

I am wondering if there any API I can use to parse a raw create table (a int primary key , b int) string such that I can use the api to get all columns, primary keys and clustering keys? 

Thanks!

Alex Ott

unread,
Feb 4, 2018, 11:14:50 AM2/4/18
to java-dri...@lists.datastax.com
Hi

Do you have only text for this statement, or there is an existing table in the database?

This project (https://github.com/lbruand/cql2plantuml) is using parser written in Scala to parse CQL statements into pieces & generate PlantUML diagrams.
But if you have existing table, then it's much easier - just use Metadata class to retrieve all necessary information...


--
You received this message because you are subscribed to the Google Groups "DataStax Java Driver for Apache Cassandra User Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to java-driver-user+unsubscribe@lists.datastax.com.



--
With best wishes,                    Alex Ott
http://alexott.net/
Twitter: alexott_en (English), alexott (Russian)
Skype: alex.ott

Alex Ott

unread,
Feb 4, 2018, 11:17:50 AM2/4/18
to java-dri...@lists.datastax.com
Sorry, clicked Send too early...

Another possibility - re-use Cassandra's parser directly, like here: https://github.com/tacoo/cassandra-antlr-sample

Allan Pomeroy

unread,
Feb 4, 2018, 1:22:23 PM2/4/18
to java-dri...@lists.datastax.com
Not sure, but you might be able o query that data from one of the system tables.

Sent from my iPad
--
You received this message because you are subscribed to the Google Groups "DataStax Java Driver for Apache Cassandra User Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to java-driver-us...@lists.datastax.com.

Alex Ott

unread,
Feb 4, 2018, 1:27:22 PM2/4/18
to java-dri...@lists.datastax.com
com.datastax.driver.core.Metadata is more reliable method that works with different versions of Cassandra...

To unsubscribe from this group and stop receiving emails from it, send an email to java-driver-user+unsubscribe@lists.datastax.com.

--
You received this message because you are subscribed to the Google Groups "DataStax Java Driver for Apache Cassandra User Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to java-driver-user+unsubscribe@lists.datastax.com.

Kant Kodali

unread,
Feb 4, 2018, 2:28:57 PM2/4/18
to DataStax Java Driver for Apache Cassandra User Mailing List
Hi Alex,

I only have the text for the statement so I can't send it to Cassandra first and then read the System tables. This https://github.com/tacoo/cassandra-antlr-sample looks the option I am looking for! 

can I use just this com.datastax.driver.core.Metadata given that I only have text and extract the columns out of it?

Thanks!

Kant Kodali

unread,
Feb 4, 2018, 11:29:32 PM2/4/18
to ale...@gmail.com, DataStax Java Driver for Apache Cassandra User Mailing List
HI Alex,

I used the example from that link you sent. I get the following error. 

Exception in thread "main" org.apache.cassandra.exceptions.ConfigurationException: Keyspace test_keyspace doesn't exist
at org.apache.cassandra.cql3.statements.CreateTableStatement$RawStatement.prepare(CreateTableStatement.java:200)
at com.hello.world.Test.main(Test.java:23)


Here is my code.

package com.hello.world;

import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CommonTokenStream;
import org.apache.cassandra.cql3.CqlLexer;
import org.apache.cassandra.cql3.CqlParser;
import org.apache.cassandra.cql3.statements.CreateTableStatement;
import org.apache.cassandra.cql3.statements.ParsedStatement;

public class Test {

public static void main(String[] args) throws Exception {
String stmt = "create table if not exists test_keyspace.my_table (field1 text, field2 int, field3 set<ascii>, field4 map<ascii, text>, primary key (field1) );";
ANTLRStringStream stringStream = new ANTLRStringStream(stmt);
CqlLexer cqlLexer = new CqlLexer(stringStream);
CommonTokenStream token = new CommonTokenStream(cqlLexer);
CqlParser parser = new CqlParser(token);
ParsedStatement query = parser.query();
if (query.getClass().getDeclaringClass() == CreateTableStatement.class) {
CreateTableStatement.RawStatement cts = (CreateTableStatement.RawStatement) query;
System.out.println(cts.keyspace());
System.out.println(cts.columnFamily());
ParsedStatement.Prepared prepared = cts.prepare();
CreateTableStatement cts2 = (CreateTableStatement) prepared.statement;
cts2.getCFMetaData()
.getColumnMetadata()
.values()
.stream()
.forEach(cd -> System.out.println(cd));
}
}
}
Thanks!

Jens Teglhus Møller

unread,
Feb 6, 2018, 6:49:43 AM2/6/18
to DataStax Java Driver for Apache Cassandra User Mailing List
Hi

If you include cassandra as a dependency in your project, you can use the lexer that comes with it. I did it for a prototype i have for parsing full statements in the cassandra-maven-plugin, it is quite simple.

Below is a snippet that parses a full cql file into statements (instead of the current split in ; which breaks badly if you have ; in a string or comment).

protected static String[] splitStatementsUsingCqlLexer(String statements) {
ANTLRStringStream stream = new ANTLRStringStream(statements);
CqlLexer lexer = new CqlLexer(stream);
ArrayList<String> statementList = new ArrayList<String>();
StringBuffer currentStatement = new StringBuffer();
boolean inComment;
// Not the prettiest code i ever wrote, but it gets the job done.
for (Token token = lexer.nextToken(); token.getType() != Token.EOF; token = lexer.nextToken()) {
if (token.getText().equals(";")) {
// when we meet a ; terminate current statement and prepare the next
currentStatement.append(";");
statementList.add(currentStatement.toString());
currentStatement = new StringBuffer();
} else if (token.getType() == CqlLexer.STRING_LITERAL) {
// If we meet a string we should quote it and escape any enclosed ' as ''
currentStatement.append("'");
// TODO: There must be a cassandra util method somewhere that escapes a string for sql
currentStatement.append(token.getText().replaceAll("'", "''"));
currentStatement.append("'");
} else {
currentStatement.append(token.getText());
}
}
if (currentStatement.length() > 0 && currentStatement.toString().trim().length() > 0) {
statementList.add(currentStatement.toString());
}
return statementList.toArray(new String[statementList.size()]);
}

Best regards Jens

Jens Teglhus Møller

unread,
Feb 6, 2018, 6:54:15 AM2/6/18
to DataStax Java Driver for Apache Cassandra User Mailing List
Ok, next time I will read the full thread before answering ;-)

Jens Teglhus Møller

unread,
Feb 6, 2018, 7:01:07 AM2/6/18
to DataStax Java Driver for Apache Cassandra User Mailing List, ale...@gmail.com
Hi Kant

I think the error message does a pretty decent job at describing the problem. You need to create the keyspace before you can add table to it. See https://docs.datastax.com/en/cql/3.3/cql/cql_reference/cqlCreateKeyspace.html for details.

Best regards Jens
To unsubscribe from this group and stop receiving emails from it, send an email to java-driver-us...@lists.datastax.com.



--
With best wishes,                    Alex Ott
http://alexott.net/
Twitter: alexott_en (English), alexott (Russian)
Skype: alex.ott



--
With best wishes,                    Alex Ott
http://alexott.net/
Twitter: alexott_en (English), alexott (Russian)
Skype: alex.ott

--
You received this message because you are subscribed to the Google Groups "DataStax Java Driver for Apache Cassandra User Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to java-driver-us...@lists.datastax.com.

Reply all
Reply to author
Forward
0 new messages