Javaで使えるpresto-parserのメモ。
|
presto-parserは、SQLをパースするライブラリー。
JDBCのパラメーター「?
」や「:name
」は識別できない。(パース時に例外が発生する)
presto-parserはMavenリポジトリーから取得できる。
〜 repositories { mavenCentral() } dependencies { // https://mvnrepository.com/artifact/com.facebook.presto/presto-parser compile group: 'com.facebook.presto', name: 'presto-parser', version: '0.211' }
import java.util.Optional; import com.facebook.presto.sql.parser.ParsingOptions; import com.facebook.presto.sql.parser.ParsingOptions.DecimalLiteralTreatment; import com.facebook.presto.sql.parser.SqlParser; import com.facebook.presto.sql.tree.Expression; import com.facebook.presto.sql.tree.Query; import com.facebook.presto.sql.tree.QuerySpecification; import com.facebook.presto.sql.tree.Relation; import com.facebook.presto.sql.tree.Select;
public class PrestoParserExample {
public static void main(String... args) {
// String sql = "select a,b,1,nvl(a,b) from dual where a=? and b=:b"; //× JDBCパラメーターは識別できない。例外が発生する
String sql = "select a,b,1,nvl(a,b) from dual";
// String sql = "select a,b,1,nvl(a,b) from dual where a=1";
SqlParser parser = new SqlParser();
Query query = (Query) parser.createStatement(sql, new ParsingOptions(DecimalLiteralTreatment.AS_DECIMAL));
QuerySpecification body = (QuerySpecification) query.getQueryBody();
Select select = body.getSelect();
System.out.println(select.getSelectItems());
Optional<Relation> from = body.getFrom();
System.out.println(from.get());
Optional<Expression> where = body.getWhere();
System.out.println(where);
}
}
import java.util.Optional; import com.facebook.presto.sql.parser.ParsingOptions; import com.facebook.presto.sql.parser.ParsingOptions.DecimalLiteralTreatment; import com.facebook.presto.sql.parser.SqlParser; import com.facebook.presto.sql.tree.AstVisitor; import com.facebook.presto.sql.tree.Expression; import com.facebook.presto.sql.tree.Query; import com.facebook.presto.sql.tree.QueryBody; import com.facebook.presto.sql.tree.QuerySpecification; import com.facebook.presto.sql.tree.Relation; import com.facebook.presto.sql.tree.Select; import com.facebook.presto.sql.tree.Statement;
public class PrestoParserExample2 { public static void main(String... args) { String sql = "select a,b,1,nvl(a,b) from dual"; // String sql = "select a,b,1,nvl(a,b) from dual where a=1"; SqlParser parser = new SqlParser(); Statement statement = parser.createStatement(sql, new ParsingOptions(DecimalLiteralTreatment.AS_DECIMAL)); MyVisitor visitor = new MyVisitor(); MyContext context = new MyContext(); statement.accept(visitor, context); }
static class MyContext { }
static class MyVisitor extends AstVisitor<Void, MyContext> { @Override protected Void visitQuery(Query node, MyContext context) { QueryBody body = node.getQueryBody(); return body.accept(this, context); } @Override protected Void visitQuerySpecification(QuerySpecification node, MyContext context) { Select select = node.getSelect(); System.out.println(select.getSelectItems()); Optional<Relation> from = node.getFrom(); System.out.println(from.get()); Optional<Expression> where = node.getWhere(); System.out.println(where); return null; } } }
AstVisitor<R, C>の型引数は、Rはacceptメソッドの戻り値の型(各visitメソッドの戻り値の型)、Cはcontextの型。
どちらも自由なクラスが使える。