diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/cost/CostCalculator.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/cost/CostCalculator.java index 7ee533e0f6..b37b3ca2cf 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/cost/CostCalculator.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/cost/CostCalculator.java @@ -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. - * + *

* 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) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java index 69e3829dd4..7adedfcc1f 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java @@ -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 slotList = new ImmutableList.Builder() + .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 slots = tvfRelation.getLogicalProperties().getOutput(); diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleSet.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleSet.java index 7d59f130f4..ba0a4ffda7 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleSet.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleSet.java @@ -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()) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleType.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleType.java index 00c4053f7f..75612ab524 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleType.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleType.java @@ -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), diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindRelation.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindRelation.java index a87e72060a..b740aadae2 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindRelation.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindRelation.java @@ -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()); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalSchemaScanToPhysicalSchemaScan.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalSchemaScanToPhysicalSchemaScan.java new file mode 100644 index 0000000000..cb4832067a --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalSchemaScanToPhysicalSchemaScan.java @@ -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); + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/StatsCalculator.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/StatsCalculator.java index 60455f9c4d..79b8b35d47 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/StatsCalculator.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/StatsCalculator.java @@ -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 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 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 } private ColumnStatistic getLeftStats(int fistSetOperation, - Slot leftSlot, - Map leftStatsSlotIdToColumnStats, - Map newColumnStatsMap) { + Slot leftSlot, + Map leftStatsSlotIdToColumnStats, + Map newColumnStatsMap) { return fistSetOperation == 0 ? leftStatsSlotIdToColumnStats.get(leftSlot.getExprId()) : newColumnStatsMap.get(leftSlot.getExprId()); diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanType.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanType.java index 368a561d3f..c1681a08bb 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanType.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanType.java @@ -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, diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalOlapScan.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalOlapScan.java index 751fc72d74..2d6e40b943 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalOlapScan.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalOlapScan.java @@ -95,6 +95,8 @@ public class LogicalOlapScan extends LogicalRelation implements CatalogRelation, private final boolean partitionPruned; private final List manuallySpecifiedPartitions; + private final ImmutableList 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 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 getSelectedPartitionIds() { + return selectedPartitionIds; } @Override diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalRelation.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalRelation.java index ce57dd0aa9..f1c88adfad 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalRelation.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalRelation.java @@ -44,18 +44,17 @@ public abstract class LogicalRelation extends LogicalLeaf implements Scan { protected final Table table; protected final ImmutableList qualifier; - protected final ImmutableList selectedPartitionIds; protected final RelationId id; public LogicalRelation(RelationId id, PlanType type, Table table, List 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, Optional 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 qualifier, - Optional groupExpression, Optional logicalProperties, - List selectedPartitionIds) { + Optional groupExpression, Optional 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 getSelectedPartitionIds() { - return selectedPartitionIds; - } - public RelationId getId() { return id; } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalSchemaScan.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalSchemaScan.java new file mode 100644 index 0000000000..3641e36319 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalSchemaScan.java @@ -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 qualifier) { + super(id, PlanType.LOGICAL_SCHEMA_SCAN, table, qualifier); + } + + public LogicalSchemaScan(RelationId id, + Table table, + List qualifier, Optional groupExpression, + Optional logicalProperties) { + super(id, PlanType.LOGICAL_SCHEMA_SCAN, table, qualifier, groupExpression, logicalProperties); + } + + @Override + public SchemaTable getTable() { + return (SchemaTable) table; + } + + @Override + public R accept(PlanVisitor visitor, C context) { + return visitor.visitLogicalSchemaScan(this, context); + } + + @Override + public List computeNonUserVisibleOutput() { + SchemaTable schemaTable = getTable(); + return schemaTable.getBaseSchema().stream() + .map(col -> SlotReference.fromColumn(col, qualified())) + .collect(ImmutableList.toImmutableList()); + } + + @Override + public Plan withGroupExpression(Optional groupExpression) { + return new LogicalSchemaScan(id, table, qualifier, groupExpression, Optional.of(getLogicalProperties())); + } + + @Override + public Plan withLogicalProperties(Optional 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"); + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalTVFRelation.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalTVFRelation.java index b9f7b94de4..8d89fcf159 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalTVFRelation.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalTVFRelation.java @@ -46,7 +46,7 @@ public class LogicalTVFRelation extends LogicalRelation implements TVFRelation { Optional 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; } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalSchemaScan.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalSchemaScan.java new file mode 100644 index 0000000000..7d751d4fa4 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalSchemaScan.java @@ -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 qualifier, + Optional groupExpression, LogicalProperties logicalProperties) { + super(id, PlanType.PHYSICAL_SCHEMA_SCAN, qualifier, groupExpression, logicalProperties); + this.table = table; + } + + public PhysicalSchemaScan(RelationId id, Table table, List qualifier, + Optional 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 accept(PlanVisitor visitor, C context) { + return visitor.visitPhysicalSchemaScan(this, context); + } + + @Override + public Plan withGroupExpression(Optional groupExpression) { + return new PhysicalSchemaScan(id, table, qualifier, groupExpression, getLogicalProperties(), physicalProperties, + statsDeriveResult); + } + + @Override + public Plan withLogicalProperties(Optional 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"); + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/visitor/PlanVisitor.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/visitor/PlanVisitor.java index 8b20444697..2af0bd3a3c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/visitor/PlanVisitor.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/visitor/PlanVisitor.java @@ -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 { 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 { 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); } diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/RewriteTopDownJobTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/RewriteTopDownJobTest.java index 92894b39ad..e993d764b6 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/RewriteTopDownJobTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/RewriteTopDownJobTest.java @@ -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 qualifier, Optional groupExpression, Optional logicalProperties) { super(RelationUtil.newRelationId(), PlanType.LOGICAL_BOUND_RELATION, table, qualifier, - groupExpression, logicalProperties, Collections.emptyList()); + groupExpression, logicalProperties); } @Override diff --git a/regression-test/suites/nereids_syntax_p0/information_schema.groovy b/regression-test/suites/nereids_syntax_p0/information_schema.groovy new file mode 100644 index 0000000000..44756adaf4 --- /dev/null +++ b/regression-test/suites/nereids_syntax_p0/information_schema.groovy @@ -0,0 +1,22 @@ +// 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. + +suite("information_schema") { + List> table = sql """ select * from information_schema.backends; """ + assertTrue(table.size() > 0) // row should > 0 + assertTrue(table[0].size == 23) // column should be 23 +}