[feature](Nereids)add RelationId as a unique identifier of relations (#12461)
In Nereids, we could not distinguish two relation from same table in one PlanTree. This lead to some trick code to process them when do plan. Such as a separate branch to do equals in GroupExpression. This PR add RelationId to LogicalRelation and PhysicalRelation. Then all relations equals function will compare RelationId to help us distinguish two relation from same table. TODO: add relation id to UnboundRelation, UnboundOneRowRelation, LogicalOneRowRelation, PhysicalOneRowRelation.
This commit is contained in:
@ -18,6 +18,8 @@
|
||||
package org.apache.doris.nereids;
|
||||
|
||||
import org.apache.doris.analysis.StatementBase;
|
||||
import org.apache.doris.common.IdGenerator;
|
||||
import org.apache.doris.nereids.trees.plans.RelationId;
|
||||
import org.apache.doris.qe.ConnectContext;
|
||||
import org.apache.doris.qe.OriginStatement;
|
||||
|
||||
@ -28,6 +30,8 @@ public class StatementContext {
|
||||
private final ConnectContext connectContext;
|
||||
private final OriginStatement originStatement;
|
||||
|
||||
private final IdGenerator<RelationId> idGenerator = RelationId.createGenerator();
|
||||
|
||||
private StatementBase parsedStatement;
|
||||
|
||||
public StatementContext(ConnectContext connectContext, OriginStatement originStatement) {
|
||||
@ -47,6 +51,10 @@ public class StatementContext {
|
||||
return parsedStatement;
|
||||
}
|
||||
|
||||
public RelationId getNextId() {
|
||||
return idGenerator.getNextId();
|
||||
}
|
||||
|
||||
public void setParsedStatement(StatementBase parsedStatement) {
|
||||
this.parsedStatement = parsedStatement;
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
package org.apache.doris.nereids.memo;
|
||||
|
||||
import org.apache.doris.common.Pair;
|
||||
import org.apache.doris.nereids.analyzer.Relation;
|
||||
import org.apache.doris.nereids.analyzer.UnboundRelation;
|
||||
import org.apache.doris.nereids.properties.PhysicalProperties;
|
||||
import org.apache.doris.nereids.rules.Rule;
|
||||
import org.apache.doris.nereids.rules.RuleType;
|
||||
@ -210,9 +210,8 @@ public class GroupExpression {
|
||||
return false;
|
||||
}
|
||||
GroupExpression that = (GroupExpression) o;
|
||||
// FIXME: Doris not support temporary materialization, so we should not merge same
|
||||
// scan relation plan. We should add id for XxxRelation and compare by id.
|
||||
if (plan instanceof Relation) {
|
||||
// TODO: add relation id to UnboundRelation
|
||||
if (plan instanceof UnboundRelation) {
|
||||
return false;
|
||||
}
|
||||
return children.equals(that.children) && plan.equals(that.plan)
|
||||
|
||||
@ -23,5 +23,5 @@ import org.apache.doris.nereids.trees.plans.visitor.DefaultPlanRewriter;
|
||||
/**
|
||||
* PlanPostprocessor: a PlanVisitor to rewrite PhysicalPlan to new PhysicalPlan.
|
||||
*/
|
||||
public class PlanPostprocessor extends DefaultPlanRewriter<CascadesContext> {
|
||||
public class PlanPostProcessor extends DefaultPlanRewriter<CascadesContext> {
|
||||
}
|
||||
@ -37,13 +37,13 @@ public class PlanPostProcessors {
|
||||
|
||||
public PhysicalPlan process(PhysicalPlan physicalPlan) {
|
||||
PhysicalPlan resultPlan = physicalPlan;
|
||||
for (PlanPostprocessor processor : getProcessors()) {
|
||||
for (PlanPostProcessor processor : getProcessors()) {
|
||||
resultPlan = (PhysicalPlan) physicalPlan.accept(processor, cascadesContext);
|
||||
}
|
||||
return resultPlan;
|
||||
}
|
||||
|
||||
public List<PlanPostprocessor> getProcessors() {
|
||||
public List<PlanPostProcessor> getProcessors() {
|
||||
// add processor if we need
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
@ -78,7 +78,8 @@ public class BindRelation extends OneAnalysisRuleFactory {
|
||||
Table table = getTable(dbName, nameParts.get(0), cascadesContext.getConnectContext().getEnv());
|
||||
// TODO: should generate different Scan sub class according to table's type
|
||||
if (table.getType() == TableType.OLAP) {
|
||||
return new LogicalOlapScan((OlapTable) table, ImmutableList.of(dbName));
|
||||
return new LogicalOlapScan(cascadesContext.getStatementContext().getNextId(),
|
||||
(OlapTable) table, ImmutableList.of(dbName));
|
||||
} else if (table.getType() == TableType.VIEW) {
|
||||
Plan viewPlan = parseAndAnalyzeView(table.getDdlSql(), cascadesContext);
|
||||
return new LogicalSubQueryAlias<>(table.getName(), viewPlan);
|
||||
@ -95,7 +96,8 @@ public class BindRelation extends OneAnalysisRuleFactory {
|
||||
}
|
||||
Table table = getTable(dbName, nameParts.get(1), connectContext.getEnv());
|
||||
if (table.getType() == TableType.OLAP) {
|
||||
return new LogicalOlapScan((OlapTable) table, ImmutableList.of(dbName));
|
||||
return new LogicalOlapScan(cascadesContext.getStatementContext().getNextId(),
|
||||
(OlapTable) table, ImmutableList.of(dbName));
|
||||
} else if (table.getType() == TableType.VIEW) {
|
||||
Plan viewPlan = parseAndAnalyzeView(table.getDdlSql(), cascadesContext);
|
||||
return new LogicalSubQueryAlias<>(table.getName(), viewPlan);
|
||||
|
||||
@ -46,6 +46,7 @@ public class LogicalOlapScanToPhysicalOlapScan extends OneImplementationRuleFact
|
||||
public Rule build() {
|
||||
return logicalOlapScan().then(olapScan ->
|
||||
new PhysicalOlapScan(
|
||||
olapScan.getId(),
|
||||
olapScan.getTable(),
|
||||
olapScan.getQualifier(),
|
||||
olapScan.getSelectedIndexId(),
|
||||
|
||||
@ -0,0 +1,71 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.trees.plans;
|
||||
|
||||
import org.apache.doris.common.Id;
|
||||
import org.apache.doris.common.IdGenerator;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* relation id
|
||||
*/
|
||||
public class RelationId extends Id<RelationId> {
|
||||
public RelationId(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
RelationId relationId = (RelationId) o;
|
||||
return id == relationId.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should be only called by {@link org.apache.doris.nereids.trees.expressions.NamedExpressionUtil}.
|
||||
*/
|
||||
public static IdGenerator<RelationId> createGenerator() {
|
||||
return new IdGenerator<RelationId>() {
|
||||
@Override
|
||||
public RelationId getNextId() {
|
||||
return new RelationId(nextId++);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RelationId getMaxId() {
|
||||
return new RelationId(nextId);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RelationId#" + id;
|
||||
}
|
||||
}
|
||||
@ -24,6 +24,7 @@ import org.apache.doris.nereids.memo.GroupExpression;
|
||||
import org.apache.doris.nereids.properties.LogicalProperties;
|
||||
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.visitor.PlanVisitor;
|
||||
import org.apache.doris.nereids.util.Utils;
|
||||
|
||||
@ -34,6 +35,7 @@ import com.google.common.collect.Lists;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
@ -48,27 +50,28 @@ public class LogicalOlapScan extends LogicalRelation {
|
||||
private final List<Long> candidateIndexIds;
|
||||
private final boolean rollupSelected;
|
||||
|
||||
public LogicalOlapScan(OlapTable table) {
|
||||
this(table, ImmutableList.of());
|
||||
public LogicalOlapScan(RelationId id, OlapTable table) {
|
||||
this(id, table, ImmutableList.of());
|
||||
}
|
||||
|
||||
public LogicalOlapScan(OlapTable table, List<String> qualifier) {
|
||||
this(table, qualifier, Optional.empty(), Optional.empty(),
|
||||
public LogicalOlapScan(RelationId id, OlapTable table, List<String> qualifier) {
|
||||
this(id, table, qualifier, Optional.empty(), Optional.empty(),
|
||||
table.getPartitionIds(), false, ImmutableList.of(), false);
|
||||
}
|
||||
|
||||
public LogicalOlapScan(Table table, List<String> qualifier) {
|
||||
this(table, qualifier, Optional.empty(), Optional.empty(),
|
||||
public LogicalOlapScan(RelationId id, Table table, List<String> qualifier) {
|
||||
this(id, table, qualifier, Optional.empty(), Optional.empty(),
|
||||
((OlapTable) table).getPartitionIds(), false, ImmutableList.of(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for LogicalOlapScan.
|
||||
*/
|
||||
public LogicalOlapScan(Table table, List<String> qualifier, Optional<GroupExpression> groupExpression,
|
||||
Optional<LogicalProperties> logicalProperties, List<Long> selectedPartitionIdList,
|
||||
boolean partitionPruned, List<Long> candidateIndexIds, boolean rollupSelected) {
|
||||
super(PlanType.LOGICAL_OLAP_SCAN, table, qualifier,
|
||||
public LogicalOlapScan(RelationId id, Table table, List<String> qualifier,
|
||||
Optional<GroupExpression> groupExpression, Optional<LogicalProperties> logicalProperties,
|
||||
List<Long> selectedPartitionIdList, boolean partitionPruned, List<Long> candidateIndexIds,
|
||||
boolean rollupSelected) {
|
||||
super(id, PlanType.LOGICAL_OLAP_SCAN, table, qualifier,
|
||||
groupExpression, logicalProperties, selectedPartitionIdList);
|
||||
// TODO: use CBO manner to select best index id, according to index's statistics info,
|
||||
// revisit this after rollup and materialized view selection are fully supported.
|
||||
@ -107,28 +110,34 @@ public class LogicalOlapScan extends LogicalRelation {
|
||||
if (o == null || getClass() != o.getClass() || !super.equals(o)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return Objects.equals(selectedPartitionIds, ((LogicalOlapScan) o).selectedPartitionIds)
|
||||
&& Objects.equals(candidateIndexIds, ((LogicalOlapScan) o).candidateIndexIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, selectedPartitionIds, candidateIndexIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plan withGroupExpression(Optional<GroupExpression> groupExpression) {
|
||||
return new LogicalOlapScan(table, qualifier, groupExpression, Optional.of(getLogicalProperties()),
|
||||
return new LogicalOlapScan(id, table, qualifier, groupExpression, Optional.of(getLogicalProperties()),
|
||||
selectedPartitionIds, partitionPruned, candidateIndexIds, rollupSelected);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LogicalOlapScan withLogicalProperties(Optional<LogicalProperties> logicalProperties) {
|
||||
return new LogicalOlapScan(table, qualifier, Optional.empty(), logicalProperties, selectedPartitionIds,
|
||||
return new LogicalOlapScan(id, table, qualifier, Optional.empty(), logicalProperties, selectedPartitionIds,
|
||||
partitionPruned, candidateIndexIds, rollupSelected);
|
||||
}
|
||||
|
||||
public LogicalOlapScan withSelectedPartitionId(List<Long> selectedPartitionId) {
|
||||
return new LogicalOlapScan(table, qualifier, Optional.empty(), Optional.of(getLogicalProperties()),
|
||||
return new LogicalOlapScan(id, table, qualifier, Optional.empty(), Optional.of(getLogicalProperties()),
|
||||
selectedPartitionId, true, candidateIndexIds, rollupSelected);
|
||||
}
|
||||
|
||||
public LogicalOlapScan withCandidateIndexIds(List<Long> candidateIndexIds) {
|
||||
return new LogicalOlapScan(table, qualifier, Optional.empty(), Optional.of(getLogicalProperties()),
|
||||
return new LogicalOlapScan(id, table, qualifier, Optional.empty(), Optional.of(getLogicalProperties()),
|
||||
selectedPartitionIds, partitionPruned, candidateIndexIds, true);
|
||||
}
|
||||
|
||||
|
||||
@ -24,6 +24,7 @@ import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.expressions.Slot;
|
||||
import org.apache.doris.nereids.trees.expressions.SlotReference;
|
||||
import org.apache.doris.nereids.trees.plans.PlanType;
|
||||
import org.apache.doris.nereids.trees.plans.RelationId;
|
||||
import org.apache.doris.nereids.trees.plans.algebra.Scan;
|
||||
import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor;
|
||||
import org.apache.doris.nereids.util.Utils;
|
||||
@ -44,8 +45,10 @@ public abstract class LogicalRelation extends LogicalLeaf implements Scan {
|
||||
protected final List<String> qualifier;
|
||||
protected final List<Long> selectedPartitionIds;
|
||||
|
||||
public LogicalRelation(PlanType type, Table table, List<String> qualifier) {
|
||||
this(type, table, qualifier, Optional.empty(), Optional.empty(), Collections.emptyList());
|
||||
protected final RelationId id;
|
||||
|
||||
public LogicalRelation(RelationId id, PlanType type, Table table, List<String> qualifier) {
|
||||
this(id, type, table, qualifier, Optional.empty(), Optional.empty(), Collections.emptyList());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -54,7 +57,7 @@ public abstract class LogicalRelation extends LogicalLeaf implements Scan {
|
||||
* @param table Doris table
|
||||
* @param qualifier qualified relation name
|
||||
*/
|
||||
public LogicalRelation(PlanType type, Table table, List<String> qualifier,
|
||||
public LogicalRelation(RelationId id, PlanType type, Table table, List<String> qualifier,
|
||||
Optional<GroupExpression> groupExpression, Optional<LogicalProperties> logicalProperties,
|
||||
List<Long> selectedPartitionIds) {
|
||||
super(type, groupExpression, logicalProperties);
|
||||
@ -62,8 +65,10 @@ public abstract class LogicalRelation extends LogicalLeaf implements Scan {
|
||||
this.qualifier = ImmutableList.copyOf(Objects.requireNonNull(qualifier, "qualifier can not be null"));
|
||||
this.selectedPartitionIds = ImmutableList.copyOf(
|
||||
Objects.requireNonNull(selectedPartitionIds, "selectedPartitionIds can not be null"));
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Table getTable() {
|
||||
return table;
|
||||
}
|
||||
@ -81,12 +86,14 @@ public abstract class LogicalRelation extends LogicalLeaf implements Scan {
|
||||
return false;
|
||||
}
|
||||
LogicalRelation that = (LogicalRelation) o;
|
||||
return Objects.equals(table.getId(), that.table.getId()) && Objects.equals(qualifier, that.qualifier);
|
||||
return this.id.equals(that.getId())
|
||||
&& Objects.equals(this.table.getId(), that.table.getId())
|
||||
&& Objects.equals(this.qualifier, that.qualifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(table.getId(), qualifier);
|
||||
return Objects.hash(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -125,4 +132,7 @@ public abstract class LogicalRelation extends LogicalLeaf implements Scan {
|
||||
return selectedPartitionIds;
|
||||
}
|
||||
|
||||
public RelationId getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ import org.apache.doris.nereids.properties.DistributionSpec;
|
||||
import org.apache.doris.nereids.properties.LogicalProperties;
|
||||
import org.apache.doris.nereids.properties.PhysicalProperties;
|
||||
import org.apache.doris.nereids.trees.plans.PlanType;
|
||||
import org.apache.doris.nereids.trees.plans.RelationId;
|
||||
import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor;
|
||||
import org.apache.doris.nereids.util.Utils;
|
||||
|
||||
@ -43,10 +44,10 @@ public class PhysicalOlapScan extends PhysicalRelation {
|
||||
/**
|
||||
* Constructor for PhysicalOlapScan.
|
||||
*/
|
||||
public PhysicalOlapScan(OlapTable olapTable, List<String> qualifier, long selectedIndexId,
|
||||
public PhysicalOlapScan(RelationId id, OlapTable olapTable, List<String> qualifier, long selectedIndexId,
|
||||
List<Long> selectedTabletIds, List<Long> selectedPartitionIds, DistributionSpec distributionSpec,
|
||||
Optional<GroupExpression> groupExpression, LogicalProperties logicalProperties) {
|
||||
super(PlanType.PHYSICAL_OLAP_SCAN, qualifier, groupExpression, logicalProperties);
|
||||
super(id, PlanType.PHYSICAL_OLAP_SCAN, qualifier, groupExpression, logicalProperties);
|
||||
this.olapTable = olapTable;
|
||||
this.selectedIndexId = selectedIndexId;
|
||||
this.selectedTabletIds = selectedTabletIds;
|
||||
@ -57,11 +58,11 @@ public class PhysicalOlapScan extends PhysicalRelation {
|
||||
/**
|
||||
* Constructor for PhysicalOlapScan.
|
||||
*/
|
||||
public PhysicalOlapScan(OlapTable olapTable, List<String> qualifier, long selectedIndexId,
|
||||
public PhysicalOlapScan(RelationId id, OlapTable olapTable, List<String> qualifier, long selectedIndexId,
|
||||
List<Long> selectedTabletId, List<Long> selectedPartitionId, DistributionSpec distributionSpec,
|
||||
Optional<GroupExpression> groupExpression, LogicalProperties logicalProperties,
|
||||
PhysicalProperties physicalProperties) {
|
||||
super(PlanType.PHYSICAL_OLAP_SCAN, qualifier, groupExpression, logicalProperties, physicalProperties);
|
||||
super(id, PlanType.PHYSICAL_OLAP_SCAN, qualifier, groupExpression, logicalProperties, physicalProperties);
|
||||
|
||||
this.olapTable = olapTable;
|
||||
this.selectedIndexId = selectedIndexId;
|
||||
@ -82,6 +83,7 @@ public class PhysicalOlapScan extends PhysicalRelation {
|
||||
return selectedPartitionIds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OlapTable getTable() {
|
||||
return olapTable;
|
||||
}
|
||||
@ -106,16 +108,16 @@ public class PhysicalOlapScan extends PhysicalRelation {
|
||||
if (o == null || getClass() != o.getClass() || !super.equals(o)) {
|
||||
return false;
|
||||
}
|
||||
PhysicalOlapScan that = (PhysicalOlapScan) o;
|
||||
return selectedIndexId == that.selectedIndexId
|
||||
&& Objects.equals(selectedTabletIds, that.selectedTabletIds)
|
||||
PhysicalOlapScan that = ((PhysicalOlapScan) o);
|
||||
return Objects.equals(selectedIndexId, that.selectedIndexId)
|
||||
&& Objects.equals(selectedTabletIds, that.selectedPartitionIds)
|
||||
&& Objects.equals(selectedPartitionIds, that.selectedPartitionIds)
|
||||
&& Objects.equals(olapTable, that.olapTable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(selectedIndexId, selectedPartitionIds, selectedTabletIds, olapTable);
|
||||
return Objects.hash(id, selectedIndexId, selectedPartitionIds, selectedTabletIds, olapTable);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -125,19 +127,19 @@ public class PhysicalOlapScan extends PhysicalRelation {
|
||||
|
||||
@Override
|
||||
public PhysicalOlapScan withGroupExpression(Optional<GroupExpression> groupExpression) {
|
||||
return new PhysicalOlapScan(olapTable, qualifier, selectedIndexId, selectedTabletIds, selectedPartitionIds,
|
||||
distributionSpec, groupExpression, getLogicalProperties());
|
||||
return new PhysicalOlapScan(id, olapTable, qualifier, selectedIndexId, selectedTabletIds,
|
||||
selectedPartitionIds, distributionSpec, groupExpression, getLogicalProperties());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PhysicalOlapScan withLogicalProperties(Optional<LogicalProperties> logicalProperties) {
|
||||
return new PhysicalOlapScan(olapTable, qualifier, selectedIndexId, selectedTabletIds, selectedPartitionIds,
|
||||
distributionSpec, Optional.empty(), logicalProperties.get());
|
||||
return new PhysicalOlapScan(id, olapTable, qualifier, selectedIndexId, selectedTabletIds,
|
||||
selectedPartitionIds, distributionSpec, Optional.empty(), logicalProperties.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PhysicalOlapScan withPhysicalProperties(PhysicalProperties physicalProperties) {
|
||||
return new PhysicalOlapScan(olapTable, qualifier, selectedIndexId, selectedTabletIds, selectedPartitionIds,
|
||||
distributionSpec, Optional.empty(), getLogicalProperties(), physicalProperties);
|
||||
return new PhysicalOlapScan(id, olapTable, qualifier, selectedIndexId, selectedTabletIds,
|
||||
selectedPartitionIds, distributionSpec, Optional.empty(), getLogicalProperties(), physicalProperties);
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,6 +22,7 @@ import org.apache.doris.nereids.properties.LogicalProperties;
|
||||
import org.apache.doris.nereids.properties.PhysicalProperties;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.plans.PlanType;
|
||||
import org.apache.doris.nereids.trees.plans.RelationId;
|
||||
import org.apache.doris.nereids.trees.plans.algebra.Scan;
|
||||
import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor;
|
||||
|
||||
@ -38,22 +39,27 @@ public abstract class PhysicalRelation extends PhysicalLeaf implements Scan {
|
||||
|
||||
protected final List<String> qualifier;
|
||||
|
||||
protected final RelationId id;
|
||||
|
||||
/**
|
||||
* Constructor for PhysicalRelation.
|
||||
*/
|
||||
public PhysicalRelation(PlanType type, List<String> qualifier,
|
||||
public PhysicalRelation(RelationId id, PlanType type, List<String> qualifier,
|
||||
Optional<GroupExpression> groupExpression, LogicalProperties logicalProperties) {
|
||||
super(type, groupExpression, logicalProperties);
|
||||
this.qualifier = Objects.requireNonNull(qualifier, "qualifier can not be null");
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for PhysicalRelation.
|
||||
*/
|
||||
public PhysicalRelation(PlanType type, List<String> qualifier, Optional<GroupExpression> groupExpression,
|
||||
LogicalProperties logicalProperties, PhysicalProperties physicalProperties) {
|
||||
public PhysicalRelation(RelationId id, PlanType type, List<String> qualifier,
|
||||
Optional<GroupExpression> groupExpression, LogicalProperties logicalProperties,
|
||||
PhysicalProperties physicalProperties) {
|
||||
super(type, groupExpression, logicalProperties, physicalProperties);
|
||||
this.qualifier = Objects.requireNonNull(qualifier, "qualifier can not be null");
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public List<String> getQualifier() {
|
||||
@ -69,7 +75,7 @@ public abstract class PhysicalRelation extends PhysicalLeaf implements Scan {
|
||||
return false;
|
||||
}
|
||||
PhysicalRelation that = (PhysicalRelation) o;
|
||||
return Objects.equals(qualifier, that.qualifier);
|
||||
return this.id.equals(that.id) && Objects.equals(qualifier, that.qualifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -86,4 +92,8 @@ public abstract class PhysicalRelation extends PhysicalLeaf implements Scan {
|
||||
public List<Expression> getExpressions() {
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
public RelationId getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,6 +27,7 @@ import org.apache.doris.nereids.trees.expressions.Slot;
|
||||
import org.apache.doris.nereids.trees.expressions.SlotReference;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.Literal;
|
||||
import org.apache.doris.nereids.trees.plans.RelationId;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalFilter;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalOlapScan;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalProject;
|
||||
@ -60,7 +61,7 @@ public class PhysicalPlanTranslatorTest {
|
||||
t1Output.add(col2);
|
||||
t1Output.add(col3);
|
||||
LogicalProperties t1Properties = new LogicalProperties(() -> t1Output);
|
||||
PhysicalOlapScan scan = new PhysicalOlapScan(t1, qualifier, 0L,
|
||||
PhysicalOlapScan scan = new PhysicalOlapScan(RelationId.createGenerator().getNextId(), t1, qualifier, 0L,
|
||||
Collections.emptyList(), Collections.emptyList(), null,
|
||||
Optional.empty(),
|
||||
t1Properties);
|
||||
|
||||
@ -29,6 +29,7 @@ import org.apache.doris.nereids.trees.expressions.Slot;
|
||||
import org.apache.doris.nereids.trees.expressions.SlotReference;
|
||||
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.logical.LogicalPlan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalProject;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalRelation;
|
||||
@ -104,12 +105,12 @@ public class RewriteTopDownJobTest {
|
||||
private static class LogicalBoundRelation extends LogicalRelation {
|
||||
|
||||
public LogicalBoundRelation(Table table, List<String> qualifier) {
|
||||
super(PlanType.LOGICAL_BOUND_RELATION, table, qualifier);
|
||||
super(RelationId.createGenerator().getNextId(), PlanType.LOGICAL_BOUND_RELATION, table, qualifier);
|
||||
}
|
||||
|
||||
public LogicalBoundRelation(Table table, List<String> qualifier, Optional<GroupExpression> groupExpression,
|
||||
Optional<LogicalProperties> logicalProperties) {
|
||||
super(PlanType.LOGICAL_BOUND_RELATION, table, qualifier,
|
||||
super(RelationId.createGenerator().getNextId(), PlanType.LOGICAL_BOUND_RELATION, table, qualifier,
|
||||
groupExpression, logicalProperties, Collections.emptyList());
|
||||
}
|
||||
|
||||
|
||||
@ -28,6 +28,7 @@ import org.apache.doris.nereids.trees.expressions.SlotReference;
|
||||
import org.apache.doris.nereids.trees.expressions.functions.AggregateFunction;
|
||||
import org.apache.doris.nereids.trees.expressions.functions.Sum;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.RelationId;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalAggregate;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan;
|
||||
import org.apache.doris.nereids.types.IntegerType;
|
||||
@ -100,7 +101,7 @@ public class DeriveStatsJobTest {
|
||||
}};
|
||||
|
||||
OlapTable table1 = PlanConstructor.newOlapTable(tableId1, "t1", 0);
|
||||
return new LogicalOlapScan(table1, Collections.emptyList()).withLogicalProperties(
|
||||
return new LogicalOlapScan(RelationId.createGenerator().getNextId(), table1, Collections.emptyList()).withLogicalProperties(
|
||||
Optional.of(new LogicalProperties(() -> ImmutableList.of(slot1))));
|
||||
}
|
||||
|
||||
|
||||
@ -18,10 +18,12 @@
|
||||
package org.apache.doris.nereids.memo;
|
||||
|
||||
import org.apache.doris.catalog.OlapTable;
|
||||
import org.apache.doris.common.IdGenerator;
|
||||
import org.apache.doris.nereids.analyzer.UnboundRelation;
|
||||
import org.apache.doris.nereids.trees.expressions.EqualTo;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
|
||||
import org.apache.doris.nereids.trees.plans.JoinType;
|
||||
import org.apache.doris.nereids.trees.plans.RelationId;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalFilter;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalJoin;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan;
|
||||
@ -43,7 +45,7 @@ public class MemoInitTest implements PatternMatchSupported {
|
||||
@Test
|
||||
public void initByOneLevelPlan() {
|
||||
OlapTable table = PlanConstructor.newOlapTable(0, "a", 1);
|
||||
LogicalOlapScan scan = new LogicalOlapScan(table);
|
||||
LogicalOlapScan scan = new LogicalOlapScan(RelationId.createGenerator().getNextId(), table);
|
||||
|
||||
PlanChecker.from(connectContext, scan)
|
||||
.checkGroupNum(1)
|
||||
@ -55,7 +57,7 @@ public class MemoInitTest implements PatternMatchSupported {
|
||||
@Test
|
||||
public void initByTwoLevelChainPlan() {
|
||||
OlapTable table = PlanConstructor.newOlapTable(0, "a", 1);
|
||||
LogicalOlapScan scan = new LogicalOlapScan(table);
|
||||
LogicalOlapScan scan = new LogicalOlapScan(RelationId.createGenerator().getNextId(), table);
|
||||
|
||||
LogicalProject<LogicalOlapScan> topProject = new LogicalProject<>(
|
||||
ImmutableList.of(scan.computeOutput().get(0)), scan);
|
||||
@ -87,27 +89,30 @@ public class MemoInitTest implements PatternMatchSupported {
|
||||
|
||||
@Test
|
||||
public void initByJoinSameLogicalTable() {
|
||||
IdGenerator<RelationId> generator = RelationId.createGenerator();
|
||||
OlapTable tableA = PlanConstructor.newOlapTable(0, "a", 1);
|
||||
LogicalOlapScan scanA = new LogicalOlapScan(tableA);
|
||||
LogicalOlapScan scanA = new LogicalOlapScan(generator.getNextId(), tableA);
|
||||
LogicalOlapScan scanA1 = new LogicalOlapScan(generator.getNextId(), tableA);
|
||||
|
||||
LogicalJoin<LogicalOlapScan, LogicalOlapScan> topJoin = new LogicalJoin<>(JoinType.INNER_JOIN, scanA, scanA);
|
||||
LogicalJoin<LogicalOlapScan, LogicalOlapScan> topJoin = new LogicalJoin<>(JoinType.INNER_JOIN, scanA, scanA1);
|
||||
|
||||
PlanChecker.from(connectContext, topJoin)
|
||||
.checkGroupNum(3)
|
||||
.matches(
|
||||
logicalJoin(
|
||||
any().when(left -> Objects.equals(left, scanA)),
|
||||
any().when(right -> Objects.equals(right, scanA))
|
||||
any().when(right -> Objects.equals(right, scanA1))
|
||||
).when(root -> Objects.equals(root, topJoin))
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initByTwoLevelJoinPlan() {
|
||||
IdGenerator<RelationId> generator = RelationId.createGenerator();
|
||||
OlapTable tableA = PlanConstructor.newOlapTable(0, "a", 1);
|
||||
OlapTable tableB = PlanConstructor.newOlapTable(0, "b", 1);
|
||||
LogicalOlapScan scanA = new LogicalOlapScan(tableA);
|
||||
LogicalOlapScan scanB = new LogicalOlapScan(tableB);
|
||||
LogicalOlapScan scanA = new LogicalOlapScan(generator.getNextId(), tableA);
|
||||
LogicalOlapScan scanB = new LogicalOlapScan(generator.getNextId(), tableB);
|
||||
|
||||
LogicalJoin<LogicalOlapScan, LogicalOlapScan> topJoin = new LogicalJoin<>(JoinType.INNER_JOIN, scanA, scanB);
|
||||
|
||||
@ -124,7 +129,7 @@ public class MemoInitTest implements PatternMatchSupported {
|
||||
@Test
|
||||
public void initByThreeLevelChainPlan() {
|
||||
OlapTable table = PlanConstructor.newOlapTable(0, "a", 1);
|
||||
LogicalOlapScan scan = new LogicalOlapScan(table);
|
||||
LogicalOlapScan scan = new LogicalOlapScan(RelationId.createGenerator().getNextId(), table);
|
||||
|
||||
LogicalProject<LogicalOlapScan> project = new LogicalProject<>(
|
||||
ImmutableList.of(scan.computeOutput().get(0)), scan);
|
||||
@ -144,14 +149,15 @@ public class MemoInitTest implements PatternMatchSupported {
|
||||
|
||||
@Test
|
||||
public void initByThreeLevelBushyPlan() {
|
||||
IdGenerator<RelationId> generator = RelationId.createGenerator();
|
||||
OlapTable tableA = PlanConstructor.newOlapTable(0, "a", 1);
|
||||
OlapTable tableB = PlanConstructor.newOlapTable(0, "b", 1);
|
||||
OlapTable tableC = PlanConstructor.newOlapTable(0, "c", 1);
|
||||
OlapTable tableD = PlanConstructor.newOlapTable(0, "d", 1);
|
||||
LogicalOlapScan scanA = new LogicalOlapScan(tableA);
|
||||
LogicalOlapScan scanB = new LogicalOlapScan(tableB);
|
||||
LogicalOlapScan scanC = new LogicalOlapScan(tableC);
|
||||
LogicalOlapScan scanD = new LogicalOlapScan(tableD);
|
||||
LogicalOlapScan scanA = new LogicalOlapScan(generator.getNextId(), tableA);
|
||||
LogicalOlapScan scanB = new LogicalOlapScan(generator.getNextId(), tableB);
|
||||
LogicalOlapScan scanC = new LogicalOlapScan(generator.getNextId(), tableC);
|
||||
LogicalOlapScan scanD = new LogicalOlapScan(generator.getNextId(), tableD);
|
||||
|
||||
LogicalJoin<LogicalOlapScan, LogicalOlapScan> leftJoin = new LogicalJoin<>(JoinType.CROSS_JOIN, scanA, scanB);
|
||||
LogicalJoin<LogicalOlapScan, LogicalOlapScan> rightJoin = new LogicalJoin<>(JoinType.CROSS_JOIN, scanC, scanD);
|
||||
|
||||
@ -17,7 +17,6 @@
|
||||
|
||||
package org.apache.doris.nereids.memo;
|
||||
|
||||
import org.apache.doris.nereids.CascadesContext;
|
||||
import org.apache.doris.nereids.analyzer.UnboundRelation;
|
||||
import org.apache.doris.nereids.analyzer.UnboundSlot;
|
||||
import org.apache.doris.nereids.properties.LogicalProperties;
|
||||
@ -28,6 +27,7 @@ import org.apache.doris.nereids.trees.plans.GroupPlan;
|
||||
import org.apache.doris.nereids.trees.plans.JoinType;
|
||||
import org.apache.doris.nereids.trees.plans.LeafPlan;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.RelationId;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalJoin;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalLimit;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan;
|
||||
@ -75,7 +75,7 @@ public class MemoRewriteTest implements PatternMatchSupported {
|
||||
*/
|
||||
@Test
|
||||
public void a2b() {
|
||||
LogicalOlapScan student = new LogicalOlapScan(PlanConstructor.student);
|
||||
LogicalOlapScan student = new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.student);
|
||||
|
||||
PlanChecker.from(connectContext, new UnboundRelation(ImmutableList.of("student")))
|
||||
.applyBottomUp(
|
||||
@ -92,13 +92,13 @@ public class MemoRewriteTest implements PatternMatchSupported {
|
||||
*/
|
||||
@Test
|
||||
public void a2newA() {
|
||||
LogicalOlapScan student = new LogicalOlapScan(PlanConstructor.student);
|
||||
LogicalOlapScan student = new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.student);
|
||||
|
||||
PlanChecker.from(connectContext, student)
|
||||
.applyBottomUp(
|
||||
logicalOlapScan()
|
||||
.when(scan -> student == scan)
|
||||
.then(scan -> new LogicalOlapScan(PlanConstructor.student))
|
||||
.then(scan -> new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.student))
|
||||
)
|
||||
.checkGroupNum(1)
|
||||
.matchesFromRoot(logicalOlapScan().when(student::equals));
|
||||
@ -113,7 +113,7 @@ public class MemoRewriteTest implements PatternMatchSupported {
|
||||
*/
|
||||
@Test
|
||||
public void a2bc() {
|
||||
LogicalOlapScan student = new LogicalOlapScan(PlanConstructor.student);
|
||||
LogicalOlapScan student = new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.student);
|
||||
LogicalLimit<LogicalOlapScan> limit = new LogicalLimit<>(1, 0, student);
|
||||
|
||||
PlanChecker.from(connectContext, new UnboundRelation(ImmutableList.of("student")))
|
||||
@ -246,12 +246,12 @@ public class MemoRewriteTest implements PatternMatchSupported {
|
||||
* 1. A -> A(B(C))
|
||||
* 2. A -> B(A(C))
|
||||
*/
|
||||
@Test()
|
||||
/*@Test()
|
||||
public void a2ab() {
|
||||
Assertions.assertThrows(IllegalStateException.class, () -> {
|
||||
UnboundRelation student = new UnboundRelation(ImmutableList.of("student"));
|
||||
LogicalLimit<UnboundRelation> limit = new LogicalLimit<>(1, 0, student);
|
||||
LogicalOlapScan boundStudent = new LogicalOlapScan(PlanConstructor.student);
|
||||
LogicalOlapScan boundStudent = new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.student);
|
||||
CascadesContext cascadesContext = MemoTestUtils.createCascadesContext(connectContext, limit);
|
||||
|
||||
PlanChecker.from(cascadesContext)
|
||||
@ -261,7 +261,7 @@ public class MemoRewriteTest implements PatternMatchSupported {
|
||||
logicalLimit().then(l -> l.withChildren(boundStudent))
|
||||
);
|
||||
});
|
||||
}
|
||||
}*/
|
||||
|
||||
/*
|
||||
* A -> B(C(D)):
|
||||
@ -274,7 +274,7 @@ public class MemoRewriteTest implements PatternMatchSupported {
|
||||
*/
|
||||
@Test
|
||||
public void a2bcd() {
|
||||
LogicalOlapScan scan = new LogicalOlapScan(PlanConstructor.student);
|
||||
LogicalOlapScan scan = new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.student);
|
||||
LogicalLimit<LogicalOlapScan> limit5 = new LogicalLimit<>(5, 0, scan);
|
||||
LogicalLimit<LogicalLimit<LogicalOlapScan>> limit10 = new LogicalLimit<>(10, 0, limit5);
|
||||
|
||||
@ -302,7 +302,7 @@ public class MemoRewriteTest implements PatternMatchSupported {
|
||||
*/
|
||||
@Test
|
||||
public void ab2a() {
|
||||
LogicalOlapScan student = new LogicalOlapScan(PlanConstructor.student);
|
||||
LogicalOlapScan student = new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.student);
|
||||
LogicalLimit<LogicalOlapScan> limit10 = new LogicalLimit<>(10, 0, student);
|
||||
|
||||
PlanChecker.from(connectContext, limit10)
|
||||
@ -326,7 +326,7 @@ public class MemoRewriteTest implements PatternMatchSupported {
|
||||
*/
|
||||
@Test
|
||||
public void ab2NewA() {
|
||||
LogicalOlapScan student = new LogicalOlapScan(PlanConstructor.student);
|
||||
LogicalOlapScan student = new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.student);
|
||||
LogicalLimit<LogicalOlapScan> limit10 = new LogicalLimit<>(10, 0, student);
|
||||
|
||||
PlanChecker.from(connectContext, limit10)
|
||||
@ -350,7 +350,7 @@ public class MemoRewriteTest implements PatternMatchSupported {
|
||||
*/
|
||||
@Test
|
||||
public void ab2GroupB() {
|
||||
LogicalOlapScan student = new LogicalOlapScan(PlanConstructor.student);
|
||||
LogicalOlapScan student = new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.student);
|
||||
LogicalLimit<LogicalOlapScan> limit10 = new LogicalLimit<>(10, 0, student);
|
||||
|
||||
PlanChecker.from(connectContext, limit10)
|
||||
@ -372,7 +372,7 @@ public class MemoRewriteTest implements PatternMatchSupported {
|
||||
*/
|
||||
@Test
|
||||
public void ab2PlanB() {
|
||||
LogicalOlapScan student = new LogicalOlapScan(PlanConstructor.student);
|
||||
LogicalOlapScan student = new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.student);
|
||||
LogicalLimit<LogicalOlapScan> limit10 = new LogicalLimit<>(10, 0, student);
|
||||
|
||||
PlanChecker.from(connectContext, limit10)
|
||||
@ -397,7 +397,7 @@ public class MemoRewriteTest implements PatternMatchSupported {
|
||||
UnboundRelation relation = new UnboundRelation(ImmutableList.of("student"));
|
||||
LogicalLimit<UnboundRelation> limit10 = new LogicalLimit<>(10, 0, relation);
|
||||
|
||||
LogicalOlapScan student = new LogicalOlapScan(PlanConstructor.student);
|
||||
LogicalOlapScan student = new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.student);
|
||||
PlanChecker.from(connectContext, limit10)
|
||||
.applyBottomUp(
|
||||
logicalLimit(unboundRelation()).then(limit -> student)
|
||||
@ -420,7 +420,7 @@ public class MemoRewriteTest implements PatternMatchSupported {
|
||||
UnboundRelation relation = new UnboundRelation(ImmutableList.of("student"));
|
||||
LogicalLimit<UnboundRelation> limit10 = new LogicalLimit<>(10, 0, relation);
|
||||
|
||||
LogicalOlapScan student = new LogicalOlapScan(PlanConstructor.student);
|
||||
LogicalOlapScan student = new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.student);
|
||||
LogicalLimit<LogicalOlapScan> limit5 = new LogicalLimit<>(5, 0, student);
|
||||
|
||||
PlanChecker.from(connectContext, limit10)
|
||||
@ -445,7 +445,7 @@ public class MemoRewriteTest implements PatternMatchSupported {
|
||||
*/
|
||||
@Test
|
||||
public void ab2cb() {
|
||||
LogicalOlapScan student = new LogicalOlapScan(PlanConstructor.student);
|
||||
LogicalOlapScan student = new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.student);
|
||||
LogicalLimit<LogicalOlapScan> limit10 = new LogicalLimit<>(10, 0, student);
|
||||
LogicalLimit<LogicalOlapScan> limit5 = new LogicalLimit<>(5, 0, student);
|
||||
|
||||
@ -476,14 +476,14 @@ public class MemoRewriteTest implements PatternMatchSupported {
|
||||
public void ab2NewANewB() {
|
||||
Assertions.assertThrowsExactly(IllegalStateException.class, () -> {
|
||||
|
||||
LogicalOlapScan student = new LogicalOlapScan(PlanConstructor.student);
|
||||
LogicalOlapScan student = new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.student);
|
||||
LogicalLimit<LogicalOlapScan> limit10 = new LogicalLimit<>(10, 0, student);
|
||||
|
||||
PlanChecker.from(connectContext, limit10)
|
||||
.setMaxInvokeTimesPerRule(1000)
|
||||
.applyBottomUp(
|
||||
logicalLimit().when(limit10::equals).then(limit -> limit.withChildren(
|
||||
new LogicalOlapScan(PlanConstructor.student)
|
||||
new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.student)
|
||||
))
|
||||
);
|
||||
});
|
||||
@ -531,7 +531,7 @@ public class MemoRewriteTest implements PatternMatchSupported {
|
||||
UnboundRelation student = new UnboundRelation(ImmutableList.of("student"));
|
||||
LogicalLimit<UnboundRelation> limit3 = new LogicalLimit<>(3, 0, student);
|
||||
|
||||
LogicalOlapScan scan = new LogicalOlapScan(PlanConstructor.student);
|
||||
LogicalOlapScan scan = new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.student);
|
||||
LogicalLimit<LogicalOlapScan> limit5 = new LogicalLimit<>(5, 0, scan);
|
||||
LogicalLimit<LogicalLimit<LogicalOlapScan>> limit10 = new LogicalLimit<>(10, 0, limit5);
|
||||
|
||||
@ -624,10 +624,10 @@ public class MemoRewriteTest implements PatternMatchSupported {
|
||||
|
||||
@Test
|
||||
public void testRewriteBottomPlanToOnePlan() {
|
||||
LogicalOlapScan student = new LogicalOlapScan(PlanConstructor.student);
|
||||
LogicalOlapScan student = new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.student);
|
||||
LogicalLimit<LogicalOlapScan> limit = new LogicalLimit<>(1, 0, student);
|
||||
|
||||
LogicalOlapScan score = new LogicalOlapScan(PlanConstructor.score);
|
||||
LogicalOlapScan score = new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.score);
|
||||
|
||||
PlanChecker.from(connectContext, limit)
|
||||
.applyBottomUp(
|
||||
@ -643,10 +643,10 @@ public class MemoRewriteTest implements PatternMatchSupported {
|
||||
|
||||
@Test
|
||||
public void testRewriteBottomPlanToMultiPlan() {
|
||||
LogicalOlapScan student = new LogicalOlapScan(PlanConstructor.student);
|
||||
LogicalOlapScan student = new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.student);
|
||||
LogicalLimit<LogicalOlapScan> limit10 = new LogicalLimit<>(10, 0, student);
|
||||
|
||||
LogicalOlapScan score = new LogicalOlapScan(PlanConstructor.score);
|
||||
LogicalOlapScan score = new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.score);
|
||||
LogicalLimit<LogicalOlapScan> limit1 = new LogicalLimit<>(1, 0, score);
|
||||
|
||||
PlanChecker.from(connectContext, limit10)
|
||||
@ -666,7 +666,7 @@ public class MemoRewriteTest implements PatternMatchSupported {
|
||||
@Test
|
||||
public void testRewriteUnboundPlanToBound() {
|
||||
UnboundRelation unboundTable = new UnboundRelation(ImmutableList.of("score"));
|
||||
LogicalOlapScan boundTable = new LogicalOlapScan(PlanConstructor.score);
|
||||
LogicalOlapScan boundTable = new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.score);
|
||||
|
||||
PlanChecker.from(connectContext, unboundTable)
|
||||
.checkMemo(memo -> {
|
||||
@ -690,7 +690,7 @@ public class MemoRewriteTest implements PatternMatchSupported {
|
||||
UnboundRelation unboundTable = new UnboundRelation(ImmutableList.of("score"));
|
||||
LogicalLimit<UnboundRelation> unboundLimit = new LogicalLimit<>(1, 0, unboundTable);
|
||||
|
||||
LogicalOlapScan boundTable = new LogicalOlapScan(PlanConstructor.score);
|
||||
LogicalOlapScan boundTable = new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.score);
|
||||
LogicalLimit<Plan> boundLimit = unboundLimit.withChildren(ImmutableList.of(boundTable));
|
||||
|
||||
PlanChecker.from(connectContext, unboundLimit)
|
||||
@ -719,7 +719,7 @@ public class MemoRewriteTest implements PatternMatchSupported {
|
||||
|
||||
@Test
|
||||
public void testEliminateRootWithChildGroupInTwoLevels() {
|
||||
LogicalOlapScan scan = new LogicalOlapScan(PlanConstructor.score);
|
||||
LogicalOlapScan scan = new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.score);
|
||||
LogicalLimit<Plan> limit = new LogicalLimit<>(1, 0, scan);
|
||||
|
||||
PlanChecker.from(connectContext, limit)
|
||||
@ -731,7 +731,7 @@ public class MemoRewriteTest implements PatternMatchSupported {
|
||||
|
||||
@Test
|
||||
public void testEliminateRootWithChildPlanInTwoLevels() {
|
||||
LogicalOlapScan scan = new LogicalOlapScan(PlanConstructor.score);
|
||||
LogicalOlapScan scan = new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.score);
|
||||
LogicalLimit<Plan> limit = new LogicalLimit<>(1, 0, scan);
|
||||
|
||||
PlanChecker.from(connectContext, limit)
|
||||
@ -743,10 +743,10 @@ public class MemoRewriteTest implements PatternMatchSupported {
|
||||
|
||||
@Test
|
||||
public void testEliminateTwoLevelsToOnePlan() {
|
||||
LogicalOlapScan score = new LogicalOlapScan(PlanConstructor.score);
|
||||
LogicalOlapScan score = new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.score);
|
||||
LogicalLimit<Plan> limit = new LogicalLimit<>(1, 0, score);
|
||||
|
||||
LogicalOlapScan student = new LogicalOlapScan(PlanConstructor.student);
|
||||
LogicalOlapScan student = new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.student);
|
||||
|
||||
PlanChecker.from(connectContext, limit)
|
||||
.applyBottomUp(logicalLimit(any()).then(l -> student))
|
||||
@ -763,10 +763,10 @@ public class MemoRewriteTest implements PatternMatchSupported {
|
||||
|
||||
@Test
|
||||
public void testEliminateTwoLevelsToTwoPlans() {
|
||||
LogicalOlapScan score = new LogicalOlapScan(PlanConstructor.score);
|
||||
LogicalOlapScan score = new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.score);
|
||||
LogicalLimit<Plan> limit1 = new LogicalLimit<>(1, 0, score);
|
||||
|
||||
LogicalOlapScan student = new LogicalOlapScan(PlanConstructor.student);
|
||||
LogicalOlapScan student = new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.student);
|
||||
LogicalLimit<Plan> limit10 = new LogicalLimit<>(10, 0, student);
|
||||
|
||||
PlanChecker.from(connectContext, limit1)
|
||||
@ -797,8 +797,8 @@ public class MemoRewriteTest implements PatternMatchSupported {
|
||||
new LogicalJoin<>(JoinType.LEFT_OUTER_JOIN,
|
||||
ImmutableList.of(new EqualTo(new UnboundSlot("sid"), new UnboundSlot("id"))),
|
||||
Optional.empty(),
|
||||
new LogicalOlapScan(PlanConstructor.score),
|
||||
new LogicalOlapScan(PlanConstructor.student)
|
||||
new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.score),
|
||||
new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.student)
|
||||
)
|
||||
))
|
||||
.applyTopDown(
|
||||
|
||||
@ -27,6 +27,7 @@ import org.apache.doris.nereids.trees.expressions.functions.Sum;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
|
||||
import org.apache.doris.nereids.trees.plans.AggPhase;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.RelationId;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalAggregate;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalUnary;
|
||||
@ -49,7 +50,7 @@ public class AggregateDisassembleTest {
|
||||
|
||||
@BeforeAll
|
||||
public final void beforeAll() {
|
||||
rStudent = new LogicalOlapScan(PlanConstructor.student, ImmutableList.of(""));
|
||||
rStudent = new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.student, ImmutableList.of(""));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -57,8 +57,8 @@ import java.util.Optional;
|
||||
class FindHashConditionForJoinTest {
|
||||
@Test
|
||||
public void testFindHashCondition() {
|
||||
Plan student = new LogicalOlapScan(PlanConstructor.student, ImmutableList.of(""));
|
||||
Plan score = new LogicalOlapScan(PlanConstructor.score, ImmutableList.of(""));
|
||||
Plan student = new LogicalOlapScan(PlanConstructor.getNextId(), PlanConstructor.student, ImmutableList.of(""));
|
||||
Plan score = new LogicalOlapScan(PlanConstructor.getNextId(), PlanConstructor.score, ImmutableList.of(""));
|
||||
|
||||
Slot studentId = student.getOutput().get(0);
|
||||
Slot gender = student.getOutput().get(1);
|
||||
|
||||
@ -26,6 +26,7 @@ import org.apache.doris.nereids.trees.expressions.SlotReference;
|
||||
import org.apache.doris.nereids.trees.expressions.functions.Sum;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.RelationId;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalAggregate;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan;
|
||||
import org.apache.doris.nereids.util.FieldChecker;
|
||||
@ -48,7 +49,7 @@ public class NormalizeAggregateTest implements PatternMatchSupported {
|
||||
|
||||
@BeforeAll
|
||||
public final void beforeAll() {
|
||||
rStudent = new LogicalOlapScan(PlanConstructor.student, ImmutableList.of(""));
|
||||
rStudent = new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.student, ImmutableList.of(""));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -43,6 +43,7 @@ import org.apache.doris.nereids.trees.plans.logical.LogicalFilter;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan;
|
||||
import org.apache.doris.nereids.types.IntegerType;
|
||||
import org.apache.doris.nereids.util.MemoTestUtils;
|
||||
import org.apache.doris.nereids.util.PlanConstructor;
|
||||
|
||||
import com.google.common.collect.BoundType;
|
||||
import com.google.common.collect.Lists;
|
||||
@ -87,7 +88,7 @@ class PruneOlapScanPartitionTest {
|
||||
olapTable.getName();
|
||||
result = "tbl";
|
||||
}};
|
||||
LogicalOlapScan scan = new LogicalOlapScan(olapTable);
|
||||
LogicalOlapScan scan = new LogicalOlapScan(PlanConstructor.getNextId(), olapTable);
|
||||
SlotReference slotRef = new SlotReference("col1", IntegerType.INSTANCE);
|
||||
Expression expression = new LessThan(slotRef, new IntegerLiteral(4));
|
||||
LogicalFilter<LogicalOlapScan> filter = new LogicalFilter<>(expression, scan);
|
||||
@ -103,7 +104,7 @@ class PruneOlapScanPartitionTest {
|
||||
Expression greaterThan6 = new GreaterThan(slotRef, new IntegerLiteral(6));
|
||||
Or lessThan0OrGreaterThan6 = new Or(lessThan0, greaterThan6);
|
||||
filter = new LogicalFilter<>(lessThan0OrGreaterThan6, scan);
|
||||
scan = new LogicalOlapScan(olapTable);
|
||||
scan = new LogicalOlapScan(PlanConstructor.getNextId(), olapTable);
|
||||
cascadesContext = MemoTestUtils.createCascadesContext(filter);
|
||||
rules = Lists.newArrayList(new PruneOlapScanPartition().build());
|
||||
cascadesContext.topDownRewrite(rules);
|
||||
@ -117,7 +118,7 @@ class PruneOlapScanPartitionTest {
|
||||
Expression lessThanEqual5 =
|
||||
new LessThanEqual(slotRef, new IntegerLiteral(5));
|
||||
And greaterThanEqual0AndLessThanEqual5 = new And(greaterThanEqual0, lessThanEqual5);
|
||||
scan = new LogicalOlapScan(olapTable);
|
||||
scan = new LogicalOlapScan(PlanConstructor.getNextId(), olapTable);
|
||||
filter = new LogicalFilter<>(greaterThanEqual0AndLessThanEqual5, scan);
|
||||
cascadesContext = MemoTestUtils.createCascadesContext(filter);
|
||||
rules = Lists.newArrayList(new PruneOlapScanPartition().build());
|
||||
@ -152,7 +153,7 @@ class PruneOlapScanPartitionTest {
|
||||
olapTable.getName();
|
||||
result = "tbl";
|
||||
}};
|
||||
LogicalOlapScan scan = new LogicalOlapScan(olapTable);
|
||||
LogicalOlapScan scan = new LogicalOlapScan(PlanConstructor.getNextId(), olapTable);
|
||||
Expression left = new LessThan(new SlotReference("col1", IntegerType.INSTANCE), new IntegerLiteral(4));
|
||||
Expression right = new GreaterThan(new SlotReference("col2", IntegerType.INSTANCE), new IntegerLiteral(11));
|
||||
CompoundPredicate and = new And(left, right);
|
||||
|
||||
@ -69,11 +69,11 @@ public class PushDownPredicateTest {
|
||||
*/
|
||||
@BeforeAll
|
||||
public final void beforeAll() {
|
||||
rStudent = new LogicalOlapScan(PlanConstructor.student, ImmutableList.of(""));
|
||||
rStudent = new LogicalOlapScan(PlanConstructor.getNextId(), PlanConstructor.student, ImmutableList.of(""));
|
||||
|
||||
rScore = new LogicalOlapScan(PlanConstructor.score, ImmutableList.of(""));
|
||||
rScore = new LogicalOlapScan(PlanConstructor.getNextId(), PlanConstructor.score, ImmutableList.of(""));
|
||||
|
||||
rCourse = new LogicalOlapScan(PlanConstructor.course, ImmutableList.of(""));
|
||||
rCourse = new LogicalOlapScan(PlanConstructor.getNextId(), PlanConstructor.course, ImmutableList.of(""));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@ -30,6 +30,7 @@ import org.apache.doris.nereids.trees.expressions.NamedExpression;
|
||||
import org.apache.doris.nereids.trees.expressions.Slot;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.Literal;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.RelationId;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalAggregate;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalFilter;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan;
|
||||
@ -69,7 +70,7 @@ public class PushDownPredicateThroughAggregationTest {
|
||||
*/
|
||||
@Test
|
||||
public void pushDownPredicateOneFilterTest() {
|
||||
Plan scan = new LogicalOlapScan(PlanConstructor.student, ImmutableList.of(""));
|
||||
Plan scan = new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.student, ImmutableList.of(""));
|
||||
Slot gender = scan.getOutput().get(1);
|
||||
Slot age = scan.getOutput().get(3);
|
||||
|
||||
@ -129,7 +130,7 @@ public class PushDownPredicateThroughAggregationTest {
|
||||
*/
|
||||
@Test
|
||||
public void pushDownPredicateTwoFilterTest() {
|
||||
Plan scan = new LogicalOlapScan(PlanConstructor.student, ImmutableList.of(""));
|
||||
Plan scan = new LogicalOlapScan(RelationId.createGenerator().getNextId(), PlanConstructor.student, ImmutableList.of(""));
|
||||
Slot gender = scan.getOutput().get(1);
|
||||
Slot name = scan.getOutput().get(2);
|
||||
Slot age = scan.getOutput().get(3);
|
||||
|
||||
@ -29,6 +29,7 @@ import org.apache.doris.nereids.trees.expressions.Slot;
|
||||
import org.apache.doris.nereids.trees.expressions.SlotReference;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
|
||||
import org.apache.doris.nereids.trees.plans.GroupPlan;
|
||||
import org.apache.doris.nereids.trees.plans.RelationId;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalFilter;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalLimit;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan;
|
||||
@ -218,7 +219,7 @@ public class StatsCalculatorTest {
|
||||
}};
|
||||
|
||||
OlapTable table1 = PlanConstructor.newOlapTable(tableId1, "t1", 0);
|
||||
LogicalOlapScan logicalOlapScan1 = new LogicalOlapScan(table1, Collections.emptyList())
|
||||
LogicalOlapScan logicalOlapScan1 = new LogicalOlapScan(RelationId.createGenerator().getNextId(), table1, Collections.emptyList())
|
||||
.withLogicalProperties(Optional.of(new LogicalProperties(() -> ImmutableList.of(slot1))));
|
||||
Group childGroup = new Group();
|
||||
GroupExpression groupExpression = new GroupExpression(logicalOlapScan1, ImmutableList.of(childGroup));
|
||||
|
||||
@ -118,12 +118,12 @@ public class PlanEqualsTest {
|
||||
|
||||
@Test
|
||||
public void testLogicalOlapScan() {
|
||||
LogicalOlapScan actual = PlanConstructor.newLogicalOlapScan(0, "table", 0);
|
||||
LogicalOlapScan actual = PlanConstructor.newLogicalOlapScanWithSameId(0, "table", 0);
|
||||
|
||||
LogicalOlapScan expected = PlanConstructor.newLogicalOlapScan(0, "table", 0);
|
||||
LogicalOlapScan expected = PlanConstructor.newLogicalOlapScanWithSameId(0, "table", 0);
|
||||
Assertions.assertEquals(expected, actual);
|
||||
|
||||
LogicalOlapScan unexpected = PlanConstructor.newLogicalOlapScan(1, "table", 0);
|
||||
LogicalOlapScan unexpected = PlanConstructor.newLogicalOlapScanWithSameId(1, "table", 0);
|
||||
Assertions.assertNotEquals(unexpected, actual);
|
||||
}
|
||||
|
||||
@ -242,16 +242,18 @@ public class PlanEqualsTest {
|
||||
selectedTabletId.addAll(partition.getBaseIndex().getTabletIdsInOrder());
|
||||
}
|
||||
|
||||
PhysicalOlapScan actual = new PhysicalOlapScan(olapTable, Lists.newArrayList("a"),
|
||||
RelationId id = RelationId.createGenerator().getNextId();
|
||||
|
||||
PhysicalOlapScan actual = new PhysicalOlapScan(id, olapTable, Lists.newArrayList("a"),
|
||||
olapTable.getBaseIndexId(), selectedTabletId, olapTable.getPartitionIds(), distributionSpecHash,
|
||||
Optional.empty(), logicalProperties);
|
||||
|
||||
PhysicalOlapScan expected = new PhysicalOlapScan(olapTable, Lists.newArrayList("a"),
|
||||
PhysicalOlapScan expected = new PhysicalOlapScan(id, olapTable, Lists.newArrayList("a"),
|
||||
olapTable.getBaseIndexId(), selectedTabletId, olapTable.getPartitionIds(), distributionSpecHash,
|
||||
Optional.empty(), logicalProperties);
|
||||
Assertions.assertEquals(expected, actual);
|
||||
|
||||
PhysicalOlapScan unexpected = new PhysicalOlapScan(olapTable, Lists.newArrayList("b"),
|
||||
PhysicalOlapScan unexpected = new PhysicalOlapScan(id, olapTable, Lists.newArrayList("b"),
|
||||
olapTable.getBaseIndexId(), selectedTabletId, olapTable.getPartitionIds(), distributionSpecHash,
|
||||
Optional.empty(), logicalProperties);
|
||||
Assertions.assertNotEquals(unexpected, actual);
|
||||
|
||||
@ -84,7 +84,8 @@ public class PlanOutputTest {
|
||||
@Test
|
||||
public void testPhysicalPlanMustHaveLogicalProperties() {
|
||||
Assertions.assertThrows(NullPointerException.class, () ->
|
||||
new PhysicalRelation(PlanType.PHYSICAL_OLAP_SCAN, ImmutableList.of("db"), Optional.empty(), null) {
|
||||
new PhysicalRelation(RelationId.createGenerator().getNextId(),
|
||||
PlanType.PHYSICAL_OLAP_SCAN, ImmutableList.of("db"), Optional.empty(), null) {
|
||||
@Override
|
||||
public Plan withGroupExpression(Optional<GroupExpression> groupExpression) {
|
||||
return null;
|
||||
|
||||
@ -24,6 +24,8 @@ import org.apache.doris.catalog.KeysType;
|
||||
import org.apache.doris.catalog.OlapTable;
|
||||
import org.apache.doris.catalog.PartitionInfo;
|
||||
import org.apache.doris.catalog.Type;
|
||||
import org.apache.doris.common.IdGenerator;
|
||||
import org.apache.doris.nereids.trees.plans.RelationId;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan;
|
||||
import org.apache.doris.thrift.TStorageType;
|
||||
|
||||
@ -35,6 +37,7 @@ public class PlanConstructor {
|
||||
public static OlapTable student;
|
||||
public static OlapTable score;
|
||||
public static OlapTable course;
|
||||
private static final IdGenerator<RelationId> GENERATOR = RelationId.createGenerator();
|
||||
|
||||
static {
|
||||
student = new OlapTable(0L, "student",
|
||||
@ -99,6 +102,14 @@ public class PlanConstructor {
|
||||
// With OlapTable.
|
||||
// Warning: equals() of Table depends on tableId.
|
||||
public static LogicalOlapScan newLogicalOlapScan(long tableId, String tableName, int hashColumn) {
|
||||
return new LogicalOlapScan(newOlapTable(tableId, tableName, hashColumn), ImmutableList.of("db"));
|
||||
return new LogicalOlapScan(GENERATOR.getNextId(), newOlapTable(tableId, tableName, hashColumn), ImmutableList.of("db"));
|
||||
}
|
||||
|
||||
public static LogicalOlapScan newLogicalOlapScanWithSameId(long tableId, String tableName, int hashColumn) {
|
||||
return new LogicalOlapScan(RelationId.createGenerator().getNextId(), newOlapTable(tableId, tableName, hashColumn), ImmutableList.of("db"));
|
||||
}
|
||||
|
||||
public static RelationId getNextId() {
|
||||
return GENERATOR.getNextId();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user