S-JIS[2018-09-29] 変更履歴

presto-parser

Javaで使えるpresto-parserのメモ。


概要

presto-parserは、SQLをパースするライブラリー。

JDBCのパラメーター「?」や「:name」は識別できない。(パース時に例外が発生する)


インストール

presto-parserはMavenリポジトリーから取得できる。

build.gradle

〜
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);
	}
}

Visitorの例

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の型。
どちらも自由なクラスが使える。


Javaへ戻る / 技術メモへ戻る
メールの送信先:ひしだま