SQL ステートメントで列名を変更する (テーブル名はそのままにする) シンプルなアプリを実装しています。ステートメントは として渡され、String
変更されたものも として返されString
ます。データベース接続は関係ありません。
これを実現するために、Apache Calcite の SQL パーサーを使用しています。SQL 文字列を に解析し、名前を変更した を作成する をSqlNode
受け入れ、すべてを( を使用して) に書き戻します。SqlVisitor
SqlNode
String
SqlNode.toSqlString()
SqlNode
問題は、を受け入れながら、解析されたオブジェクトの列とテーブルの違いを見分ける方法がわからないことSqlVisitor
です。どちらも として表されSqlIdentifier
、同じ を持ちSqlKind
ます。したがって、が にSqlVisitor
アクセスするSqlIdentifier
と、それが列であろうとテーブルであろうと名前が変更されます。
private String changeNames(String str) throws SqlParseException {
SqlShuttle visitor = new SqlShuttle() {
private String rename(String str) {
return str + "-test";
}
@Override
public SqlNode visit(SqlIdentifier identifier) {
SqlIdentifier output = new SqlIdentifier(rename(identifier.getSimple()), identifier.getCollation(), identifier.getParserPosition());
return output;
}
};
SqlParser.ConfigBuilder configBuilder = SqlParser.configBuilder();
configBuilder.setLex(Lex.MYSQL);
SqlParser.Config config = configBuilder.build();
SqlParser parser = SqlParser.create(str, config);
SqlNode parsedStatement = parser.parseQuery(str);
SqlNode outputNode = parsedStatement.accept(visitor);
return outputNode.toSqlString(SqlDialect.DUMMY).getSql();
}
例えば
SELECT name, address, age FROM mytablename WHERE age = 23 AND name = 'John'
に変更されます
SELECT `name-test`, `address-test`, `age-test` FROM `mytablename-test` WHERE `age-test` = 23 AND `name-test` = 'John'
SqlIdentifier
与えられたものが列かテーブルかをどうやって見分けることができますか?