SQL文でカラム名を変更してテーブル名だけを変更する簡単なアプリケーションを実装しています。ステートメントはString
として渡され、変更されたステートメントもString
として返されます。データベース接続は必要ありません。apache calciteはテーブル名とカラム名を区別する
これを達成するために、Apache CalciteのSQLパーサーを使用しています。私はSqlNode
にSQL文字列を解析し、SqlNode
と名前を変更したSqlVisitor
を受け入れ、SqlNode.toSqlString()
を使用してString
にすべてを書き戻します。
問題は、SqlVisitor
を受け入れる間に、解析されたSqlNode
オブジェクトの列と表の違いをわかりません。両方とも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'
がSqlIdentifier
が列または表で与えられた場合にはどのように私は言うことができる?
SELECT `name-test`, `address-test`, `age-test` FROM `mytablename-test` WHERE `age-test` = 23 AND `name-test` = 'John'
に変更されますか
SqlScopedShuttleはどうなっていますか? –
SqlScopedShuttleは便利なように聞こえますが、それほど多くは行いません。これは、ツリーに再帰的にASTノード(SqlNode)のスタックを保持します。 SQLスコープ規則については何も知らない。 –