我正在实现一个简单的应用程序,它可以在 SQL 语句中更改列名(并单独保留表名)。语句作为 a 传递String
,修改后的语句也作为 a 返回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
的是列还是表?