This is an automated email from the ASF dual-hosted git repository.
kxiao pushed a commit to branch branch-2.0
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-2.0 by this push:
new 969dd9b4f45 [feat](Nereids) Support tablesample syntax (#23717)
(#25135)
969dd9b4f45 is described below
commit 969dd9b4f451acbc0b5d7ccff477913eab44b3bc
Author: AKIRA <[email protected]>
AuthorDate: Thu Oct 12 00:05:30 2023 +0900
[feat](Nereids) Support tablesample syntax (#23717) (#25135)
Add table sample support like such SQL:
```sql
select * from test_table_sample_tbl tablesample(4 rows);
select * from test_table_sample_tbl t tablesample(20 percent);
select * from test_table_sample_tbl t tablesample(20 percent) repeatable 2;
```
This function has already been implemented in legacy planner, more detailed
description could be found here: https://github.com/apache/doris/pull/10170
---
.../antlr4/org/apache/doris/nereids/DorisParser.g4 | 11 +++-
.../doris/nereids/analyzer/UnboundRelation.java | 28 +++++++---
.../glue/translator/PhysicalPlanTranslator.java | 6 +++
.../doris/nereids/parser/LogicalPlanBuilder.java | 23 +++++++-
.../doris/nereids/rules/analysis/BindRelation.java | 6 ++-
.../LogicalOlapScanToPhysicalOlapScan.java | 3 +-
.../apache/doris/nereids/trees/TableSample.java | 61 ++++++++++++++++++++++
.../trees/copier/LogicalPlanDeepCopier.java | 4 +-
.../trees/plans/logical/LogicalOlapScan.java | 53 ++++++++++++-------
.../trees/plans/physical/PhysicalOlapScan.java | 21 +++++---
.../translator/PhysicalPlanTranslatorTest.java | 2 +-
.../postprocess/MergeProjectPostProcessTest.java | 2 +-
.../PushdownFilterThroughProjectTest.java | 3 +-
.../doris/nereids/trees/plans/PlanEqualsTest.java | 9 ++--
.../apache/doris/nereids/util/PlanConstructor.java | 3 +-
.../suites/nereids_p0/tablesample.groovy | 45 ++++++++++++++++
16 files changed, 235 insertions(+), 45 deletions(-)
diff --git a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4
b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4
index bb2188e6fa6..6b1f5f742e3 100644
--- a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4
+++ b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4
@@ -259,7 +259,7 @@ identifierSeq
;
relationPrimary
- : multipartIdentifier specifiedPartition? tableAlias relationHint?
lateralView* #tableName
+ : multipartIdentifier specifiedPartition? tableAlias sample? relationHint?
lateralView* #tableName
| LEFT_PAREN query RIGHT_PAREN tableAlias lateralView*
#aliasedQuery
| tvfName=identifier LEFT_PAREN
(properties+=tvfProperty (COMMA properties+=tvfProperty)*)?
@@ -494,6 +494,15 @@ primitiveColType:
| type=ALL
;
+sample
+ : TABLESAMPLE LEFT_PAREN sampleMethod? RIGHT_PAREN (REPEATABLE
seed=INTEGER_VALUE)?
+ ;
+
+sampleMethod
+ : percentage=INTEGER_VALUE PERCENT
#sampleByPercentile
+ | INTEGER_VALUE ROWS
#sampleByRows
+ ;
+
// this rule is used for explicitly capturing wrong identifiers such as
test-table, which should actually be `test-table`
// replace identifier with errorCapturingIdentifier where the immediate follow
symbol is not an expression, otherwise
// valid expressions such as "a-b" can be recognized as an identifier
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/analyzer/UnboundRelation.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/analyzer/UnboundRelation.java
index 6d625f7068e..30485fe66f8 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/analyzer/UnboundRelation.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/analyzer/UnboundRelation.java
@@ -21,6 +21,7 @@ import org.apache.doris.nereids.exceptions.UnboundException;
import org.apache.doris.nereids.memo.GroupExpression;
import org.apache.doris.nereids.properties.LogicalProperties;
import org.apache.doris.nereids.properties.UnboundLogicalProperties;
+import org.apache.doris.nereids.trees.TableSample;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.Slot;
import org.apache.doris.nereids.trees.plans.Plan;
@@ -48,28 +49,36 @@ public class UnboundRelation extends LogicalRelation
implements Unbound {
private final List<String> partNames;
private final boolean isTempPart;
private final List<String> hints;
+ private final Optional<TableSample> tableSample;
public UnboundRelation(RelationId id, List<String> nameParts) {
- this(id, nameParts, Optional.empty(), Optional.empty(),
ImmutableList.of(), false, ImmutableList.of());
+ this(id, nameParts, Optional.empty(), Optional.empty(),
ImmutableList.of(), false,
+ ImmutableList.of(), Optional.empty());
}
public UnboundRelation(RelationId id, List<String> nameParts, List<String>
partNames, boolean isTempPart) {
- this(id, nameParts, Optional.empty(), Optional.empty(), partNames,
isTempPart, ImmutableList.of());
+ this(id, nameParts, Optional.empty(), Optional.empty(), partNames,
isTempPart,
+ ImmutableList.of(), Optional.empty());
}
public UnboundRelation(RelationId id, List<String> nameParts, List<String>
partNames, boolean isTempPart,
- List<String> hints) {
- this(id, nameParts, Optional.empty(), Optional.empty(), partNames,
isTempPart, hints);
+ List<String> hints, Optional<TableSample> tableSample) {
+ this(id, nameParts, Optional.empty(), Optional.empty(),
+ partNames, isTempPart, hints, tableSample);
}
+ /**
+ * Constructor.
+ */
public UnboundRelation(RelationId id, List<String> nameParts,
Optional<GroupExpression> groupExpression,
Optional<LogicalProperties> logicalProperties, List<String>
partNames, boolean isTempPart,
- List<String> hints) {
+ List<String> hints, Optional<TableSample> tableSample) {
super(id, PlanType.LOGICAL_UNBOUND_RELATION, groupExpression,
logicalProperties);
this.nameParts =
ImmutableList.copyOf(Objects.requireNonNull(nameParts, "nameParts should not
null"));
this.partNames =
ImmutableList.copyOf(Objects.requireNonNull(partNames, "partNames should not
null"));
this.isTempPart = isTempPart;
this.hints = ImmutableList.copyOf(Objects.requireNonNull(hints, "hints
should not be null."));
+ this.tableSample = tableSample;
}
public List<String> getNameParts() {
@@ -90,14 +99,15 @@ public class UnboundRelation extends LogicalRelation
implements Unbound {
public Plan withGroupExpression(Optional<GroupExpression> groupExpression)
{
return new UnboundRelation(relationId, nameParts,
groupExpression, Optional.of(getLogicalProperties()),
- partNames, isTempPart, hints);
+ partNames, isTempPart, hints, tableSample);
+
}
@Override
public Plan withGroupExprLogicalPropChildren(Optional<GroupExpression>
groupExpression,
Optional<LogicalProperties> logicalProperties, List<Plan>
children) {
return new UnboundRelation(relationId, nameParts, groupExpression,
logicalProperties, partNames,
- isTempPart, hints);
+ isTempPart, hints, tableSample);
}
@Override
@@ -139,4 +149,8 @@ public class UnboundRelation extends LogicalRelation
implements Unbound {
public List<String> getHints() {
return hints;
}
+
+ public Optional<TableSample> getTableSample() {
+ return tableSample;
+ }
}
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 12f4a5a8bd7..049619eb209 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
@@ -36,6 +36,7 @@ import org.apache.doris.analysis.SlotRef;
import org.apache.doris.analysis.SortInfo;
import org.apache.doris.analysis.TableName;
import org.apache.doris.analysis.TableRef;
+import org.apache.doris.analysis.TableSample;
import org.apache.doris.analysis.TupleDescriptor;
import org.apache.doris.analysis.TupleId;
import org.apache.doris.catalog.Column;
@@ -604,6 +605,11 @@ public class PhysicalPlanTranslator extends
DefaultPlanVisitor<PlanFragment, Pla
tupleDescriptor.setRef(tableRef);
olapScanNode.setSelectedPartitionIds(olapScan.getSelectedPartitionIds());
olapScanNode.setSampleTabletIds(olapScan.getSelectedTabletIds());
+ if (olapScan.getTableSample().isPresent()) {
+ olapScanNode.setTableSample(new
TableSample(olapScan.getTableSample().get().isPercent,
+ olapScan.getTableSample().get().sampleValue,
olapScan.getTableSample().get().seek));
+ olapScanNode.computeSampleTabletIds();
+ }
// TODO: remove this switch?
switch (olapScan.getTable().getKeysType()) {
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
index 0fe54f9069b..f6e0cd117d2 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
@@ -83,6 +83,9 @@ import
org.apache.doris.nereids.DorisParser.QueryOrganizationContext;
import org.apache.doris.nereids.DorisParser.QueryTermContext;
import org.apache.doris.nereids.DorisParser.RegularQuerySpecificationContext;
import org.apache.doris.nereids.DorisParser.RelationContext;
+import org.apache.doris.nereids.DorisParser.SampleByPercentileContext;
+import org.apache.doris.nereids.DorisParser.SampleByRowsContext;
+import org.apache.doris.nereids.DorisParser.SampleContext;
import org.apache.doris.nereids.DorisParser.SelectClauseContext;
import org.apache.doris.nereids.DorisParser.SelectColumnClauseContext;
import org.apache.doris.nereids.DorisParser.SelectHintContext;
@@ -129,6 +132,7 @@ import
org.apache.doris.nereids.analyzer.UnboundVariable.VariableType;
import org.apache.doris.nereids.exceptions.ParseException;
import org.apache.doris.nereids.properties.OrderKey;
import org.apache.doris.nereids.properties.SelectHint;
+import org.apache.doris.nereids.trees.TableSample;
import org.apache.doris.nereids.trees.expressions.Add;
import org.apache.doris.nereids.trees.expressions.And;
import org.apache.doris.nereids.trees.expressions.BitAnd;
@@ -632,9 +636,11 @@ public class LogicalPlanBuilder extends
DorisParserBaseVisitor<Object> {
relationHints = ImmutableList.of();
}
+ TableSample tableSample = ctx.sample() == null ? null : (TableSample)
visit(ctx.sample());
LogicalPlan checkedRelation = withCheckPolicy(
new UnboundRelation(StatementScopeIdGenerator.newRelationId(),
- tableId, partitionNames, isTempPart, relationHints));
+ tableId, partitionNames, isTempPart, relationHints,
+ Optional.ofNullable(tableSample)));
LogicalPlan plan = withTableAlias(checkedRelation, ctx.tableAlias());
for (LateralViewContext lateralViewContext : ctx.lateralView()) {
plan = withGenerate(plan, lateralViewContext);
@@ -2016,4 +2022,19 @@ public class LogicalPlanBuilder extends
DorisParserBaseVisitor<Object> {
}
return context.getText();
}
+
+ @Override
+ public Object visitSample(SampleContext ctx) {
+ long seek = ctx.seed == null ? -1L :
Long.parseLong(ctx.seed.getText());
+ DorisParser.SampleMethodContext sampleContext = ctx.sampleMethod();
+ if (sampleContext instanceof SampleByPercentileContext) {
+ SampleByPercentileContext sampleByPercentileContext =
(SampleByPercentileContext) sampleContext;
+ long percent =
Long.parseLong(sampleByPercentileContext.INTEGER_VALUE().getText());
+ return new TableSample(percent, true, seek);
+ }
+ SampleByRowsContext sampleByRowsContext = (SampleByRowsContext)
sampleContext;
+ long rows = Long.parseLong(sampleByRowsContext.ROWS().getText());
+ return new TableSample(rows, false, seek);
+ }
+
}
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 054c882b158..cffe32df5b0 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
@@ -170,10 +170,12 @@ public class BindRelation extends OneAnalysisRuleFactory {
List<Long> partIds = getPartitionIds(table, unboundRelation);
if (!CollectionUtils.isEmpty(partIds)) {
scan = new LogicalOlapScan(unboundRelation.getRelationId(),
- (OlapTable) table,
ImmutableList.of(tableQualifier.get(1)), partIds, unboundRelation.getHints());
+ (OlapTable) table,
ImmutableList.of(tableQualifier.get(1)), partIds,
+ unboundRelation.getHints(),
unboundRelation.getTableSample());
} else {
scan = new LogicalOlapScan(unboundRelation.getRelationId(),
- (OlapTable) table,
ImmutableList.of(tableQualifier.get(1)), unboundRelation.getHints());
+ (OlapTable) table,
ImmutableList.of(tableQualifier.get(1)), unboundRelation.getHints(),
+ unboundRelation.getTableSample());
}
if (!Util.showHiddenColumns() && scan.getTable().hasDeleteSign()
&& !ConnectContext.get().getSessionVariable()
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalOlapScanToPhysicalOlapScan.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalOlapScanToPhysicalOlapScan.java
index b578247d06c..6bcf22a9adc 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalOlapScanToPhysicalOlapScan.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/implementation/LogicalOlapScanToPhysicalOlapScan.java
@@ -60,7 +60,8 @@ public class LogicalOlapScanToPhysicalOlapScan extends
OneImplementationRuleFact
olapScan.getPreAggStatus(),
olapScan.getOutputByIndex(olapScan.getTable().getBaseIndexId()),
Optional.empty(),
- olapScan.getLogicalProperties())
+ olapScan.getLogicalProperties(),
+ olapScan.getTableSample())
).toRule(RuleType.LOGICAL_OLAP_SCAN_TO_PHYSICAL_OLAP_SCAN_RULE);
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/TableSample.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/TableSample.java
new file mode 100644
index 00000000000..da300cd442d
--- /dev/null
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/TableSample.java
@@ -0,0 +1,61 @@
+// 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;
+
+import java.util.Objects;
+
+/**
+ * To represent following stmt:
+ * TABLESAMPLE (10 PERCENT)
+ * TABLESAMPLE (100 ROWS)
+ * TABLESAMPLE (10 PERCENT) REPEATABLE 2
+ * TABLESAMPLE (100 ROWS) REPEATABLE 2
+ */
+public class TableSample {
+
+ public final long sampleValue;
+
+ public final boolean isPercent;
+
+ public final long seek;
+
+ public TableSample(long sampleValue, boolean isPercent, long seek) {
+ this.sampleValue = sampleValue;
+ this.isPercent = isPercent;
+ this.seek = seek;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof TableSample)) {
+ return false;
+ }
+ TableSample tableSample = (TableSample) obj;
+ return this.sampleValue == tableSample.sampleValue
+ && this.isPercent == tableSample.isPercent
+ && this.seek == tableSample.seek;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(sampleValue, isPercent, seek);
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/copier/LogicalPlanDeepCopier.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/copier/LogicalPlanDeepCopier.java
index 2e52c582d91..12455b66f2e 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/copier/LogicalPlanDeepCopier.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/copier/LogicalPlanDeepCopier.java
@@ -160,11 +160,11 @@ public class LogicalPlanDeepCopier extends
DefaultPlanRewriter<DeepCopierContext
LogicalOlapScan newOlapScan;
if (olapScan.getManuallySpecifiedPartitions().isEmpty()) {
newOlapScan = new
LogicalOlapScan(StatementScopeIdGenerator.newRelationId(),
- olapScan.getTable(), olapScan.getQualifier(),
olapScan.getHints());
+ olapScan.getTable(), olapScan.getQualifier(),
olapScan.getHints(), olapScan.getTableSample());
} else {
newOlapScan = new
LogicalOlapScan(StatementScopeIdGenerator.newRelationId(),
olapScan.getTable(), olapScan.getQualifier(),
- olapScan.getManuallySpecifiedPartitions(),
olapScan.getHints());
+ olapScan.getManuallySpecifiedPartitions(),
olapScan.getHints(), olapScan.getTableSample());
}
newOlapScan.getOutput();
context.putRelation(olapScan.getRelationId(), newOlapScan);
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 0759162116f..71b68fdd7fa 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
@@ -23,6 +23,7 @@ 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.rules.rewrite.mv.AbstractSelectMaterializedIndexRule;
+import org.apache.doris.nereids.trees.TableSample;
import org.apache.doris.nereids.trees.expressions.Slot;
import org.apache.doris.nereids.trees.expressions.SlotReference;
import org.apache.doris.nereids.trees.plans.Plan;
@@ -103,6 +104,8 @@ public class LogicalOlapScan extends LogicalCatalogRelation
implements OlapScan
///////////////////////////////////////////////////////////////////////////
private final List<String> hints;
+ private final Optional<TableSample> tableSample;
+
public LogicalOlapScan(RelationId id, OlapTable table) {
this(id, table, ImmutableList.of());
}
@@ -111,22 +114,25 @@ public class LogicalOlapScan extends
LogicalCatalogRelation implements OlapScan
this(id, table, qualifier, Optional.empty(), Optional.empty(),
table.getPartitionIds(), false,
ImmutableList.of(),
- -1, false, PreAggStatus.on(), ImmutableList.of(),
ImmutableList.of(), Maps.newHashMap());
+ -1, false, PreAggStatus.on(), ImmutableList.of(),
ImmutableList.of(),
+ Maps.newHashMap(), Optional.empty());
}
- public LogicalOlapScan(RelationId id, OlapTable table, List<String>
qualifier, List<String> hints) {
+ public LogicalOlapScan(RelationId id, OlapTable table, List<String>
qualifier,
+ List<String> hints, Optional<TableSample> tableSample) {
this(id, table, qualifier, Optional.empty(), Optional.empty(),
- table.getPartitionIds(), false,
- ImmutableList.of(),
- -1, false, PreAggStatus.on(), ImmutableList.of(), hints,
Maps.newHashMap());
+ table.getPartitionIds(), false, ImmutableList.of(),
+ -1, false, PreAggStatus.on(), ImmutableList.of(), hints,
Maps.newHashMap(),
+ tableSample);
}
public LogicalOlapScan(RelationId id, OlapTable table, List<String>
qualifier, List<Long> specifiedPartitions,
- List<String> hints) {
+ List<String> hints, Optional<TableSample> tableSample) {
this(id, table, qualifier, Optional.empty(), Optional.empty(),
// must use specifiedPartitions here for prune partition by
sql like 'select * from t partition p1'
specifiedPartitions, false, ImmutableList.of(),
- -1, false, PreAggStatus.on(), specifiedPartitions, hints,
Maps.newHashMap());
+ -1, false, PreAggStatus.on(), specifiedPartitions, hints,
Maps.newHashMap(),
+ tableSample);
}
/**
@@ -137,10 +143,12 @@ public class LogicalOlapScan extends
LogicalCatalogRelation implements OlapScan
List<Long> selectedPartitionIds, boolean partitionPruned,
List<Long> selectedTabletIds, long selectedIndexId, boolean
indexSelected,
PreAggStatus preAggStatus, List<Long> specifiedPartitions,
- List<String> hints, Map<Pair<Long, String>, Slot>
cacheSlotWithSlotName) {
+ List<String> hints, Map<Pair<Long, String>, Slot>
cacheSlotWithSlotName,
+ Optional<TableSample> tableSample) {
super(id, PlanType.LOGICAL_OLAP_SCAN, table, qualifier,
groupExpression, logicalProperties);
- Preconditions.checkArgument(selectedPartitionIds != null,
"selectedPartitionIds can not be null");
+ Preconditions.checkArgument(selectedPartitionIds != null,
+ "selectedPartitionIds can not be null");
this.selectedTabletIds = ImmutableList.copyOf(selectedTabletIds);
this.partitionPruned = partitionPruned;
this.selectedIndexId = selectedIndexId <= 0 ?
getTable().getBaseIndexId() : selectedIndexId;
@@ -152,7 +160,9 @@ public class LogicalOlapScan extends LogicalCatalogRelation
implements OlapScan
.filter(partitionId ->
this.getTable().getPartition(partitionId).hasData())
.collect(Collectors.toList());
this.hints = Objects.requireNonNull(hints, "hints can not be null");
- this.cacheSlotWithSlotName =
Objects.requireNonNull(cacheSlotWithSlotName, "mvNameToSlot can not be null");
+ this.cacheSlotWithSlotName =
Objects.requireNonNull(cacheSlotWithSlotName,
+ "mvNameToSlot can not be null");
+ this.tableSample = tableSample;
}
public List<Long> getSelectedPartitionIds() {
@@ -192,13 +202,15 @@ public class LogicalOlapScan extends
LogicalCatalogRelation implements OlapScan
&& Objects.equals(selectedTabletIds, that.selectedTabletIds)
&& Objects.equals(manuallySpecifiedPartitions,
that.manuallySpecifiedPartitions)
&& Objects.equals(selectedPartitionIds,
that.selectedPartitionIds)
- && Objects.equals(hints, that.hints);
+ && Objects.equals(hints, that.hints)
+ && Objects.equals(tableSample, tableSample);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), selectedIndexId, indexSelected,
preAggStatus, cacheSlotWithSlotName,
- selectedTabletIds, partitionPruned,
manuallySpecifiedPartitions, selectedPartitionIds, hints);
+ selectedTabletIds, partitionPruned,
manuallySpecifiedPartitions, selectedPartitionIds, hints,
+ tableSample);
}
@Override
@@ -207,7 +219,7 @@ public class LogicalOlapScan extends LogicalCatalogRelation
implements OlapScan
groupExpression, Optional.of(getLogicalProperties()),
selectedPartitionIds, partitionPruned, selectedTabletIds,
selectedIndexId, indexSelected, preAggStatus,
manuallySpecifiedPartitions,
- hints, cacheSlotWithSlotName);
+ hints, cacheSlotWithSlotName, tableSample);
}
@Override
@@ -216,7 +228,7 @@ public class LogicalOlapScan extends LogicalCatalogRelation
implements OlapScan
return new LogicalOlapScan(relationId, (Table) table, qualifier,
groupExpression, logicalProperties,
selectedPartitionIds, partitionPruned, selectedTabletIds,
selectedIndexId, indexSelected, preAggStatus,
manuallySpecifiedPartitions,
- hints, cacheSlotWithSlotName);
+ hints, cacheSlotWithSlotName, tableSample);
}
public LogicalOlapScan withSelectedPartitionIds(List<Long>
selectedPartitionIds) {
@@ -224,14 +236,15 @@ public class LogicalOlapScan extends
LogicalCatalogRelation implements OlapScan
Optional.empty(), Optional.of(getLogicalProperties()),
selectedPartitionIds, true, selectedTabletIds,
selectedIndexId, indexSelected, preAggStatus,
manuallySpecifiedPartitions,
- hints, cacheSlotWithSlotName);
+ hints, cacheSlotWithSlotName, tableSample);
}
public LogicalOlapScan withMaterializedIndexSelected(PreAggStatus preAgg,
long indexId) {
return new LogicalOlapScan(relationId, (Table) table, qualifier,
Optional.empty(), Optional.of(getLogicalProperties()),
selectedPartitionIds, partitionPruned, selectedTabletIds,
- indexId, true, preAgg, manuallySpecifiedPartitions, hints,
cacheSlotWithSlotName);
+ indexId, true, preAgg, manuallySpecifiedPartitions, hints,
cacheSlotWithSlotName,
+ tableSample);
}
public LogicalOlapScan withSelectedTabletIds(List<Long> selectedTabletIds)
{
@@ -239,7 +252,7 @@ public class LogicalOlapScan extends LogicalCatalogRelation
implements OlapScan
Optional.empty(), Optional.of(getLogicalProperties()),
selectedPartitionIds, partitionPruned, selectedTabletIds,
selectedIndexId, indexSelected, preAggStatus,
manuallySpecifiedPartitions,
- hints, cacheSlotWithSlotName);
+ hints, cacheSlotWithSlotName, tableSample);
}
public LogicalOlapScan withPreAggStatus(PreAggStatus preAggStatus) {
@@ -247,7 +260,7 @@ public class LogicalOlapScan extends LogicalCatalogRelation
implements OlapScan
Optional.empty(), Optional.of(getLogicalProperties()),
selectedPartitionIds, partitionPruned, selectedTabletIds,
selectedIndexId, indexSelected, preAggStatus,
manuallySpecifiedPartitions,
- hints, cacheSlotWithSlotName);
+ hints, cacheSlotWithSlotName, tableSample);
}
@Override
@@ -334,4 +347,8 @@ public class LogicalOlapScan extends LogicalCatalogRelation
implements OlapScan
public List<String> getHints() {
return hints;
}
+
+ public Optional<TableSample> getTableSample() {
+ return tableSample;
+ }
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalOlapScan.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalOlapScan.java
index 57292551a91..47433c3389a 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalOlapScan.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalOlapScan.java
@@ -22,6 +22,7 @@ import org.apache.doris.nereids.memo.GroupExpression;
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.TableSample;
import org.apache.doris.nereids.trees.expressions.Slot;
import org.apache.doris.nereids.trees.plans.AbstractPlan;
import org.apache.doris.nereids.trees.plans.Plan;
@@ -52,15 +53,19 @@ public class PhysicalOlapScan extends
PhysicalCatalogRelation implements OlapSca
private final PreAggStatus preAggStatus;
private final List<Slot> baseOutputs;
+ private final Optional<TableSample> tableSample;
+
/**
* Constructor for PhysicalOlapScan.
*/
public PhysicalOlapScan(RelationId id, OlapTable olapTable, List<String>
qualifier, long selectedIndexId,
List<Long> selectedTabletIds, List<Long> selectedPartitionIds,
DistributionSpec distributionSpec,
PreAggStatus preAggStatus, List<Slot> baseOutputs,
- Optional<GroupExpression> groupExpression, LogicalProperties
logicalProperties) {
+ Optional<GroupExpression> groupExpression, LogicalProperties
logicalProperties,
+ Optional<TableSample> tableSample) {
this(id, olapTable, qualifier, selectedIndexId, selectedTabletIds,
selectedPartitionIds, distributionSpec,
- preAggStatus, baseOutputs, groupExpression, logicalProperties,
null, null);
+ preAggStatus, baseOutputs, groupExpression, logicalProperties,
null, null,
+ tableSample);
}
/**
@@ -70,7 +75,7 @@ public class PhysicalOlapScan extends PhysicalCatalogRelation
implements OlapSca
List<Long> selectedTabletIds, List<Long> selectedPartitionIds,
DistributionSpec distributionSpec,
PreAggStatus preAggStatus, List<Slot> baseOutputs,
Optional<GroupExpression> groupExpression, LogicalProperties
logicalProperties,
- PhysicalProperties physicalProperties, Statistics statistics) {
+ PhysicalProperties physicalProperties, Statistics statistics,
Optional<TableSample> tableSample) {
super(id, PlanType.PHYSICAL_OLAP_SCAN, olapTable, qualifier,
groupExpression, logicalProperties, physicalProperties,
statistics);
this.selectedIndexId = selectedIndexId;
@@ -79,6 +84,7 @@ public class PhysicalOlapScan extends PhysicalCatalogRelation
implements OlapSca
this.distributionSpec = distributionSpec;
this.preAggStatus = preAggStatus;
this.baseOutputs = ImmutableList.copyOf(baseOutputs);
+ this.tableSample = tableSample;
}
@Override
@@ -155,7 +161,7 @@ public class PhysicalOlapScan extends
PhysicalCatalogRelation implements OlapSca
public PhysicalOlapScan withGroupExpression(Optional<GroupExpression>
groupExpression) {
return new PhysicalOlapScan(relationId, getTable(), qualifier,
selectedIndexId, selectedTabletIds,
selectedPartitionIds, distributionSpec, preAggStatus,
baseOutputs,
- groupExpression, getLogicalProperties());
+ groupExpression, getLogicalProperties(), tableSample);
}
@Override
@@ -163,7 +169,7 @@ public class PhysicalOlapScan extends
PhysicalCatalogRelation implements OlapSca
Optional<LogicalProperties> logicalProperties, List<Plan>
children) {
return new PhysicalOlapScan(relationId, getTable(), qualifier,
selectedIndexId, selectedTabletIds,
selectedPartitionIds, distributionSpec, preAggStatus,
baseOutputs, groupExpression,
- logicalProperties.get());
+ logicalProperties.get(), tableSample);
}
@Override
@@ -171,7 +177,7 @@ public class PhysicalOlapScan extends
PhysicalCatalogRelation implements OlapSca
PhysicalProperties physicalProperties, Statistics statistics) {
return new PhysicalOlapScan(relationId, getTable(), qualifier,
selectedIndexId, selectedTabletIds,
selectedPartitionIds, distributionSpec, preAggStatus,
baseOutputs, groupExpression,
- getLogicalProperties(), physicalProperties, statistics);
+ getLogicalProperties(), physicalProperties, statistics,
tableSample);
}
@Override
@@ -193,4 +199,7 @@ public class PhysicalOlapScan extends
PhysicalCatalogRelation implements OlapSca
return olapScan;
}
+ public Optional<TableSample> getTableSample() {
+ return tableSample;
+ }
}
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslatorTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslatorTest.java
index be5a14343da..ad8ed9b6bf1 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslatorTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslatorTest.java
@@ -66,7 +66,7 @@ public class PhysicalPlanTranslatorTest {
LogicalProperties t1Properties = new LogicalProperties(() -> t1Output);
PhysicalOlapScan scan = new
PhysicalOlapScan(StatementScopeIdGenerator.newRelationId(), t1, qualifier,
t1.getBaseIndexId(),
Collections.emptyList(), Collections.emptyList(), null,
PreAggStatus.on(),
- ImmutableList.of(), Optional.empty(), t1Properties);
+ ImmutableList.of(), Optional.empty(), t1Properties,
Optional.empty());
Literal t1FilterRight = new IntegerLiteral(1);
Expression t1FilterExpr = new GreaterThan(col1, t1FilterRight);
PhysicalFilter<PhysicalOlapScan> filter =
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/postprocess/MergeProjectPostProcessTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/postprocess/MergeProjectPostProcessTest.java
index 74822d8fe59..729d988d93d 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/postprocess/MergeProjectPostProcessTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/postprocess/MergeProjectPostProcessTest.java
@@ -77,7 +77,7 @@ public class MergeProjectPostProcessTest {
LogicalProperties t1Properties = new LogicalProperties(() -> t1Output);
PhysicalOlapScan scan = new
PhysicalOlapScan(RelationId.createGenerator().getNextId(), t1, qualifier, 0L,
Collections.emptyList(), Collections.emptyList(), null,
PreAggStatus.on(), ImmutableList.of(),
- Optional.empty(), t1Properties);
+ Optional.empty(), t1Properties, Optional.empty());
Alias x = new Alias(a, "x");
List<NamedExpression> projList3 = Lists.newArrayList(x, b, c);
PhysicalProject proj3 = new PhysicalProject(projList3, placeHolder,
scan);
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/postprocess/PushdownFilterThroughProjectTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/postprocess/PushdownFilterThroughProjectTest.java
index ccbed847c32..46130efbcbd 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/postprocess/PushdownFilterThroughProjectTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/postprocess/PushdownFilterThroughProjectTest.java
@@ -88,7 +88,8 @@ public class PushdownFilterThroughProjectTest {
LogicalProperties t1Properties = new LogicalProperties(() -> t1Output);
PhysicalOlapScan scan = new
PhysicalOlapScan(RelationId.createGenerator().getNextId(), t1,
qualifier, 0L, Collections.emptyList(),
Collections.emptyList(), null,
- PreAggStatus.on(), ImmutableList.of(), Optional.empty(),
t1Properties);
+ PreAggStatus.on(), ImmutableList.of(), Optional.empty(),
t1Properties,
+ Optional.empty());
Alias x = new Alias(a, "x");
List<NamedExpression> projList3 = Lists.newArrayList(x, b, c);
PhysicalProject proj3 = new PhysicalProject(projList3, placeHolder,
scan);
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/PlanEqualsTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/PlanEqualsTest.java
index c018c0d6dfe..c43ecd6872e 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/PlanEqualsTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/plans/PlanEqualsTest.java
@@ -265,16 +265,19 @@ class PlanEqualsTest {
PhysicalOlapScan actual = new PhysicalOlapScan(id, olapTable,
Lists.newArrayList("a"),
1L, selectedTabletId, olapTable.getPartitionIds(),
distributionSpecHash,
- PreAggStatus.on(), ImmutableList.of(), Optional.empty(),
logicalProperties);
+ PreAggStatus.on(), ImmutableList.of(), Optional.empty(),
logicalProperties,
+ Optional.empty());
PhysicalOlapScan expected = new PhysicalOlapScan(id, olapTable,
Lists.newArrayList("a"),
1L, selectedTabletId, olapTable.getPartitionIds(),
distributionSpecHash,
- PreAggStatus.on(), ImmutableList.of(), Optional.empty(),
logicalProperties);
+ PreAggStatus.on(), ImmutableList.of(), Optional.empty(),
logicalProperties,
+ Optional.empty());
Assertions.assertEquals(expected, actual);
PhysicalOlapScan unexpected = new PhysicalOlapScan(id, olapTable,
Lists.newArrayList("b"),
12345L, selectedTabletId, olapTable.getPartitionIds(),
distributionSpecHash,
- PreAggStatus.on(), ImmutableList.of(), Optional.empty(),
logicalProperties);
+ PreAggStatus.on(), ImmutableList.of(), Optional.empty(),
logicalProperties,
+ Optional.empty());
Assertions.assertNotEquals(unexpected, actual);
}
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/util/PlanConstructor.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/util/PlanConstructor.java
index 9bb48837754..3866ce98bf3 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/util/PlanConstructor.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/util/PlanConstructor.java
@@ -32,6 +32,7 @@ import org.apache.doris.thrift.TStorageType;
import com.google.common.collect.ImmutableList;
import java.util.List;
+import java.util.Optional;
public class PlanConstructor {
@@ -112,7 +113,7 @@ public class PlanConstructor {
int hashColumn, List<Long> selectedPartitions) {
return new LogicalOlapScan(RelationId.createGenerator().getNextId(),
newOlapTable(tableId, tableName, hashColumn),
ImmutableList.of("db"),
- selectedPartitions, ImmutableList.of());
+ selectedPartitions, ImmutableList.of(), Optional.empty());
}
public static RelationId getNextRelationId() {
diff --git a/regression-test/suites/nereids_p0/tablesample.groovy
b/regression-test/suites/nereids_p0/tablesample.groovy
new file mode 100644
index 00000000000..52203bed232
--- /dev/null
+++ b/regression-test/suites/nereids_p0/tablesample.groovy
@@ -0,0 +1,45 @@
+// 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("test_table_sample") {
+ sql "SET enable_nereids_planner=false"
+ sql "SET enable_fallback_to_original_planner=false"
+ sql """DROP TABLE IF EXISTS test_table_sample_tbl"""
+ sql """
+ CREATE TABLE `test_table_sample_tbl` (
+ `col1` varchar(11451) NOT NULL,
+ `col2` int(11) NOT NULL,
+ `col3` int(11) NOT NULL
+ ) ENGINE=OLAP
+ DUPLICATE KEY(`col1`)
+ COMMENT 'OLAP'
+ DISTRIBUTED BY HASH(`col1`) BUCKETS 3
+ PROPERTIES (
+ "replication_allocation" = "tag.location.default: 1",
+ "is_being_synced" = "false",
+ "storage_format" = "V2",
+ "light_schema_change" = "true",
+ "disable_auto_compaction" = "false",
+ "enable_single_replica_compaction" = "false"
+ );
+ """
+
+ // result is random, couldn't check it
+ sql """ select * from test_table_sample_tbl tablesample(4 rows);"""
+ sql """select * from test_table_sample_tbl t tablesample(20 percent);"""
+ sql """select * from test_table_sample_tbl t tablesample(20 percent)
repeatable 2;"""
+}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]