[feature](Nereids) Support SchemaScan (#15411)
such as: select * from information_schema.backends;
This commit is contained in:
@ -35,6 +35,7 @@ import org.apache.doris.nereids.trees.plans.physical.PhysicalNestedLoopJoin;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalOlapScan;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalProject;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalQuickSort;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalSchemaScan;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalStorageLayerAggregate;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalTopN;
|
||||
import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor;
|
||||
@ -62,7 +63,7 @@ public class CostCalculator {
|
||||
* AGG is time-consuming operator. From the perspective of rowCount, nereids may choose Plan1,
|
||||
* because `Agg1 join Agg2` generates few tuples. But in Plan1, Agg1 and Agg2 are done in serial, in Plan2, Agg1 and
|
||||
* Agg2 are done in parallel. And hence, Plan1 should be punished.
|
||||
*
|
||||
* <p>
|
||||
* An example is tpch q15.
|
||||
*/
|
||||
static final double HEAVY_OPERATOR_PUNISH_FACTOR = 6.0;
|
||||
@ -100,6 +101,11 @@ public class CostCalculator {
|
||||
return CostEstimate.ofCpu(statistics.getRowCount());
|
||||
}
|
||||
|
||||
public CostEstimate visitPhysicalSchemaScan(PhysicalSchemaScan physicalSchemaScan, PlanContext context) {
|
||||
StatsDeriveResult statistics = context.getStatisticsWithCheck();
|
||||
return CostEstimate.ofCpu(statistics.getRowCount());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CostEstimate visitPhysicalStorageLayerAggregate(
|
||||
PhysicalStorageLayerAggregate storageLayerAggregate, PlanContext context) {
|
||||
|
||||
@ -78,6 +78,7 @@ import org.apache.doris.nereids.trees.plans.physical.PhysicalPlan;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalProject;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalQuickSort;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalRepeat;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalSchemaScan;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalSetOperation;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalStorageLayerAggregate;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalTVFRelation;
|
||||
@ -105,6 +106,7 @@ import org.apache.doris.planner.PlanFragment;
|
||||
import org.apache.doris.planner.PlanNode;
|
||||
import org.apache.doris.planner.RepeatNode;
|
||||
import org.apache.doris.planner.ScanNode;
|
||||
import org.apache.doris.planner.SchemaScanNode;
|
||||
import org.apache.doris.planner.SelectNode;
|
||||
import org.apache.doris.planner.SetOperationNode;
|
||||
import org.apache.doris.planner.SortNode;
|
||||
@ -446,6 +448,7 @@ public class PhysicalPlanTranslator extends DefaultPlanVisitor<PlanFragment, Pla
|
||||
OlapTable olapTable = olapScan.getTable();
|
||||
TupleDescriptor tupleDescriptor = generateTupleDesc(slotList, olapTable, context);
|
||||
tupleDescriptor.setTable(olapTable);
|
||||
|
||||
OlapScanNode olapScanNode = new OlapScanNode(context.nextPlanNodeId(), tupleDescriptor, "OlapScanNode");
|
||||
if (olapScan.getStats() != null) {
|
||||
olapScanNode.setCardinality((long) olapScan.getStats().getRowCount());
|
||||
@ -491,6 +494,26 @@ public class PhysicalPlanTranslator extends DefaultPlanVisitor<PlanFragment, Pla
|
||||
return planFragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlanFragment visitPhysicalSchemaScan(PhysicalSchemaScan schemaScan, PlanTranslatorContext context) {
|
||||
Table table = schemaScan.getTable();
|
||||
|
||||
List<Slot> slotList = new ImmutableList.Builder<Slot>()
|
||||
.addAll(schemaScan.getOutput())
|
||||
.addAll(schemaScan.getNonUserVisibleOutput())
|
||||
.build();
|
||||
TupleDescriptor tupleDescriptor = generateTupleDesc(slotList, table, context);
|
||||
tupleDescriptor.setTable(table);
|
||||
|
||||
SchemaScanNode scanNode = new SchemaScanNode(context.nextPlanNodeId(), tupleDescriptor);
|
||||
|
||||
context.getScanNodes().add(scanNode);
|
||||
PlanFragment planFragment =
|
||||
new PlanFragment(context.nextFragmentId(), scanNode, DataPartition.RANDOM);
|
||||
context.addPlanFragment(planFragment);
|
||||
return planFragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlanFragment visitPhysicalTVFRelation(PhysicalTVFRelation tvfRelation, PlanTranslatorContext context) {
|
||||
List<Slot> slots = tvfRelation.getLogicalProperties().getOutput();
|
||||
|
||||
@ -39,6 +39,7 @@ import org.apache.doris.nereids.rules.implementation.LogicalOlapScanToPhysicalOl
|
||||
import org.apache.doris.nereids.rules.implementation.LogicalOneRowRelationToPhysicalOneRowRelation;
|
||||
import org.apache.doris.nereids.rules.implementation.LogicalProjectToPhysicalProject;
|
||||
import org.apache.doris.nereids.rules.implementation.LogicalRepeatToPhysicalRepeat;
|
||||
import org.apache.doris.nereids.rules.implementation.LogicalSchemaScanToPhysicalSchemaScan;
|
||||
import org.apache.doris.nereids.rules.implementation.LogicalSortToPhysicalQuickSort;
|
||||
import org.apache.doris.nereids.rules.implementation.LogicalTVFRelationToPhysicalTVFRelation;
|
||||
import org.apache.doris.nereids.rules.implementation.LogicalTopNToPhysicalTopN;
|
||||
@ -103,6 +104,7 @@ public class RuleSet {
|
||||
.add(new LogicalJoinToHashJoin())
|
||||
.add(new LogicalJoinToNestedLoopJoin())
|
||||
.add(new LogicalOlapScanToPhysicalOlapScan())
|
||||
.add(new LogicalSchemaScanToPhysicalSchemaScan())
|
||||
.add(new LogicalProjectToPhysicalProject())
|
||||
.add(new LogicalLimitToPhysicalLimit())
|
||||
.add(new LogicalSortToPhysicalQuickSort())
|
||||
|
||||
@ -207,6 +207,7 @@ public enum RuleType {
|
||||
LOGICAL_EMPTY_RELATION_TO_PHYSICAL_EMPTY_RELATION_RULE(RuleTypeClass.IMPLEMENTATION),
|
||||
LOGICAL_LIMIT_TO_PHYSICAL_LIMIT_RULE(RuleTypeClass.IMPLEMENTATION),
|
||||
LOGICAL_OLAP_SCAN_TO_PHYSICAL_OLAP_SCAN_RULE(RuleTypeClass.IMPLEMENTATION),
|
||||
LOGICAL_SCHEMA_SCAN_TO_PHYSICAL_SCHEMA_SCAN_RULE(RuleTypeClass.IMPLEMENTATION),
|
||||
LOGICAL_ASSERT_NUM_ROWS_TO_PHYSICAL_ASSERT_NUM_ROWS(RuleTypeClass.IMPLEMENTATION),
|
||||
STORAGE_LAYER_AGGREGATE_WITHOUT_PROJECT(RuleTypeClass.IMPLEMENTATION),
|
||||
STORAGE_LAYER_AGGREGATE_WITH_PROJECT(RuleTypeClass.IMPLEMENTATION),
|
||||
|
||||
@ -31,6 +31,7 @@ import org.apache.doris.nereids.rules.RuleType;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalSchemaScan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalSubQueryAlias;
|
||||
import org.apache.doris.nereids.trees.plans.logical.RelationUtil;
|
||||
import org.apache.doris.qe.ConnectContext;
|
||||
@ -98,6 +99,8 @@ public class BindRelation extends OneAnalysisRuleFactory {
|
||||
} else if (table.getType() == TableType.VIEW) {
|
||||
Plan viewPlan = parseAndAnalyzeView(table.getDdlSql(), cascadesContext);
|
||||
return new LogicalSubQueryAlias<>(table.getName(), viewPlan);
|
||||
} else if (table.getType() == TableType.SCHEMA) {
|
||||
return new LogicalSchemaScan(RelationUtil.newRelationId(), table, ImmutableList.of(dbName));
|
||||
}
|
||||
throw new AnalysisException("Unsupported tableType:" + table.getType());
|
||||
}
|
||||
@ -122,6 +125,8 @@ public class BindRelation extends OneAnalysisRuleFactory {
|
||||
} else if (table.getType() == TableType.VIEW) {
|
||||
Plan viewPlan = parseAndAnalyzeView(table.getDdlSql(), cascadesContext);
|
||||
return new LogicalSubQueryAlias<>(table.getName(), viewPlan);
|
||||
} else if (table.getType() == TableType.SCHEMA) {
|
||||
return new LogicalSchemaScan(RelationUtil.newRelationId(), table, ImmutableList.of(dbName));
|
||||
}
|
||||
throw new AnalysisException("Unsupported tableType:" + table.getType());
|
||||
}
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
// 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.rules.implementation;
|
||||
|
||||
import org.apache.doris.nereids.rules.Rule;
|
||||
import org.apache.doris.nereids.rules.RuleType;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalSchemaScan;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* SchemaScan
|
||||
*/
|
||||
public class LogicalSchemaScanToPhysicalSchemaScan extends OneImplementationRuleFactory {
|
||||
@Override
|
||||
public Rule build() {
|
||||
return logicalSchemaScan().then(scan ->
|
||||
new PhysicalSchemaScan(scan.getId(),
|
||||
scan.getTable(),
|
||||
scan.getQualifier(),
|
||||
Optional.empty(),
|
||||
scan.getLogicalProperties())
|
||||
).toRule(RuleType.LOGICAL_SCHEMA_SCAN_TO_PHYSICAL_SCHEMA_SCAN_RULE);
|
||||
}
|
||||
}
|
||||
@ -51,6 +51,7 @@ import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalOneRowRelation;
|
||||
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.LogicalSchemaScan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalSort;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalTVFRelation;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalTopN;
|
||||
@ -72,6 +73,7 @@ import org.apache.doris.nereids.trees.plans.physical.PhysicalOneRowRelation;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalProject;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalQuickSort;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalRepeat;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalSchemaScan;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalStorageLayerAggregate;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalTVFRelation;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalTopN;
|
||||
@ -164,6 +166,11 @@ public class StatsCalculator extends DefaultPlanVisitor<StatsDeriveResult, Void>
|
||||
return computeScan(olapScan);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StatsDeriveResult visitLogicalSchemaScan(LogicalSchemaScan schemaScan, Void context) {
|
||||
return new StatsDeriveResult(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StatsDeriveResult visitLogicalTVFRelation(LogicalTVFRelation tvfRelation, Void context) {
|
||||
return tvfRelation.getFunction().computeStats(tvfRelation.getOutput());
|
||||
@ -244,6 +251,11 @@ public class StatsCalculator extends DefaultPlanVisitor<StatsDeriveResult, Void>
|
||||
return computeScan(olapScan);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StatsDeriveResult visitPhysicalSchemaScan(PhysicalSchemaScan schemaScan, Void context) {
|
||||
return new StatsDeriveResult(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StatsDeriveResult visitPhysicalStorageLayerAggregate(
|
||||
PhysicalStorageLayerAggregate storageLayerAggregate, Void context) {
|
||||
@ -532,9 +544,9 @@ public class StatsCalculator extends DefaultPlanVisitor<StatsDeriveResult, Void>
|
||||
}
|
||||
|
||||
private ColumnStatistic getLeftStats(int fistSetOperation,
|
||||
Slot leftSlot,
|
||||
Map<Id, ColumnStatistic> leftStatsSlotIdToColumnStats,
|
||||
Map<Id, ColumnStatistic> newColumnStatsMap) {
|
||||
Slot leftSlot,
|
||||
Map<Id, ColumnStatistic> leftStatsSlotIdToColumnStats,
|
||||
Map<Id, ColumnStatistic> newColumnStatsMap) {
|
||||
return fistSetOperation == 0
|
||||
? leftStatsSlotIdToColumnStats.get(leftSlot.getExprId())
|
||||
: newColumnStatsMap.get(leftSlot.getExprId());
|
||||
|
||||
@ -42,6 +42,7 @@ public enum PlanType {
|
||||
LOGICAL_TOP_N,
|
||||
LOGICAL_LIMIT,
|
||||
LOGICAL_OLAP_SCAN,
|
||||
LOGICAL_SCHEMA_SCAN,
|
||||
LOGICAL_APPLY,
|
||||
LOGICAL_SELECT_HINT,
|
||||
LOGICAL_ASSERT_NUM_ROWS,
|
||||
@ -58,6 +59,7 @@ public enum PlanType {
|
||||
PHYSICAL_ONE_ROW_RELATION,
|
||||
PHYSICAL_OLAP_SCAN,
|
||||
PHYSICAL_TVF_RELATION,
|
||||
PHYSICAL_SCHEMA_SCAN,
|
||||
PHYSICAL_PROJECT,
|
||||
PHYSICAL_FILTER,
|
||||
PHYSICAL_BROADCAST_HASH_JOIN,
|
||||
|
||||
@ -95,6 +95,8 @@ public class LogicalOlapScan extends LogicalRelation implements CatalogRelation,
|
||||
private final boolean partitionPruned;
|
||||
private final List<Long> manuallySpecifiedPartitions;
|
||||
|
||||
private final ImmutableList<Long> selectedPartitionIds;
|
||||
|
||||
public LogicalOlapScan(RelationId id, OlapTable table) {
|
||||
this(id, table, ImmutableList.of());
|
||||
}
|
||||
@ -128,7 +130,7 @@ public class LogicalOlapScan extends LogicalRelation implements CatalogRelation,
|
||||
long selectedIndexId, boolean indexSelected, PreAggStatus preAggStatus, List<Long> partitions) {
|
||||
|
||||
super(id, PlanType.LOGICAL_OLAP_SCAN, table, qualifier,
|
||||
groupExpression, logicalProperties, selectedPartitionIds);
|
||||
groupExpression, logicalProperties);
|
||||
this.selectedTabletIds = ImmutableList.copyOf(selectedTabletIds);
|
||||
this.partitionPruned = partitionPruned;
|
||||
this.tabletPruned = tabletPruned;
|
||||
@ -136,6 +138,12 @@ public class LogicalOlapScan extends LogicalRelation implements CatalogRelation,
|
||||
this.indexSelected = indexSelected;
|
||||
this.preAggStatus = preAggStatus;
|
||||
this.manuallySpecifiedPartitions = ImmutableList.copyOf(partitions);
|
||||
this.selectedPartitionIds = ImmutableList.copyOf(
|
||||
Objects.requireNonNull(selectedPartitionIds, "selectedPartitionIds can not be null"));
|
||||
}
|
||||
|
||||
public List<Long> getSelectedPartitionIds() {
|
||||
return selectedPartitionIds;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -44,18 +44,17 @@ public abstract class LogicalRelation extends LogicalLeaf implements Scan {
|
||||
|
||||
protected final Table table;
|
||||
protected final ImmutableList<String> qualifier;
|
||||
protected final ImmutableList<Long> selectedPartitionIds;
|
||||
|
||||
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());
|
||||
this(id, type, table, qualifier, Optional.empty(), Optional.empty());
|
||||
}
|
||||
|
||||
public LogicalRelation(RelationId id, PlanType type, Optional<GroupExpression> groupExpression,
|
||||
Optional<LogicalProperties> logicalProperties) {
|
||||
this(id, type, new OlapTable(), Collections.emptyList(), groupExpression,
|
||||
logicalProperties, Collections.emptyList());
|
||||
logicalProperties);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -65,13 +64,10 @@ public abstract class LogicalRelation extends LogicalLeaf implements Scan {
|
||||
* @param qualifier qualified relation name
|
||||
*/
|
||||
public LogicalRelation(RelationId id, PlanType type, Table table, List<String> qualifier,
|
||||
Optional<GroupExpression> groupExpression, Optional<LogicalProperties> logicalProperties,
|
||||
List<Long> selectedPartitionIds) {
|
||||
Optional<GroupExpression> groupExpression, Optional<LogicalProperties> logicalProperties) {
|
||||
super(type, groupExpression, logicalProperties);
|
||||
this.table = Objects.requireNonNull(table, "table can not be null");
|
||||
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;
|
||||
}
|
||||
|
||||
@ -135,10 +131,6 @@ public abstract class LogicalRelation extends LogicalLeaf implements Scan {
|
||||
return Utils.qualifiedName(qualifier, table.getName());
|
||||
}
|
||||
|
||||
public List<Long> getSelectedPartitionIds() {
|
||||
return selectedPartitionIds;
|
||||
}
|
||||
|
||||
public RelationId getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@ -0,0 +1,97 @@
|
||||
// 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.logical;
|
||||
|
||||
import org.apache.doris.catalog.SchemaTable;
|
||||
import org.apache.doris.catalog.Table;
|
||||
import org.apache.doris.nereids.memo.GroupExpression;
|
||||
import org.apache.doris.nereids.properties.LogicalProperties;
|
||||
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.algebra.Scan;
|
||||
import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor;
|
||||
import org.apache.doris.nereids.util.Utils;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* LogicalSchemaScan.
|
||||
*/
|
||||
public class LogicalSchemaScan extends LogicalRelation implements Scan {
|
||||
public LogicalSchemaScan(RelationId id,
|
||||
Table table,
|
||||
List<String> qualifier) {
|
||||
super(id, PlanType.LOGICAL_SCHEMA_SCAN, table, qualifier);
|
||||
}
|
||||
|
||||
public LogicalSchemaScan(RelationId id,
|
||||
Table table,
|
||||
List<String> qualifier, Optional<GroupExpression> groupExpression,
|
||||
Optional<LogicalProperties> logicalProperties) {
|
||||
super(id, PlanType.LOGICAL_SCHEMA_SCAN, table, qualifier, groupExpression, logicalProperties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SchemaTable getTable() {
|
||||
return (SchemaTable) table;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R, C> R accept(PlanVisitor<R, C> visitor, C context) {
|
||||
return visitor.visitLogicalSchemaScan(this, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Slot> computeNonUserVisibleOutput() {
|
||||
SchemaTable schemaTable = getTable();
|
||||
return schemaTable.getBaseSchema().stream()
|
||||
.map(col -> SlotReference.fromColumn(col, qualified()))
|
||||
.collect(ImmutableList.toImmutableList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plan withGroupExpression(Optional<GroupExpression> groupExpression) {
|
||||
return new LogicalSchemaScan(id, table, qualifier, groupExpression, Optional.of(getLogicalProperties()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plan withLogicalProperties(Optional<LogicalProperties> logicalProperties) {
|
||||
return new LogicalSchemaScan(id, table, qualifier, groupExpression, logicalProperties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return super.equals(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Utils.toSqlString("LogicalSchemaScan");
|
||||
}
|
||||
}
|
||||
@ -46,7 +46,7 @@ public class LogicalTVFRelation extends LogicalRelation implements TVFRelation {
|
||||
Optional<LogicalProperties> logicalProperties) {
|
||||
super(id, PlanType.LOGICAL_TVF_RELATION,
|
||||
Objects.requireNonNull(function, "table valued function can not be null").getTable(),
|
||||
ImmutableList.of(), groupExpression, logicalProperties, ImmutableList.of());
|
||||
ImmutableList.of(), groupExpression, logicalProperties);
|
||||
this.function = function;
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,99 @@
|
||||
// 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.physical;
|
||||
|
||||
import org.apache.doris.catalog.Table;
|
||||
import org.apache.doris.nereids.memo.GroupExpression;
|
||||
import org.apache.doris.nereids.properties.LogicalProperties;
|
||||
import org.apache.doris.nereids.properties.PhysicalProperties;
|
||||
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.Scan;
|
||||
import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor;
|
||||
import org.apache.doris.nereids.util.Utils;
|
||||
import org.apache.doris.statistics.StatsDeriveResult;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* PhysicalSchemaScan.
|
||||
*/
|
||||
public class PhysicalSchemaScan extends PhysicalRelation implements Scan {
|
||||
|
||||
private final Table table;
|
||||
|
||||
public PhysicalSchemaScan(RelationId id, Table table, List<String> qualifier,
|
||||
Optional<GroupExpression> groupExpression, LogicalProperties logicalProperties) {
|
||||
super(id, PlanType.PHYSICAL_SCHEMA_SCAN, qualifier, groupExpression, logicalProperties);
|
||||
this.table = table;
|
||||
}
|
||||
|
||||
public PhysicalSchemaScan(RelationId id, Table table, List<String> qualifier,
|
||||
Optional<GroupExpression> groupExpression, LogicalProperties logicalProperties,
|
||||
PhysicalProperties physicalProperties, StatsDeriveResult statsDeriveResult) {
|
||||
super(id, PlanType.PHYSICAL_SCHEMA_SCAN, qualifier, groupExpression, logicalProperties, physicalProperties,
|
||||
statsDeriveResult);
|
||||
this.table = table;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Table getTable() {
|
||||
return table;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R, C> R accept(PlanVisitor<R, C> visitor, C context) {
|
||||
return visitor.visitPhysicalSchemaScan(this, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plan withGroupExpression(Optional<GroupExpression> groupExpression) {
|
||||
return new PhysicalSchemaScan(id, table, qualifier, groupExpression, getLogicalProperties(), physicalProperties,
|
||||
statsDeriveResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plan withLogicalProperties(Optional<LogicalProperties> logicalProperties) {
|
||||
return new PhysicalSchemaScan(id, table, qualifier, groupExpression, logicalProperties.get(),
|
||||
physicalProperties, statsDeriveResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PhysicalPlan withPhysicalPropertiesAndStats(PhysicalProperties physicalProperties,
|
||||
StatsDeriveResult statsDeriveResult) {
|
||||
return new PhysicalSchemaScan(id, table, qualifier, groupExpression, getLogicalProperties(), physicalProperties,
|
||||
statsDeriveResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return super.equals(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Utils.toSqlString("PhysicalSchemaScan");
|
||||
}
|
||||
}
|
||||
@ -43,6 +43,7 @@ import org.apache.doris.nereids.trees.plans.logical.LogicalOneRowRelation;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalProject;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalRelation;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalRepeat;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalSchemaScan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalSelectHint;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalSetOperation;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalSort;
|
||||
@ -70,6 +71,7 @@ import org.apache.doris.nereids.trees.plans.physical.PhysicalProject;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalQuickSort;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalRelation;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalRepeat;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalSchemaScan;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalSetOperation;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalStorageLayerAggregate;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalTVFRelation;
|
||||
@ -162,6 +164,10 @@ public abstract class PlanVisitor<R, C> {
|
||||
return visitLogicalRelation(olapScan, context);
|
||||
}
|
||||
|
||||
public R visitLogicalSchemaScan(LogicalSchemaScan schemaScan, C context) {
|
||||
return visitLogicalRelation(schemaScan, context);
|
||||
}
|
||||
|
||||
public R visitLogicalTVFRelation(LogicalTVFRelation tvfRelation, C context) {
|
||||
return visitLogicalRelation(tvfRelation, context);
|
||||
}
|
||||
@ -251,6 +257,10 @@ public abstract class PlanVisitor<R, C> {
|
||||
return visitPhysicalScan(olapScan, context);
|
||||
}
|
||||
|
||||
public R visitPhysicalSchemaScan(PhysicalSchemaScan schemaScan, C context) {
|
||||
return visitPhysicalScan(schemaScan, context);
|
||||
}
|
||||
|
||||
public R visitPhysicalStorageLayerAggregate(PhysicalStorageLayerAggregate storageLayerAggregate, C context) {
|
||||
return storageLayerAggregate.getRelation().accept(this, context);
|
||||
}
|
||||
|
||||
@ -44,7 +44,6 @@ import com.google.common.collect.Lists;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@ -111,7 +110,7 @@ public class RewriteTopDownJobTest {
|
||||
public LogicalBoundRelation(Table table, List<String> qualifier, Optional<GroupExpression> groupExpression,
|
||||
Optional<LogicalProperties> logicalProperties) {
|
||||
super(RelationUtil.newRelationId(), PlanType.LOGICAL_BOUND_RELATION, table, qualifier,
|
||||
groupExpression, logicalProperties, Collections.emptyList());
|
||||
groupExpression, logicalProperties);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user