[fix](optimization) InferFiltersRule bug: a self inner join on a view, which contains where clause, will cause mis-inference. (#11566)
This commit is contained in:
@ -152,6 +152,17 @@ public class Analyzer {
|
||||
// Flag indicating if this analyzer instance belongs to a subquery.
|
||||
private boolean isSubquery = false;
|
||||
|
||||
public boolean isInlineView() {
|
||||
return isInlineView;
|
||||
}
|
||||
|
||||
public void setInlineView(boolean inlineView) {
|
||||
isInlineView = inlineView;
|
||||
}
|
||||
|
||||
// Flag indicating if this analyzer instance belongs to an inlineview.
|
||||
private boolean isInlineView = false;
|
||||
|
||||
// Flag indicating whether this analyzer belongs to a WITH clause view.
|
||||
private boolean isWithClause = false;
|
||||
|
||||
@ -776,6 +787,21 @@ public class Analyzer {
|
||||
d = resolveColumnRef(colName);
|
||||
} else {
|
||||
d = resolveColumnRef(newTblName, colName);
|
||||
//in reanalyze, the inferred expr may contain upper level table alias, and the upper level alias has not
|
||||
// been PROCESSED. So we resolve this column without tbl name.
|
||||
// For example: a view V "select * from t where t.a>1"
|
||||
// sql: select * from V as t1 join V as t2 on t1.a=t2.a and t1.a in (1,2)
|
||||
// after first analyze, sql becomes:
|
||||
// select * from V as t1 join V as t2 on t1.a=t2.a and t1.a in (1,2) and t2.a in (1, 2)
|
||||
// in reanalyze, when we process V as t2, we indeed process sql like this:
|
||||
// select * from t where t.a>1 and t2.a in (1, 2)
|
||||
// in order to resolve t2.a, we have to ignore "t2"
|
||||
// ===================================================
|
||||
// Someone may concern that if t2 is not alias of t, this fix will cause incorrect resolve. In fact,
|
||||
// this does not happen, since we push t2.a in (1.2) down to this inline view, t2 must be alias of t.
|
||||
if (d == null && isInlineView) {
|
||||
d = resolveColumnRef(colName);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Now, we only support the columns in the subquery to associate the outer query columns in parent level.
|
||||
|
||||
@ -185,7 +185,7 @@ public class InlineViewRef extends TableRef {
|
||||
|
||||
// Analyze the inline view query statement with its own analyzer
|
||||
inlineViewAnalyzer = new Analyzer(analyzer);
|
||||
|
||||
inlineViewAnalyzer.setInlineView(true);
|
||||
queryStmt.analyze(inlineViewAnalyzer);
|
||||
correlatedTupleIds.addAll(queryStmt.getCorrelatedTupleIds(inlineViewAnalyzer));
|
||||
|
||||
|
||||
@ -1346,6 +1346,11 @@ public class SelectStmt extends QueryStmt {
|
||||
ref.rewriteExprs(rewriter, analyzer);
|
||||
}
|
||||
// Also equal exprs in the statements of subqueries.
|
||||
// TODO: (minghong) if this a view, even no whereClause,
|
||||
// we should analyze whereClause to enable filter inference
|
||||
// for example, a view without where clause, `V`,
|
||||
// `select * from T join V on T.id = V.id and T.id=1`
|
||||
// we could infer `V.id=1`
|
||||
List<Subquery> subqueryExprs = Lists.newArrayList();
|
||||
if (whereClause != null) {
|
||||
whereClause = rewriter.rewrite(whereClause, analyzer, ExprRewriter.ClauseType.WHERE_CLAUSE);
|
||||
|
||||
@ -129,6 +129,9 @@ public class PredicatePushDown {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: (minghong) here is a bug. For example, this is a left join, we cannot infer "t2.id = 1"
|
||||
// by "t1.id=1" and "t1.id=t2.id".
|
||||
// we should not do inference work here. it should be done in some rule like InferFilterRule.
|
||||
// Rewrite the oldPredicate with new leftChild
|
||||
// For example: oldPredicate is t1.id = 1, leftChild is t2.id, will return t2.id = 1
|
||||
private static Expr rewritePredicate(Analyzer analyzer, Expr oldPredicate, Expr leftChild) {
|
||||
|
||||
Reference in New Issue
Block a user