Skip to content
  •  
  •  
  •  
10 changes: 10 additions & 0 deletions fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,16 @@ public static <C extends Expr> boolean containsAggregate(List<? extends Expr> in
return false;
}

public static void extractSlots(Expr root, Set<SlotId> slotIdSet) {
if (root instanceof SlotRef) {
slotIdSet.add(((SlotRef) root).getDesc().getId());
return;
}
for (Expr child : root.getChildren()) {
extractSlots(child, slotIdSet);
}
}

/**
* Returns an analyzed clone of 'this' with exprs substituted according to smap.
* Removes implicit casts and analysis state while cloning/substituting exprs within
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import java.util.List;

public class FunctionGenTable extends Table {
private TableValuedFunctionIf tvf;
private final TableValuedFunctionIf tvf;

public FunctionGenTable(long id, String tableName, TableType type, List<Column> fullSchema,
TableValuedFunctionIf tvf) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@ public class CTEContext {

/* build head CTEContext */
public CTEContext() {
this(null, null, CTEId.DEFAULT);
this(CTEId.DEFAULT, null, null);
}

/**
* CTEContext
*/
public CTEContext(@Nullable LogicalSubQueryAlias<Plan> parsedPlan,
@Nullable CTEContext previousCteContext, CTEId cteId) {
public CTEContext(CTEId cteId, @Nullable LogicalSubQueryAlias<Plan> parsedPlan,
@Nullable CTEContext previousCteContext) {
if ((parsedPlan == null && previousCteContext != null) || (parsedPlan != null && previousCteContext == null)) {
throw new AnalysisException("Only first CteContext can contains null cte plan or previousCteContext");
}
Expand Down Expand Up @@ -78,7 +78,7 @@ public boolean containsCTE(String cteName) {
/**
* Get for CTE reuse.
*/
public Optional<LogicalPlan> getReuse(String cteName) {
public Optional<LogicalPlan> getAnalyzedCTEPlan(String cteName) {
if (!findCTEContext(cteName).isPresent()) {
return Optional.empty();
}
Expand Down
254 changes: 103 additions & 151 deletions fe/fe-core/src/main/java/org/apache/doris/nereids/CascadesContext.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ private LogicalPlan preprocess(LogicalPlan logicalPlan) {
}

private void initCascadesContext(LogicalPlan plan, PhysicalProperties requireProperties) {
cascadesContext = CascadesContext.newRewriteContext(statementContext, plan, requireProperties);
cascadesContext = CascadesContext.initContext(statementContext, plan, requireProperties);
if (statementContext.getConnectContext().getTables() != null) {
cascadesContext.setTables(statementContext.getConnectContext().getTables());
}
Expand All @@ -283,7 +283,7 @@ private void analyze() {
* Logical plan rewrite based on a series of heuristic rules.
*/
private void rewrite() {
new Rewriter(cascadesContext).execute();
Rewriter.getWholeTreeRewriter(cascadesContext).execute();
NereidsTracer.logImportantTime("EndRewritePlan");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,27 @@

import org.apache.doris.analysis.StatementBase;
import org.apache.doris.common.IdGenerator;
import org.apache.doris.common.Pair;
import org.apache.doris.nereids.memo.Group;
import org.apache.doris.nereids.rules.analysis.ColumnAliasGenerator;
import org.apache.doris.nereids.trees.expressions.CTEId;
import org.apache.doris.nereids.trees.expressions.ExprId;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.NamedExpression;
import org.apache.doris.nereids.trees.expressions.Slot;
import org.apache.doris.nereids.trees.plans.ObjectId;
import org.apache.doris.nereids.trees.plans.RelationId;
import org.apache.doris.nereids.trees.plans.logical.LogicalCTEConsumer;
import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
import org.apache.doris.qe.ConnectContext;
import org.apache.doris.qe.OriginStatement;

import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.Maps;

import java.util.HashSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.concurrent.GuardedBy;
Expand All @@ -42,30 +51,32 @@ public class StatementContext {

private ConnectContext connectContext;

@GuardedBy("this")
private final Map<String, Supplier<Object>> contextCacheMap = Maps.newLinkedHashMap();

private OriginStatement originStatement;
// NOTICE: we set the plan parsed by DorisParser to parsedStatement and if the plan is command, create a
// LogicalPlanAdapter with the logical plan in the command.
private StatementBase parsedStatement;
private ColumnAliasGenerator columnAliasGenerator;

private int joinCount = 0;
private int maxNAryInnerJoin = 0;

private boolean isDpHyp = false;
private boolean isOtherJoinReorder = false;

private final IdGenerator<ExprId> exprIdGenerator = ExprId.createGenerator();

private final IdGenerator<ObjectId> objectIdGenerator = ObjectId.createGenerator();

private final IdGenerator<RelationId> relationIdGenerator = RelationId.createGenerator();
private final IdGenerator<CTEId> cteIdGenerator = CTEId.createGenerator();

@GuardedBy("this")
private final Map<String, Supplier<Object>> contextCacheMap = Maps.newLinkedHashMap();

// NOTICE: we set the plan parsed by DorisParser to parsedStatement and if the plan is command, create a
// LogicalPlanAdapter with the logical plan in the command.
private StatementBase parsedStatement;

private Set<String> columnNames;

private ColumnAliasGenerator columnAliasGenerator;
private final Map<CTEId, Set<LogicalCTEConsumer>> cteIdToConsumers = new HashMap<>();
private final Map<CTEId, Set<NamedExpression>> cteIdToProjects = new HashMap<>();
private final Map<RelationId, Set<Expression>> consumerIdToFilters = new HashMap<>();
private final Map<CTEId, Set<RelationId>> cteIdToConsumerUnderProjects = new HashMap<>();
// Used to update consumer's stats
private final Map<CTEId, List<Pair<Map<Slot, Slot>, Group>>> cteIdToConsumerGroup = new HashMap<>();
private final Map<CTEId, LogicalPlan> rewrittenCtePlan = new HashMap<>();

public StatementContext() {
this.connectContext = ConnectContext.get();
Expand All @@ -92,7 +103,7 @@ public OriginStatement getOriginStatement() {
return originStatement;
}

public void setMaxNArayInnerJoin(int maxNAryInnerJoin) {
public void setMaxNAryInnerJoin(int maxNAryInnerJoin) {
if (maxNAryInnerJoin > this.maxNAryInnerJoin) {
this.maxNAryInnerJoin = maxNAryInnerJoin;
}
Expand Down Expand Up @@ -140,6 +151,10 @@ public ObjectId getNextObjectId() {
return objectIdGenerator.getNextId();
}

public RelationId getNextRelationId() {
return relationIdGenerator.getNextId();
}

public void setParsedStatement(StatementBase parsedStatement) {
this.parsedStatement = parsedStatement;
}
Expand All @@ -154,17 +169,9 @@ public synchronized <T> T getOrRegisterCache(String key, Supplier<T> cacheSuppli
return supplier.get();
}

public Set<String> getColumnNames() {
return columnNames == null ? new HashSet<>() : columnNames;
}

public void setColumnNames(Set<String> columnNames) {
this.columnNames = columnNames;
}

public ColumnAliasGenerator getColumnAliasGenerator() {
return columnAliasGenerator == null
? columnAliasGenerator = new ColumnAliasGenerator(this)
? columnAliasGenerator = new ColumnAliasGenerator()
: columnAliasGenerator;
}

Expand All @@ -175,4 +182,28 @@ public String generateColumnName() {
public StatementBase getParsedStatement() {
return parsedStatement;
}

public Map<CTEId, Set<LogicalCTEConsumer>> getCteIdToConsumers() {
return cteIdToConsumers;
}

public Map<CTEId, Set<NamedExpression>> getCteIdToProjects() {
return cteIdToProjects;
}

public Map<RelationId, Set<Expression>> getConsumerIdToFilters() {
return consumerIdToFilters;
}

public Map<CTEId, Set<RelationId>> getCteIdToConsumerUnderProjects() {
return cteIdToConsumerUnderProjects;
}

public Map<CTEId, List<Pair<Map<Slot, Slot>, Group>>> getCteIdToConsumerGroup() {
return cteIdToConsumerGroup;
}

public Map<CTEId, LogicalPlan> getRewrittenCtePlan() {
return rewrittenCtePlan;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,16 @@

package org.apache.doris.nereids.analyzer;

import org.apache.doris.nereids.exceptions.UnboundException;
import org.apache.doris.nereids.memo.GroupExpression;
import org.apache.doris.nereids.properties.LogicalProperties;
import org.apache.doris.nereids.properties.UnboundLogicalProperties;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.Slot;
import org.apache.doris.nereids.trees.plans.Plan;
import org.apache.doris.nereids.trees.plans.PlanType;
import org.apache.doris.nereids.trees.plans.logical.LogicalUnary;
import org.apache.doris.nereids.trees.plans.algebra.Sink;
import org.apache.doris.nereids.trees.plans.logical.LogicalSink;
import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor;
import org.apache.doris.nereids.util.Utils;

Expand All @@ -37,7 +39,8 @@
/**
* Represent an olap table sink plan node that has not been bound.
*/
public class UnboundOlapTableSink<CHILD_TYPE extends Plan> extends LogicalUnary<CHILD_TYPE> implements Unbound {
public class UnboundOlapTableSink<CHILD_TYPE extends Plan> extends LogicalSink<CHILD_TYPE> implements Unbound, Sink {

private final List<String> nameParts;
private final List<String> colNames;
private final List<String> hints;
Expand Down Expand Up @@ -141,6 +144,6 @@ public LogicalProperties computeLogicalProperties() {

@Override
public List<Slot> computeOutput() {
return child().getOutput();
throw new UnboundException("output");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,49 +24,42 @@
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.NamedExpression;
import org.apache.doris.nereids.trees.expressions.Slot;
import org.apache.doris.nereids.trees.plans.ObjectId;
import org.apache.doris.nereids.trees.plans.Plan;
import org.apache.doris.nereids.trees.plans.PlanType;
import org.apache.doris.nereids.trees.plans.RelationId;
import org.apache.doris.nereids.trees.plans.algebra.OneRowRelation;
import org.apache.doris.nereids.trees.plans.logical.LogicalLeaf;
import org.apache.doris.nereids.trees.plans.logical.LogicalRelation;
import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor;
import org.apache.doris.nereids.util.Utils;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;

import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
* A relation that contains only one row consist of some constant expressions.
* e.g. select 100, 'value'
*/
public class UnboundOneRowRelation extends LogicalLeaf implements Unbound, OneRowRelation {
public class UnboundOneRowRelation extends LogicalRelation implements Unbound, OneRowRelation {

private final ObjectId id;
private final List<NamedExpression> projects;

public UnboundOneRowRelation(ObjectId id, List<NamedExpression> projects) {
this(id, projects, Optional.empty(), Optional.empty());
public UnboundOneRowRelation(RelationId relationId, List<NamedExpression> projects) {
this(relationId, projects, Optional.empty(), Optional.empty());
}

private UnboundOneRowRelation(ObjectId id,
private UnboundOneRowRelation(RelationId id,
List<NamedExpression> projects,
Optional<GroupExpression> groupExpression,
Optional<LogicalProperties> logicalProperties) {
super(PlanType.LOGICAL_UNBOUND_ONE_ROW_RELATION, groupExpression, logicalProperties);
super(id, PlanType.LOGICAL_UNBOUND_ONE_ROW_RELATION, groupExpression, logicalProperties);
Preconditions.checkArgument(projects.stream().noneMatch(p -> p.containsType(Slot.class)),
"OneRowRelation can not contains any slot");
this.id = id;
this.projects = ImmutableList.copyOf(projects);
}

public ObjectId getId() {
return id;
}

@Override
public <R, C> R accept(PlanVisitor<R, C> visitor, C context) {
return visitor.visitUnboundOneRowRelation(this, context);
Expand All @@ -84,13 +77,14 @@ public List<? extends Expression> getExpressions() {

@Override
public Plan withGroupExpression(Optional<GroupExpression> groupExpression) {
return new UnboundOneRowRelation(id, projects, groupExpression, Optional.of(logicalPropertiesSupplier.get()));
return new UnboundOneRowRelation(relationId, projects,
groupExpression, Optional.of(logicalPropertiesSupplier.get()));
}

@Override
public Plan withGroupExprLogicalPropChildren(Optional<GroupExpression> groupExpression,
Optional<LogicalProperties> logicalProperties, List<Plan> children) {
return new UnboundOneRowRelation(id, projects, groupExpression, logicalProperties);
return new UnboundOneRowRelation(relationId, projects, groupExpression, logicalProperties);
}

@Override
Expand All @@ -106,28 +100,8 @@ public LogicalProperties computeLogicalProperties() {
@Override
public String toString() {
return Utils.toSqlString("UnboundOneRowRelation",
"relationId", id,
"relationId", relationId,
"projects", projects
);
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
if (!super.equals(o)) {
return false;
}
UnboundOneRowRelation that = (UnboundOneRowRelation) o;
return Objects.equals(id, that.id) && Objects.equals(projects, that.projects);
}

@Override
public int hashCode() {
return Objects.hash(id, projects);
}
}
Loading