基于社区当前最新版本calcite-1.32.0进行分析
当前的SqlValidatorTest$testFieldOrigin中有一个单测可以直接用来调试
调试后,很快就能在测试专用方法assertFieldOrigin找到SqlValidatorTest$getFieldOrigins这个血缘入口方法
public SqlValidatorFixture assertFieldOrigin(Matcher matcher) {
tester.validateAndThen(factory, toSql(false), (sap, validator, n) -> {
final List> list = validator.getFieldOrigins(n);
final StringBuilder buf = new StringBuilder("{");
int i = 0;
for (List strings : list) {
if (i++ > 0) {
buf.append(", ");
}
if (strings == null) {
buf.append("null");
} else {
int j = 0;
for (String s : strings) {
if (j++ > 0) {
buf.append('.');
}
buf.append(s);
}
}
}
buf.append("}");
assertThat(buf.toString(), matcher);
});
return this;
}
getFieldOrigins
具体实现如下
@Override public List<@Nullable List> getFieldOrigins(SqlNode sqlQuery) {
if (sqlQuery instanceof SqlExplain) {
return Collections.emptyList();
}
// validate获得query的rowType,
final RelDataType rowType = getValidatedNodeType(sqlQuery);
final int fieldCount = rowType.getFieldCount();
if (!sqlQuery.isA(SqlKind.QUERY)) {
return Collections.nCopies(fieldCount, null);
}
// 再遍历rowType获得每个filed的origin列
final List<@Nullable List> list = new ArrayList<>();
for (int i = 0; i < fieldCount; i++) {
list.add(getFieldOrigin(sqlQuery, i));
}
return ImmutableNullableList.copyOf(list);
}
getFieldOrigin是处理每个Field的方法,但是看代码只支持select语句,不支持insert语句
注意这里的selectItem是擦除了别名的,上面代码有个stripAs方法;同时也只处理了别名,而没有处理其他情况
具体的实现如下:通过sqlSelect获得scope,每个scope再取出对应selectItem的SqlQualified
注意namespace可以获得table path
SqlQualified封装了namespace+identifier(table+column)
至此,可以获得列对应的表信息