[fix](optimizer) join reorder may cause column non-existence problem (#10670)

for example:
select * from t1 inner join t2 on t1.a = t2.b inner join t3 on t3.c = t2.b;
If t3 is a large table, it will be placed first after the reorderTable,
and the problem that t2.b does not exist will occur in reanalyzing.
This commit is contained in:
yinzhijian
2022-07-08 17:28:32 +08:00
committed by GitHub
parent d127cfeea2
commit eeee036cba
2 changed files with 30 additions and 1 deletions

View File

@ -820,7 +820,18 @@ public class SelectStmt extends QueryStmt {
List<Expr> candidateEqJoinPredicates = analyzer.getEqJoinConjunctsExcludeAuxPredicates(tid);
for (Expr candidateEqJoinPredicate : candidateEqJoinPredicates) {
List<TupleId> candidateTupleList = Lists.newArrayList();
Expr.getIds(Lists.newArrayList(candidateEqJoinPredicate), candidateTupleList, null);
List<Expr> candidateEqJoinPredicateList = Lists.newArrayList(candidateEqJoinPredicate);
// If a large table or view has joinClause is ranked first,
// and the joinClause is not judged here,
// the column in joinClause may not be found during reanalyzing.
// for example:
// select * from t1 inner join t2 on t1.a = t2.b inner join t3 on t3.c = t2.b;
// If t3 is a large table, it will be placed first after the reorderTable,
// and the problem that t2.b does not exist will occur in reanalyzing
if (candidateTableRef.getOnClause() != null) {
candidateEqJoinPredicateList.add(candidateTableRef.getOnClause());
}
Expr.getIds(candidateEqJoinPredicateList, candidateTupleList, null);
int count = candidateTupleList.size();
for (TupleId tupleId : candidateTupleList) {
if (validTupleId.contains(tupleId) || tid.equals(tupleId)) {

View File

@ -2169,4 +2169,22 @@ public class QueryPlanTest extends TestWithFeService {
Assert.assertFalse(explainString.contains("CROSS JOIN"));
}
@Test
public void testDefaultJoinReorderWithView() throws Exception {
connectContext.setDatabase("default_cluster:test");
createTable("CREATE TABLE t_1 (col1 varchar, col2 varchar, col3 int)\n" + "DISTRIBUTED BY HASH(col3)\n"
+ "BUCKETS 3\n" + "PROPERTIES(\n" + " \"replication_num\"=\"1\"\n" + ");");
createTable("CREATE TABLE t_2 (col1 varchar, col2 varchar, col3 int)\n" + "DISTRIBUTED BY HASH(col3)\n"
+ "BUCKETS 3\n" + "PROPERTIES(\n" + " \"replication_num\"=\"1\"\n" + ");");
createView("CREATE VIEW v_1 as select col1 from t_1;");
createView("CREATE VIEW v_2 as select x.col2 from (select t_2.col2, 1 + 1 from t_2) x;");
String sql = "explain select t_1.col2, v_1.col1 from t_1 inner join t_2 on t_1.col1 = t_2.col1 inner join v_1 "
+ "on v_1.col1 = t_2.col2 inner join v_2 on v_2.col2 = t_2.col1";
String explainString = getSQLPlanOrErrorMsg(sql);
System.out.println(explainString);
// errCode = 2, detailMessage = Unknown column 'col2' in 't_2'
Assert.assertFalse(explainString.contains("errCode"));
}
}