基于社区当前最新版本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)
至此,可以获得列对应的表信息