[feature](Nereids) support values inline table in query (#28972)

This commit is contained in:
morrySnow
2023-12-26 15:51:08 +08:00
committed by GitHub
parent 3ea9ff7d4a
commit d672e321cc
3 changed files with 28 additions and 12 deletions

View File

@ -57,7 +57,7 @@ statement
partitionSpec? // partition define
(WITH LABEL labelName=identifier)? cols=identifierList? // label and columns define
(LEFT_BRACKET hints=identifierSeq RIGHT_BRACKET)? // hint define
(query | inlineTable) #insertTable
query #insertTable
| explain? cte? UPDATE tableName=multipartIdentifier tableAlias
SET updateAssignmentSeq
fromClause?
@ -287,6 +287,7 @@ setQuantifier
queryPrimary
: querySpecification #queryPrimaryDefault
| LEFT_PAREN query RIGHT_PAREN #subquery
| inlineTable #valuesTable
;
querySpecification

View File

@ -488,7 +488,7 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> {
List<String> colNames = ctx.cols == null ? ImmutableList.of() : visitIdentifierList(ctx.cols);
// TODO visit partitionSpecCtx
Pair<Boolean, List<String>> partitionSpec = visitPartitionSpec(ctx.partitionSpec());
LogicalPlan plan = ctx.query() != null ? visitQuery(ctx.query()) : visitInlineTable(ctx.inlineTable());
LogicalPlan plan = visitQuery(ctx.query());
UnboundTableSink<?> sink = new UnboundTableSink<>(
tableName.build(),
colNames,

View File

@ -27,6 +27,7 @@ import org.apache.doris.nereids.analyzer.UnboundOneRowRelation;
import org.apache.doris.nereids.analyzer.UnboundSlot;
import org.apache.doris.nereids.analyzer.UnboundTVFRelation;
import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.parser.LogicalPlanBuilder;
import org.apache.doris.nereids.properties.OrderKey;
import org.apache.doris.nereids.rules.AppliedAwareRule.AppliedAwareRuleCondition;
import org.apache.doris.nereids.rules.Rule;
@ -36,6 +37,7 @@ import org.apache.doris.nereids.rules.expression.rules.FunctionBinder;
import org.apache.doris.nereids.trees.UnaryNode;
import org.apache.doris.nereids.trees.expressions.Alias;
import org.apache.doris.nereids.trees.expressions.BoundStar;
import org.apache.doris.nereids.trees.expressions.DefaultValueSlot;
import org.apache.doris.nereids.trees.expressions.EqualTo;
import org.apache.doris.nereids.trees.expressions.ExprId;
import org.apache.doris.nereids.trees.expressions.Expression;
@ -43,6 +45,7 @@ import org.apache.doris.nereids.trees.expressions.NamedExpression;
import org.apache.doris.nereids.trees.expressions.Properties;
import org.apache.doris.nereids.trees.expressions.Slot;
import org.apache.doris.nereids.trees.expressions.SlotReference;
import org.apache.doris.nereids.trees.expressions.StatementScopeIdGenerator;
import org.apache.doris.nereids.trees.expressions.functions.BoundFunction;
import org.apache.doris.nereids.trees.expressions.functions.Function;
import org.apache.doris.nereids.trees.expressions.functions.FunctionBuilder;
@ -67,6 +70,7 @@ import org.apache.doris.nereids.trees.plans.logical.LogicalInlineTable;
import org.apache.doris.nereids.trees.plans.logical.LogicalIntersect;
import org.apache.doris.nereids.trees.plans.logical.LogicalJoin;
import org.apache.doris.nereids.trees.plans.logical.LogicalOneRowRelation;
import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
import org.apache.doris.nereids.trees.plans.logical.LogicalProject;
import org.apache.doris.nereids.trees.plans.logical.LogicalRepeat;
import org.apache.doris.nereids.trees.plans.logical.LogicalResultSink;
@ -87,6 +91,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.apache.commons.lang3.StringUtils;
@ -528,6 +533,26 @@ public class BindExpression implements AnalysisRuleFactory {
return new LogicalHaving<>(boundConjuncts, having.child());
})
),
RuleType.BINDING_INLINE_TABLE_SLOT.build(
logicalInlineTable().thenApply(ctx -> {
LogicalInlineTable logicalInlineTable = ctx.root;
// ensure all expressions are valid.
List<LogicalPlan> relations
= Lists.newArrayListWithCapacity(logicalInlineTable.getConstantExprsList().size());
for (int i = 0; i < logicalInlineTable.getConstantExprsList().size(); i++) {
if (logicalInlineTable.getConstantExprsList().get(i).stream()
.anyMatch(DefaultValueSlot.class::isInstance)) {
throw new AnalysisException("Default expression"
+ " can't exist in SELECT statement at row " + (i + 1));
}
relations.add(new UnboundOneRowRelation(StatementScopeIdGenerator.newRelationId(),
logicalInlineTable.getConstantExprsList().get(i)));
}
// construct union all tree
return LogicalPlanBuilder.reduceToLogicalPlanTree(0, relations.size() - 1,
relations, Qualifier.ALL);
})
),
RuleType.BINDING_ONE_ROW_RELATION_SLOT.build(
// we should bind UnboundAlias in the UnboundOneRowRelation
unboundOneRowRelation().thenApply(ctx -> {
@ -540,16 +565,6 @@ public class BindExpression implements AnalysisRuleFactory {
return new LogicalOneRowRelation(oneRowRelation.getRelationId(), projects);
})
),
RuleType.BINDING_INLINE_TABLE_SLOT.build(
logicalInlineTable().thenApply(ctx -> {
LogicalInlineTable logicalInlineTable = ctx.root;
// ensure all expressions are valid.
logicalInlineTable.getExpressions().forEach(expr ->
bindSlot(expr, ImmutableList.of(), ctx.cascadesContext, false)
);
return null;
})
),
RuleType.BINDING_SET_OPERATION_SLOT.build(
// LogicalSetOperation don't bind again if LogicalSetOperation.outputs is not empty, this is special
// we should not remove LogicalSetOperation::canBind, because in default case, the plan can run into