[fix](Nereids) null type result with alias name should keep alias name (#37457) (#37524)

pick from master #37457
This commit is contained in:
morrySnow
2024-07-09 20:46:51 +08:00
committed by GitHub
parent 8ef83259ff
commit db4d061a68
4 changed files with 44 additions and 30 deletions

View File

@ -42,7 +42,6 @@ import org.apache.doris.nereids.rules.RuleType;
import org.apache.doris.nereids.rules.expression.ExpressionRewriteContext;
import org.apache.doris.nereids.trees.expressions.Alias;
import org.apache.doris.nereids.trees.expressions.BoundStar;
import org.apache.doris.nereids.trees.expressions.Cast;
import org.apache.doris.nereids.trees.expressions.DefaultValueSlot;
import org.apache.doris.nereids.trees.expressions.EqualTo;
import org.apache.doris.nereids.trees.expressions.ExprId;
@ -90,11 +89,8 @@ import org.apache.doris.nereids.trees.plans.logical.LogicalTVFRelation;
import org.apache.doris.nereids.trees.plans.logical.UsingJoin;
import org.apache.doris.nereids.trees.plans.visitor.InferPlanOutputAlias;
import org.apache.doris.nereids.types.BooleanType;
import org.apache.doris.nereids.types.DataType;
import org.apache.doris.nereids.types.NullType;
import org.apache.doris.nereids.types.StructField;
import org.apache.doris.nereids.types.StructType;
import org.apache.doris.nereids.types.TinyIntType;
import org.apache.doris.nereids.util.ExpressionUtils;
import org.apache.doris.nereids.util.PlanUtils;
import org.apache.doris.nereids.util.TypeCoercionUtils;
@ -212,38 +208,22 @@ public class BindExpression implements AnalysisRuleFactory {
private LogicalResultSink<Plan> bindResultSink(MatchingContext<UnboundResultSink<Plan>> ctx) {
LogicalSink<Plan> sink = ctx.root;
Plan child = sink.child();
List<Slot> output = child.getOutput();
List<NamedExpression> castNullToTinyInt = Lists.newArrayListWithCapacity(output.size());
boolean needProject = false;
for (Slot slot : output) {
DataType newType = TypeCoercionUtils.replaceSpecifiedType(
slot.getDataType(), NullType.class, TinyIntType.INSTANCE);
if (!newType.equals(slot.getDataType())) {
needProject = true;
castNullToTinyInt.add(new Alias(new Cast(slot, newType)));
} else {
castNullToTinyInt.add(slot);
}
}
if (needProject) {
child = new LogicalProject<>(castNullToTinyInt, child);
}
if (ctx.connectContext.getState().isQuery()) {
List<NamedExpression> outputExprs = child.getOutput().stream()
List<NamedExpression> outputExprs = sink.child().getOutput().stream()
.map(NamedExpression.class::cast)
.collect(ImmutableList.toImmutableList());
return new LogicalResultSink<>(outputExprs, child);
return new LogicalResultSink<>(outputExprs, sink.child());
}
// Should infer column name for expression when query command
final ImmutableListMultimap.Builder<ExprId, Integer> exprIdToIndexMapBuilder = ImmutableListMultimap.builder();
List<Slot> childOutput = child.getOutput();
final ImmutableListMultimap.Builder<ExprId, Integer> exprIdToIndexMapBuilder =
ImmutableListMultimap.builder();
List<Slot> childOutput = sink.child().getOutput();
for (int index = 0; index < childOutput.size(); index++) {
exprIdToIndexMapBuilder.put(childOutput.get(index).getExprId(), index);
}
InferPlanOutputAlias aliasInfer = new InferPlanOutputAlias(childOutput);
List<NamedExpression> sinkExpr = aliasInfer.infer(child, exprIdToIndexMapBuilder.build());
return new LogicalResultSink<>(sinkExpr, child);
List<NamedExpression> output = aliasInfer.infer(sink.child(), exprIdToIndexMapBuilder.build());
return new LogicalResultSink<>(output, sink.child());
}
private LogicalSubQueryAlias<Plan> bindSubqueryAlias(MatchingContext<LogicalSubQueryAlias<Plan>> ctx) {

View File

@ -66,6 +66,9 @@ import org.apache.doris.nereids.trees.plans.logical.LogicalSubQueryAlias;
import org.apache.doris.nereids.trees.plans.visitor.NondeterministicFunctionCollector;
import org.apache.doris.nereids.types.AggStateType;
import org.apache.doris.nereids.types.DataType;
import org.apache.doris.nereids.types.NullType;
import org.apache.doris.nereids.types.TinyIntType;
import org.apache.doris.nereids.util.TypeCoercionUtils;
import org.apache.doris.nereids.util.Utils;
import org.apache.doris.qe.ConnectContext;
import org.apache.doris.qe.SessionVariable;
@ -372,7 +375,8 @@ public class CreateMTMVInfo {
// If datatype is AggStateType, AggregateType should be generic, or column definition check will fail
columns.add(new ColumnDefinition(
colName,
slots.get(i).getDataType(),
TypeCoercionUtils.replaceSpecifiedType(slots.get(i).getDataType(),
NullType.class, TinyIntType.INSTANCE),
false,
slots.get(i).getDataType() instanceof AggStateType ? AggregateType.GENERIC : null,
slots.get(i).nullable(),