[Fix](Lateral View) The Error expr type when exploding a function result of inline view (#8851)

Fixed #8850

The column in inline view maybe a function instead of slotRef.
So when this column is used as the input of explode function,
it can't be converted to slotRef.

The correct way is to treat it as an Expr and extract the required slotRef for materialization.
For example:
```
with d as (select k1+k1 as k1_plus from table)
select k1_plus from d explode_split(k1_plus, ",")
```
FnExp: SlorRef<k1_plus>
SubstituteFnExpr: functionCallExpr<k1+k1>
originSlotRefList: SlotRef<k1>
This commit is contained in:
EmmyMiao87
2022-04-08 09:08:55 +08:00
committed by GitHub
parent 318feb01f3
commit e3daa9580a
2 changed files with 17 additions and 6 deletions

View File

@ -26,7 +26,6 @@ import org.apache.doris.common.UserException;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import java.util.ArrayList;
import java.util.List;
/**
@ -42,7 +41,7 @@ public class LateralViewRef extends TableRef {
// after analyzed
private FunctionCallExpr fnExpr;
private ArrayList<Expr> originSlotRefList = Lists.newArrayList();
private List<SlotRef> originSlotRefList = Lists.newArrayList();
private InlineView view;
private SlotRef explodeSlotRef;
@ -98,7 +97,6 @@ public class LateralViewRef extends TableRef {
for (Expr expr : fnExpr.getChildren()) {
checkScalarFunction(expr);
}
fnExpr.collect(SlotRef.class, originSlotRefList);
}
@Override
@ -116,11 +114,13 @@ public class LateralViewRef extends TableRef {
}
public void materializeRequiredSlots(ExprSubstitutionMap baseTblSmap, Analyzer analyzer) throws AnalysisException {
Expr substituteFnExpr = fnExpr;
if (relatedTableRef instanceof InlineViewRef) {
originSlotRefList = Expr.trySubstituteList(originSlotRefList, baseTblSmap, analyzer, false);
substituteFnExpr = fnExpr.trySubstitute(baseTblSmap, analyzer, false);
}
for (Expr originSlotRef : originSlotRefList) {
((SlotRef) originSlotRef).getDesc().setIsMaterialized(true);
substituteFnExpr.collect(SlotRef.class, originSlotRefList);
for (SlotRef originSlotRef : originSlotRefList) {
originSlotRef.getDesc().setIsMaterialized(true);
}
explodeSlotRef.getDesc().setIsMaterialized(true);
}

View File

@ -527,4 +527,15 @@ public class TableFunctionPlanTest {
String explainString = UtFrameUtils.getSQLPlanOrErrorMsg(ctx, sql, true);
Assert.assertTrue(!explainString.contains("Unknown column 'e1' in 'table list'"));
}
// The 'k1' column in 'd' view should be materialized
// Fix #8850
@Test
public void testLateralViewWithInlineViewBug() throws Exception {
String sql = "with d as (select k1+k1 as k1 from db1.table_for_view ) "
+ "select k1 from d lateral view explode_split(k1,',') tmp as e1;";
String explainString = UtFrameUtils.getSQLPlanOrErrorMsg(ctx, sql, true);
Assert.assertTrue(!explainString.contains("Unexpected exception: org.apache.doris.analysis.FunctionCallExpr cannot be cast to org.apache.doris.analysis.SlotRef"));
}
}