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
commit 6f23a0f86bf47425a93ecdc33fa75cb9161819e3 Author: zhiqqqq <[email protected]> AuthorDate: Tue Oct 10 07:25:58 2023 -0500 [Fix](func numbers) Remove backend_nums argument of numbers function (#25200) --- .../vec/exec/data_gen_functions/vnumbers_tvf.cpp | 3 ++ .../sql-functions/table-functions/numbers.md | 4 +-- .../sql-functions/table-functions/numbers.md | 4 +-- .../org/apache/doris/planner/DataGenScanNode.java | 10 +++++++ .../main/java/org/apache/doris/qe/Coordinator.java | 15 +++++++--- .../tablefunction/NumbersTableValuedFunction.java | 32 ++++++---------------- .../http_rest_api/post/test_query_stmt.groovy | 2 +- .../nereids_syntax_p0/aggregate_strategies.groovy | 8 +++--- .../suites/nereids_syntax_p0/function.groovy | 4 +-- .../nereids_syntax_p2/aggregate_strategies.groovy | 8 +++--- 10 files changed, 46 insertions(+), 44 deletions(-) diff --git a/be/src/vec/exec/data_gen_functions/vnumbers_tvf.cpp b/be/src/vec/exec/data_gen_functions/vnumbers_tvf.cpp index 278e9743320..2ac6c0fca42 100644 --- a/be/src/vec/exec/data_gen_functions/vnumbers_tvf.cpp +++ b/be/src/vec/exec/data_gen_functions/vnumbers_tvf.cpp @@ -80,6 +80,9 @@ Status VNumbersTVF::get_next(RuntimeState* state, vectorized::Block* block, bool } Status VNumbersTVF::set_scan_ranges(const std::vector<TScanRangeParams>& scan_range_params) { + // Currently we do not support multi-threads numbers function, so there is no need to + // use more than one scan_range_param. + DCHECK(scan_range_params.size() == 1); _total_numbers = scan_range_params[0].scan_range.data_gen_scan_range.numbers_params.totalNumbers; return Status::OK(); diff --git a/docs/en/docs/sql-manual/sql-functions/table-functions/numbers.md b/docs/en/docs/sql-manual/sql-functions/table-functions/numbers.md index c555e403acb..ae0f694e71e 100644 --- a/docs/en/docs/sql-manual/sql-functions/table-functions/numbers.md +++ b/docs/en/docs/sql-manual/sql-functions/table-functions/numbers.md @@ -36,14 +36,12 @@ This function is used in FROM clauses. ```sql numbers( - "number" = "n", - "backend_num" = "m" + "number" = "n" ); ``` parameter: - `number`: It means to generate rows [0, n). -- `backend_num`: Optional parameters. It means this function is executed simultaneously on `m` be nodes (multiple BEs need to be deployed). ### example ``` diff --git a/docs/zh-CN/docs/sql-manual/sql-functions/table-functions/numbers.md b/docs/zh-CN/docs/sql-manual/sql-functions/table-functions/numbers.md index ce943795053..ed44c78eb49 100644 --- a/docs/zh-CN/docs/sql-manual/sql-functions/table-functions/numbers.md +++ b/docs/zh-CN/docs/sql-manual/sql-functions/table-functions/numbers.md @@ -35,14 +35,12 @@ under the License. #### syntax ```sql numbers( - "number" = "n", - "backend_num" = "m" + "number" = "n" ); ``` 参数: - `number`: 代表生成[0,n)的行。 -- `backend_num`: 可选参数,代表`m`个be节点同时执行该函数(需要部署多个be)。 ### example ``` diff --git a/fe/fe-core/src/main/java/org/apache/doris/planner/DataGenScanNode.java b/fe/fe-core/src/main/java/org/apache/doris/planner/DataGenScanNode.java index 46af5ec1ae2..d00641d135c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/planner/DataGenScanNode.java +++ b/fe/fe-core/src/main/java/org/apache/doris/planner/DataGenScanNode.java @@ -107,4 +107,14 @@ public class DataGenScanNode extends ExternalScanNode { public boolean needToCheckColumnPriv() { return false; } + + // Currently DataGenScanNode is only used by DataGenTableValuedFunction, which is + // inherited by NumbersTableValuedFunction. + // NumbersTableValuedFunction is not a complete implementation for now, since its + // function signature do not support us to split total numbers, so it can not be executed + // by multi-processes or multi-threads. So we assign instance number to 1. + @Override + public int getNumInstances() { + return 1; + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/Coordinator.java b/fe/fe-core/src/main/java/org/apache/doris/qe/Coordinator.java index 2c52eecdd04..49afb6e6851 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/qe/Coordinator.java +++ b/fe/fe-core/src/main/java/org/apache/doris/qe/Coordinator.java @@ -637,8 +637,9 @@ public class Coordinator implements CoordInterface { // else use exec_plan_fragments directly. // we choose #fragments >=2 because in some cases // we need ensure that A fragment is already prepared to receive data before B fragment sends data. - // For example: select * from numbers("10","w") will generate ExchangeNode and TableValuedFunctionScanNode, - // we should ensure TableValuedFunctionScanNode does not send data until ExchangeNode is ready to receive. + // For example: select * from numbers("number"="10") will generate ExchangeNode and + // TableValuedFunctionScanNode, we should ensure TableValuedFunctionScanNode does + // not send data until ExchangeNode is ready to receive. boolean twoPhaseExecution = fragments.size() >= 2; for (PlanFragment fragment : fragments) { FragmentExecParams params = fragmentExecParamsMap.get(fragment.getFragmentId()); @@ -759,8 +760,9 @@ public class Coordinator implements CoordInterface { // else use exec_plan_fragments directly. // we choose #fragments >=2 because in some cases // we need ensure that A fragment is already prepared to receive data before B fragment sends data. - // For example: select * from numbers("10","w") will generate ExchangeNode and TableValuedFunctionScanNode, - // we should ensure TableValuedFunctionScanNode does not send data until ExchangeNode is ready to receive. + // For example: select * from numbers("number"="10") will generate ExchangeNode and + // TableValuedFunctionScanNode, we should ensure TableValuedFunctionScanNode does not + // send data until ExchangeNode is ready to receive. boolean twoPhaseExecution = fragments.size() >= 2; for (PlanFragment fragment : fragments) { FragmentExecParams params = fragmentExecParamsMap.get(fragment.getFragmentId()); @@ -2116,6 +2118,11 @@ public class Coordinator implements CoordInterface { FragmentScanRangeAssignment assignment, Map<TNetworkAddress, Long> assignedBytesPerHost, Map<TNetworkAddress, Long> replicaNumPerHost) throws Exception { + // Type of locations is List, it could have elements that have same "location" + // and we do have this situation for some scan node. + // The duplicate "location" will NOT be filtered by FragmentScanRangeAssignment, + // since FragmentScanRangeAssignment use List<TScanRangeParams> as its value type, + // duplicate "locations" will be converted to list. for (TScanRangeLocations scanRangeLocations : locations) { Reference<Long> backendIdRef = new Reference<Long>(); TScanRangeLocation minLocation = selectBackendsByRoundRobin(scanRangeLocations, diff --git a/fe/fe-core/src/main/java/org/apache/doris/tablefunction/NumbersTableValuedFunction.java b/fe/fe-core/src/main/java/org/apache/doris/tablefunction/NumbersTableValuedFunction.java index 639dfeef351..3c0b578b50a 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/tablefunction/NumbersTableValuedFunction.java +++ b/fe/fe-core/src/main/java/org/apache/doris/tablefunction/NumbersTableValuedFunction.java @@ -41,20 +41,16 @@ import java.util.Map; // have a single column number /** - * The Implement of table valued function——numbers("number" = "N", "backend_num" = "M"). + * The Implement of table valued function——numbers("number" = "N"). */ public class NumbersTableValuedFunction extends DataGenTableValuedFunction { public static final String NAME = "numbers"; public static final String NUMBER = "number"; - public static final String BACKEND_NUM = "backend_num"; private static final ImmutableSet<String> PROPERTIES_SET = new ImmutableSet.Builder<String>() .add(NUMBER) - .add(BACKEND_NUM) .build(); // The total numbers will be generated. private long totalNumbers; - // The total backends will server it. - private int tabletsNum; /** * Constructor. @@ -70,11 +66,6 @@ public class NumbersTableValuedFunction extends DataGenTableValuedFunction { validParams.put(key.toLowerCase(), params.get(key)); } - try { - tabletsNum = Integer.parseInt(validParams.getOrDefault(BACKEND_NUM, "1")); - } catch (NumberFormatException e) { - throw new AnalysisException("can not parse `backend_num` param to natural number"); - } String numberStr = validParams.get(NUMBER); if (!Strings.isNullOrEmpty(numberStr)) { try { @@ -92,10 +83,6 @@ public class NumbersTableValuedFunction extends DataGenTableValuedFunction { return totalNumbers; } - public int getTabletsNum() { - return tabletsNum; - } - @Override public TDataGenFunctionName getDataGenFunctionName() { return TDataGenFunctionName.NUMBERS; @@ -124,17 +111,16 @@ public class NumbersTableValuedFunction extends DataGenTableValuedFunction { if (backendList.isEmpty()) { throw new AnalysisException("No Alive backends"); } + Collections.shuffle(backendList); List<TableValuedFunctionTask> res = Lists.newArrayList(); - for (int i = 0; i < tabletsNum; ++i) { - TScanRange scanRange = new TScanRange(); - TDataGenScanRange dataGenScanRange = new TDataGenScanRange(); - TTVFNumbersScanRange tvfNumbersScanRange = new TTVFNumbersScanRange(); - tvfNumbersScanRange.setTotalNumbers(totalNumbers); - dataGenScanRange.setNumbersParams(tvfNumbersScanRange); - scanRange.setDataGenScanRange(dataGenScanRange); - res.add(new TableValuedFunctionTask(backendList.get(i % backendList.size()), scanRange)); - } + TScanRange scanRange = new TScanRange(); + TDataGenScanRange dataGenScanRange = new TDataGenScanRange(); + TTVFNumbersScanRange tvfNumbersScanRange = new TTVFNumbersScanRange(); + tvfNumbersScanRange.setTotalNumbers(totalNumbers); + dataGenScanRange.setNumbersParams(tvfNumbersScanRange); + scanRange.setDataGenScanRange(dataGenScanRange); + res.add(new TableValuedFunctionTask(backendList.get(0), scanRange)); return res; } } diff --git a/regression-test/suites/http_rest_api/post/test_query_stmt.groovy b/regression-test/suites/http_rest_api/post/test_query_stmt.groovy index 7a03cdc48bd..bcf6e23984c 100644 --- a/regression-test/suites/http_rest_api/post/test_query_stmt.groovy +++ b/regression-test/suites/http_rest_api/post/test_query_stmt.groovy @@ -49,7 +49,7 @@ suite("test_query_stmt") { def url= "/api/query/default_cluster/" + context.config.defaultDb // test select - def stmt1 = """ select * from numbers('number' = '10', 'backend_num' = '1') """ + def stmt1 = """ select * from numbers('number' = '10') """ def stmt1_json = JsonOutput.toJson(new Stmt(stmt: stmt1)); def resJson = http_post(url, stmt1_json) diff --git a/regression-test/suites/nereids_syntax_p0/aggregate_strategies.groovy b/regression-test/suites/nereids_syntax_p0/aggregate_strategies.groovy index ea63b5b7898..e2f5d8e0cf0 100644 --- a/regression-test/suites/nereids_syntax_p0/aggregate_strategies.groovy +++ b/regression-test/suites/nereids_syntax_p0/aggregate_strategies.groovy @@ -170,7 +170,7 @@ suite("aggregate_strategies") { sql """select /*+SET_VAR(disable_nereids_rules='TWO_PHASE_AGGREGATE_WITH_DISTINCT')*/ count(distinct number) - from numbers('number' = '10000', 'backend_num'='10')""" + from numbers('number' = '10000')""" result([[10000L]]) } @@ -178,7 +178,7 @@ suite("aggregate_strategies") { sql """select /*+SET_VAR(disable_nereids_rules='THREE_PHASE_AGGREGATE_WITH_DISTINCT')*/ count(distinct number) - from numbers('number' = '10000', 'backend_num'='10')""" + from numbers('number' = '10000')""" result([[10000L]]) } @@ -186,7 +186,7 @@ suite("aggregate_strategies") { sql """select /*+SET_VAR(disable_nereids_rules='TWO_PHASE_AGGREGATE_WITH_DISTINCT')*/ count(distinct number) - from numbers('number' = '10000', 'backend_num'='1')""" + from numbers('number' = '10000')""" result([[10000L]]) } @@ -194,7 +194,7 @@ suite("aggregate_strategies") { sql """select /*+SET_VAR(disable_nereids_rules='THREE_PHASE_AGGREGATE_WITH_DISTINCT')*/ count(distinct number) - from numbers('number' = '10000', 'backend_num'='1')""" + from numbers('number' = '10000')""" result([[10000L]]) } diff --git a/regression-test/suites/nereids_syntax_p0/function.groovy b/regression-test/suites/nereids_syntax_p0/function.groovy index 3f05deb09a2..498273bad91 100644 --- a/regression-test/suites/nereids_syntax_p0/function.groovy +++ b/regression-test/suites/nereids_syntax_p0/function.groovy @@ -70,7 +70,7 @@ suite("nereids_function") { // numbers: table valued function test { - sql "select `number` from numbers(number = 10, backend_num = 1)" + sql "select `number` from numbers(number = 10)" result([[0L], [1L], [2L], [3L], [4L], [5L], [6L], [7L], [8L], [9L]]) } @@ -91,7 +91,7 @@ suite("nereids_function") { qt_subquery3 """ select a.number from numbers("number" = "10") a where number in (select number from numbers("number" = "10") b where a.number=b.number); """ test { - sql """select `number` from numbers("number" = -1, 'backend_num' = `1`)""" + sql """select `number` from numbers("number" = "-1")""" result([]) } diff --git a/regression-test/suites/nereids_syntax_p2/aggregate_strategies.groovy b/regression-test/suites/nereids_syntax_p2/aggregate_strategies.groovy index cebd90a955c..e2ad64f688e 100644 --- a/regression-test/suites/nereids_syntax_p2/aggregate_strategies.groovy +++ b/regression-test/suites/nereids_syntax_p2/aggregate_strategies.groovy @@ -20,7 +20,7 @@ suite("aggregate_strategies") { sql """select /*+SET_VAR(disable_nereids_rules='TWO_PHASE_AGGREGATE_WITH_DISTINCT')*/ count(distinct number) - from numbers('number' = '10000000', 'backend_num'='10')""" + from numbers('number' = '10000000')""" result([[10000000L]]) } @@ -28,7 +28,7 @@ suite("aggregate_strategies") { sql """select /*+SET_VAR(disable_nereids_rules='THREE_PHASE_AGGREGATE_WITH_DISTINCT')*/ count(distinct number) - from numbers('number' = '10000000', 'backend_num'='10')""" + from numbers('number' = '10000000')""" result([[10000000L]]) } @@ -36,7 +36,7 @@ suite("aggregate_strategies") { sql """select /*+SET_VAR(disable_nereids_rules='TWO_PHASE_AGGREGATE_WITH_DISTINCT')*/ count(distinct number) - from numbers('number' = '10000000', 'backend_num'='1')""" + from numbers('number' = '10000000')""" result([[10000000L]]) } @@ -44,7 +44,7 @@ suite("aggregate_strategies") { sql """select /*+SET_VAR(disable_nereids_rules='THREE_PHASE_AGGREGATE_WITH_DISTINCT')*/ count(distinct number) - from numbers('number' = '10000000', 'backend_num'='1')""" + from numbers('number' = '10000000')""" result([[10000000L]]) } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
