【发布时间】:2016-05-18 00:12:29
【问题描述】:
我正在实现一个简单的应用程序,它可以在 SQL 语句中更改列名(并单独保留表名)。该语句作为String 传递,修改后的也作为String 返回,不涉及数据库连接。
为了实现这一点,我使用了 Apache Calcite 的 SQL 解析器。我将 SQL 字符串解析为SqlNode,接受创建重命名SqlNode 的SqlVisitor,然后将所有内容写回String(使用SqlNode.toSqlString())。
问题是在接受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'
会被修改成
SELECT `name-test`, `address-test`, `age-test` FROM `mytablename-test` WHERE `age-test` = 23 AND `name-test` = 'John'
如何判断给定的SqlIdentifier 是列还是表?
【问题讨论】:
标签: java sql parsing apache-calcite