diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinTableValuedFunctions.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinTableValuedFunctions.java index 66bdce4c09..edf5ce47fa 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinTableValuedFunctions.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinTableValuedFunctions.java @@ -18,6 +18,7 @@ package org.apache.doris.catalog; import org.apache.doris.nereids.trees.expressions.functions.table.Hdfs; +import org.apache.doris.nereids.trees.expressions.functions.table.Local; import org.apache.doris.nereids.trees.expressions.functions.table.Numbers; import org.apache.doris.nereids.trees.expressions.functions.table.S3; @@ -33,7 +34,8 @@ public class BuiltinTableValuedFunctions implements FunctionHelper { public final ImmutableList tableValuedFunctions = ImmutableList.of( tableValued(Numbers.class, "numbers"), tableValued(Hdfs.class, "hdfs"), - tableValued(S3.class, "s3") + tableValued(S3.class, "s3"), + tableValued(Local.class, "local") ); public static final BuiltinTableValuedFunctions INSTANCE = new BuiltinTableValuedFunctions(); @@ -41,3 +43,4 @@ public class BuiltinTableValuedFunctions implements FunctionHelper { // Note: Do not add any code here! private BuiltinTableValuedFunctions() {} } + diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/PruneFileScanPartition.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/PruneFileScanPartition.java index 4e35b8d82b..ade445f4d8 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/PruneFileScanPartition.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/PruneFileScanPartition.java @@ -34,6 +34,7 @@ import org.apache.doris.nereids.trees.plans.logical.LogicalFileScan; import org.apache.doris.nereids.trees.plans.logical.LogicalFileScan.SelectedPartitions; import org.apache.doris.nereids.trees.plans.logical.LogicalFilter; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; import org.apache.commons.collections.CollectionUtils; @@ -55,31 +56,35 @@ public class PruneFileScanPartition extends OneRewriteRuleFactory { @Override public Rule build() { - return logicalFilter(logicalFileScan()).when(p -> p.child().getSelectedPartitions() == null).thenApply(ctx -> { - LogicalFilter filter = ctx.root; - LogicalFileScan scan = filter.child(); - ExternalTable tbl = scan.getTable(); - SelectedPartitions selectedPartitions = new SelectedPartitions(0, Maps.newHashMap(), false); + return logicalFilter(logicalFileScan()).whenNot(p -> p.child().getSelectedPartitions().isPruned) + .thenApply(ctx -> { + LogicalFilter filter = ctx.root; + LogicalFileScan scan = filter.child(); + ExternalTable tbl = scan.getTable(); - // TODO(cmy): support other external table - if (tbl instanceof HMSExternalTable && ((HMSExternalTable) tbl).getDlaType() == DLAType.HIVE) { - HMSExternalTable hiveTbl = (HMSExternalTable) tbl; - selectedPartitions = pruneHivePartitions(hiveTbl, filter, scan, ctx.cascadesContext); - } + SelectedPartitions selectedPartitions; + // TODO(cmy): support other external table + if (tbl instanceof HMSExternalTable && ((HMSExternalTable) tbl).getDlaType() == DLAType.HIVE) { + HMSExternalTable hiveTbl = (HMSExternalTable) tbl; + selectedPartitions = pruneHivePartitions(hiveTbl, filter, scan, ctx.cascadesContext); + } else { + // set isPruned so that it won't go pass the partition prune again + selectedPartitions = new SelectedPartitions(0, ImmutableMap.of(), true); + } - LogicalFileScan rewrittenScan = scan.withConjuncts(filter.getConjuncts()) - .withSelectedPartitions(selectedPartitions); - return new LogicalFilter<>(filter.getConjuncts(), rewrittenScan); - }).toRule(RuleType.FILE_SCAN_PARTITION_PRUNE); + LogicalFileScan rewrittenScan = scan.withConjuncts(filter.getConjuncts()) + .withSelectedPartitions(selectedPartitions); + return new LogicalFilter<>(filter.getConjuncts(), rewrittenScan); + }).toRule(RuleType.FILE_SCAN_PARTITION_PRUNE); } private SelectedPartitions pruneHivePartitions(HMSExternalTable hiveTbl, LogicalFilter filter, LogicalFileScan scan, CascadesContext ctx) { Map selectedPartitionItems = Maps.newHashMap(); if (CollectionUtils.isEmpty(hiveTbl.getPartitionColumns())) { - // non partitioned table, return null. - // and it will be handled in HiveScanNode - return new SelectedPartitions(1, Maps.newHashMap(), false); + // non partitioned table, return NOT_PRUNED. + // non partition table will be handled in HiveScanNode. + return SelectedPartitions.NOT_PRUNED; } Map scanOutput = scan.getOutput() .stream() @@ -104,3 +109,4 @@ public class PruneFileScanPartition extends OneRewriteRuleFactory { return new SelectedPartitions(idToPartitionItem.size(), selectedPartitionItems, true); } } + diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/ExpressionEstimation.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/ExpressionEstimation.java index aa84077398..30bcba4234 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/ExpressionEstimation.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/ExpressionEstimation.java @@ -95,6 +95,7 @@ import org.apache.doris.statistics.ColumnStatistic; import org.apache.doris.statistics.ColumnStatisticBuilder; import org.apache.doris.statistics.Statistics; +import com.google.common.base.Preconditions; import org.apache.commons.collections.CollectionUtils; import java.time.Instant; @@ -163,7 +164,7 @@ public class ExpressionEstimation extends ExpressionVisitor slots) { - return new Statistics(0, new HashMap<>()); - } - @Override public R accept(ExpressionVisitor visitor, C context) { return visitor.visitHdfs(this, context); diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/table/Local.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/table/Local.java new file mode 100644 index 0000000000..d45a4c9394 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/table/Local.java @@ -0,0 +1,58 @@ +// 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.expressions.functions.table; + +import org.apache.doris.catalog.FunctionSignature; +import org.apache.doris.nereids.exceptions.AnalysisException; +import org.apache.doris.nereids.trees.expressions.Properties; +import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; +import org.apache.doris.nereids.types.coercion.AnyDataType; +import org.apache.doris.tablefunction.LocalTableValuedFunction; +import org.apache.doris.tablefunction.TableValuedFunctionIf; + +import java.util.Map; + +/** + * local + */ +public class Local extends TableValuedFunction { + public Local(Properties properties) { + super("local", properties); + } + + @Override + public FunctionSignature customSignature() { + return FunctionSignature.of(AnyDataType.INSTANCE_WITHOUT_INDEX, getArgumentsTypes()); + } + + @Override + protected TableValuedFunctionIf toCatalogFunction() { + try { + Map arguments = getTVFProperties().getMap(); + return new LocalTableValuedFunction(arguments); + } catch (Throwable t) { + throw new AnalysisException("Can not build LocalTableValuedFunction by " + + this + ": " + t.getMessage(), t); + } + } + + @Override + public R accept(ExpressionVisitor visitor, C context) { + return visitor.visitLocal(this, context); + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/table/S3.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/table/S3.java index b74fc61a4b..1f3d7cb805 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/table/S3.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/table/S3.java @@ -20,15 +20,11 @@ package org.apache.doris.nereids.trees.expressions.functions.table; import org.apache.doris.catalog.FunctionSignature; import org.apache.doris.nereids.exceptions.AnalysisException; import org.apache.doris.nereids.trees.expressions.Properties; -import org.apache.doris.nereids.trees.expressions.Slot; import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; import org.apache.doris.nereids.types.coercion.AnyDataType; -import org.apache.doris.statistics.Statistics; import org.apache.doris.tablefunction.S3TableValuedFunction; import org.apache.doris.tablefunction.TableValuedFunctionIf; -import java.util.HashMap; -import java.util.List; import java.util.Map; /** s3 */ @@ -39,7 +35,7 @@ public class S3 extends TableValuedFunction { @Override public FunctionSignature customSignature() { - return FunctionSignature.of(AnyDataType.INSTANCE_WITHOUT_INDEX, (List) getArgumentsTypes()); + return FunctionSignature.of(AnyDataType.INSTANCE_WITHOUT_INDEX, getArgumentsTypes()); } @Override @@ -53,11 +49,6 @@ public class S3 extends TableValuedFunction { } } - @Override - public Statistics computeStats(List slots) { - return new Statistics(0, new HashMap<>()); - } - @Override public R accept(ExpressionVisitor visitor, C context) { return visitor.visitS3(this, context); diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/table/TableValuedFunction.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/table/TableValuedFunction.java index 29019f6139..5acc73eb75 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/table/TableValuedFunction.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/table/TableValuedFunction.java @@ -22,6 +22,7 @@ import org.apache.doris.catalog.FunctionGenTable; import org.apache.doris.nereids.exceptions.AnalysisException; import org.apache.doris.nereids.exceptions.UnboundException; import org.apache.doris.nereids.properties.PhysicalProperties; +import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.Properties; import org.apache.doris.nereids.trees.expressions.Slot; import org.apache.doris.nereids.trees.expressions.functions.BoundFunction; @@ -29,13 +30,16 @@ import org.apache.doris.nereids.trees.expressions.functions.CustomSignature; import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression; import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; import org.apache.doris.nereids.types.DataType; +import org.apache.doris.statistics.ColumnStatistic; import org.apache.doris.statistics.Statistics; import org.apache.doris.tablefunction.TableValuedFunctionIf; import com.google.common.base.Suppliers; import com.google.common.collect.ImmutableList; +import com.google.common.collect.Maps; import java.util.List; +import java.util.Map; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -59,7 +63,20 @@ public abstract class TableValuedFunction extends BoundFunction implements Unary protected abstract TableValuedFunctionIf toCatalogFunction(); - public abstract Statistics computeStats(List slots); + /** + * For most of tvf, eg, s3/local/hdfs, the column stats is unknown. + * The derived tvf can override this method to compute the column stats. + * + * @param slots the slots of the tvf + * @return the column stats of the tvf + */ + public Statistics computeStats(List slots) { + Map columnToStatistics = Maps.newHashMap(); + for (Slot slot : slots) { + columnToStatistics.put(slot, ColumnStatistic.UNKNOWN); + } + return new Statistics(0, columnToStatistics); + } public Properties getTVFProperties() { return (Properties) child(0); diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/TableValuedFunctionVisitor.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/TableValuedFunctionVisitor.java index 0c4adcabe1..cbf980282a 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/TableValuedFunctionVisitor.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/TableValuedFunctionVisitor.java @@ -18,6 +18,7 @@ package org.apache.doris.nereids.trees.expressions.visitor; import org.apache.doris.nereids.trees.expressions.functions.table.Hdfs; +import org.apache.doris.nereids.trees.expressions.functions.table.Local; import org.apache.doris.nereids.trees.expressions.functions.table.Numbers; import org.apache.doris.nereids.trees.expressions.functions.table.S3; import org.apache.doris.nereids.trees.expressions.functions.table.TableValuedFunction; @@ -34,6 +35,10 @@ public interface TableValuedFunctionVisitor { return visitTableValuedFunction(hdfs, context); } + default R visitLocal(Local local, C context) { + return visitTableValuedFunction(local, context); + } + default R visitS3(S3 s3, C context) { return visitTableValuedFunction(s3, context); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalFileScan.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalFileScan.java index 4b46084a82..c25a25efce 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalFileScan.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalFileScan.java @@ -29,7 +29,7 @@ import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor; import org.apache.doris.nereids.util.Utils; import com.google.common.base.Preconditions; -import com.google.common.collect.Maps; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Sets; import lombok.Getter; @@ -64,7 +64,7 @@ public class LogicalFileScan extends LogicalCatalogRelation { public LogicalFileScan(RelationId id, ExternalTable table, List qualifier) { this(id, table, qualifier, Optional.empty(), Optional.empty(), - Sets.newHashSet(), SelectedPartitions.EMPTY); + Sets.newHashSet(), SelectedPartitions.NOT_PRUNED); } @Override @@ -121,39 +121,51 @@ public class LogicalFileScan extends LogicalCatalogRelation { * Mainly for hive table partition pruning. */ public static class SelectedPartitions { - public static SelectedPartitions EMPTY = new SelectedPartitions(0, Maps.newHashMap(), false); + // NOT_PRUNED means the Nereids planner does not handle the partition pruning. + // This can be treated as the initial value of SelectedPartitions. + // Or used to indicate that the partition pruning is not processed. + public static SelectedPartitions NOT_PRUNED = new SelectedPartitions(0, ImmutableMap.of(), false); /** * total partition number */ - public long totalPartitionNum = 0; + public final long totalPartitionNum; /** * partition id -> partition item */ - public Map selectedPartitions; + public final Map selectedPartitions; /** * true means the result is after partition pruning * false means the partition pruning is not processed. */ - public boolean isPartitionPruned; + public final boolean isPruned; /** * Constructor for SelectedPartitions. */ public SelectedPartitions(long totalPartitionNum, Map selectedPartitions, - boolean isPartitionPruned) { + boolean isPruned) { this.totalPartitionNum = totalPartitionNum; - this.selectedPartitions = selectedPartitions; - this.isPartitionPruned = isPartitionPruned; - if (this.selectedPartitions == null) { - this.selectedPartitions = Maps.newHashMap(); - } + this.selectedPartitions = ImmutableMap.copyOf(Objects.requireNonNull(selectedPartitions, + "selectedPartitions is null")); + this.isPruned = isPruned; } @Override public boolean equals(Object o) { - return isPartitionPruned == ((SelectedPartitions) o).isPartitionPruned && Objects.equals( - selectedPartitions.keySet(), ((SelectedPartitions) o).selectedPartitions.keySet()); + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SelectedPartitions that = (SelectedPartitions) o; + return isPruned == that.isPruned && Objects.equals( + selectedPartitions.keySet(), that.selectedPartitions.keySet()); + } + + @Override + public int hashCode() { + return Objects.hash(selectedPartitions, isPruned); } } } - diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalFileScan.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalFileScan.java index 9088217cad..be4f5b1798 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalFileScan.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalFileScan.java @@ -83,7 +83,7 @@ public class PhysicalFileScan extends PhysicalCatalogRelation { "stats", statistics, "conjuncts", conjuncts, "selected partitions num", - selectedPartitions.isPartitionPruned ? selectedPartitions.selectedPartitions.size() : "unknown" + selectedPartitions.isPruned ? selectedPartitions.selectedPartitions.size() : "unknown" ); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/planner/external/HiveScanNode.java b/fe/fe-core/src/main/java/org/apache/doris/planner/external/HiveScanNode.java index a52a86d503..0b6e1d4446 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/planner/external/HiveScanNode.java +++ b/fe/fe-core/src/main/java/org/apache/doris/planner/external/HiveScanNode.java @@ -85,6 +85,7 @@ public class HiveScanNode extends FileQueryScanNode { protected final HMSExternalTable hmsTable; private HiveTransaction hiveTransaction = null; + // will only be set in Nereids, for lagency planner, it should be null @Setter private SelectedPartitions selectedPartitions = null; @@ -127,7 +128,7 @@ public class HiveScanNode extends FileQueryScanNode { List partitionColumnTypes = hmsTable.getPartitionColumnTypes(); if (!partitionColumnTypes.isEmpty()) { // partitioned table - boolean isPartitionPruned = selectedPartitions == null ? false : selectedPartitions.isPartitionPruned; + boolean isPartitionPruned = selectedPartitions == null ? false : selectedPartitions.isPruned; Collection partitionItems; if (!isPartitionPruned) { // partitionItems is null means that the partition is not pruned by Nereids, diff --git a/regression-test/suites/external_table_p0/tvf/test_local_tvf.groovy b/regression-test/suites/external_table_p0/tvf/test_local_tvf.groovy deleted file mode 100644 index 21d985b358..0000000000 --- a/regression-test/suites/external_table_p0/tvf/test_local_tvf.groovy +++ /dev/null @@ -1,75 +0,0 @@ -// 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. - -// This suit test the `backends` tvf -suite("test_local_tvf") { - List> table = sql """ select * from backends(); """ - assertTrue(table.size() > 0) - - if ( table.size() == 1) { - // here may do not have fe log with multi doris be cluster - def be_id = table[0][0] - - List> doris_log = sql """ ADMIN SHOW FRONTEND CONFIG like "sys_log_dir"; """ - assertTrue(doris_log.size() > 0) - def doris_log_path = doris_log[0][1] - - table = sql """ - select count(*) from local( - "file_path" = "${doris_log_path}/fe.out", - "backend_id" = "${be_id}", - "format" = "csv") - where c1 like "%FE type%";""" - - assertTrue(table.size() > 0) - assertTrue(Long.valueOf(table[0][0]) > 0) - - table = sql """ - select count(*) from local( - "file_path" = "${doris_log_path}/*.out", - "backend_id" = "${be_id}", - "format" = "csv") - where c1 like "%FE type%";""" - - assertTrue(table.size() > 0) - assertTrue(Long.valueOf(table[0][0]) > 0) - - test { - sql """ - select count(*) from local( - "file_path" = "../fe.out", - "backend_id" = "${be_id}", - "format" = "csv") - where c1 like "%FE type%"; - """ - // check exception message contains - exception "can not contain '..' in path" - } - - test { - sql """ - select count(*) from local( - "file_path" = "./xx.out", - "backend_id" = "${be_id}", - "format" = "csv") - where c1 like "%FE type%"; - """ - // check exception message contains - exception "No matches found" - } - } -} diff --git a/regression-test/suites/external_table_p2/hive/test_external_catalog_hive.groovy b/regression-test/suites/external_table_p2/hive/test_external_catalog_hive.groovy index 09394a6122..e02de02628 100644 --- a/regression-test/suites/external_table_p2/hive/test_external_catalog_hive.groovy +++ b/regression-test/suites/external_table_p2/hive/test_external_catalog_hive.groovy @@ -94,8 +94,8 @@ suite("test_external_catalog_hive", "p2,external,hive,external_remote,external_r qt_not_single_slot_filter_conjuncts_parquet """ select * from multi_catalog.lineitem_string_date_orc where l_commitdate < l_receiptdate and l_receiptdate = '1995-01-01' order by l_orderkey, l_partkey, l_suppkey, l_linenumber limit 10; """ // test null expr with dict filter issue - qt_null_expr_dict_filter_orc """ select count(*), count(distinct user_no) from multi_catalog.dict_fitler_test_orc WHERE partitions in ('2023-08-21') and actual_intf_type = 'type1' and (REUSE_FLAG<> 'y' or REUSE_FLAG is null); """ - qt_null_expr_dict_filter_parquet """ select count(*), count(distinct user_no) from multi_catalog.dict_fitler_test_parquet WHERE partitions in ('2023-08-21') and actual_intf_type = 'type1' and (REUSE_FLAG<> 'y' or REUSE_FLAG is null); """ + qt_null_expr_dict_filter_orc """ select count(*), count(distinct user_no) from multi_catalog.dict_fitler_test_orc WHERE `partitions` in ('2023-08-21') and actual_intf_type = 'type1' and (REUSE_FLAG<> 'y' or REUSE_FLAG is null); """ + qt_null_expr_dict_filter_parquet """ select count(*), count(distinct user_no) from multi_catalog.dict_fitler_test_parquet WHERE `partitions` in ('2023-08-21') and actual_intf_type = 'type1' and (REUSE_FLAG<> 'y' or REUSE_FLAG is null); """ // test par fields in file qt_par_fields_in_file_orc1 """ select * from multi_catalog.par_fields_in_file_orc where year = 2023 and month = 8 order by id; """ diff --git a/regression-test/suites/external_table_p2/hive/test_hive_default_partition.groovy b/regression-test/suites/external_table_p2/hive/test_hive_default_partition.groovy index d96d5d8362..c69f79c141 100644 --- a/regression-test/suites/external_table_p2/hive/test_hive_default_partition.groovy +++ b/regression-test/suites/external_table_p2/hive/test_hive_default_partition.groovy @@ -206,7 +206,7 @@ suite("test_hive_default_partition", "p2,external,hive,external_remote,external_ explain { sql("${string_part_prune1}") - contains "partition=2/4" + contains "partition=1/4" } explain { sql("${string_part_prune2}") @@ -222,7 +222,7 @@ suite("test_hive_default_partition", "p2,external,hive,external_remote,external_ } explain { sql("${string_part_prune5}") - contains "partition=2/4" + contains "partition=1/4" } explain { sql("${string_part_prune6}") @@ -234,11 +234,11 @@ suite("test_hive_default_partition", "p2,external,hive,external_remote,external_ } explain { sql("${string_part_prune8}") - contains "partition=2/4" + contains "partition=1/4" } explain { sql("${string_part_prune9}") - contains "partition=2/4" + contains "partition=1/4" } } } diff --git a/regression-test/suites/external_table_p2/tvf/test_local_tvf_compression.groovy b/regression-test/suites/external_table_p2/tvf/test_local_tvf_compression.groovy index 0f783900df..8b13d88a4f 100644 --- a/regression-test/suites/external_table_p2/tvf/test_local_tvf_compression.groovy +++ b/regression-test/suites/external_table_p2/tvf/test_local_tvf_compression.groovy @@ -32,6 +32,8 @@ suite("test_local_tvf_compression", "p2,external,tvf,external_remote,external_re String filename = "test_tvf.csv" + sql """set enable_nereids_planner=true""" + sql """set enable_fallback_to_original_planner=false""" String compress_type = "gz" qt_gz_1 """ @@ -123,5 +125,30 @@ suite("test_local_tvf_compression", "p2,external,tvf,external_remote,external_re "format" = "csv", "compress_type" ="${compress_type}block") where c2="abcd" order by c3 limit 22 ; """ + + // test error case + test { + sql """ + select count(*) from local( + "file_path" = "../be.out", + "backend_id" = "${be_id}", + "format" = "csv") + where c1 like "%FE type%"; + """ + // check exception message contains + exception "can not contain '..' in path" + } + + test { + sql """ + select count(*) from local( + "file_path" = "./xx.out", + "backend_id" = "${be_id}", + "format" = "csv") + where c1 like "%FE type%"; + """ + // check exception message contains + exception "No matches found" + } }