This is an automated email from the ASF dual-hosted git repository. yiguolei pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push: new f33c5cfc72c [opt](profile) Add ExecutedByFrontend in profile (#39942) f33c5cfc72c is described below commit f33c5cfc72c3a0d795e671dc3a18d17083568324 Author: zhiqiang <seuhezhiqi...@163.com> AuthorDate: Tue Aug 27 13:20:11 2024 +0800 [opt](profile) Add ExecutedByFrontend in profile (#39942) `Executed By Frontend: true` means query is executed on FE. <img width="561" alt="image" src="https://github.com/user-attachments/assets/ce6899f2-55a5-4972-810b-1805f2a0db16"> --- .../doris/common/profile/SummaryProfile.java | 8 +- .../java/org/apache/doris/qe/StmtExecutor.java | 5 ++ .../query_profile/test_execute_by_frontend.groovy | 90 ++++++++++++++++++++++ 3 files changed, 102 insertions(+), 1 deletion(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/common/profile/SummaryProfile.java b/fe/fe-core/src/main/java/org/apache/doris/common/profile/SummaryProfile.java index ed1f0caa027..df4e73be048 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/common/profile/SummaryProfile.java +++ b/fe/fe-core/src/main/java/org/apache/doris/common/profile/SummaryProfile.java @@ -69,6 +69,7 @@ public class SummaryProfile { public static final String PHYSICAL_PLAN = "Physical Plan"; public static final String DISTRIBUTED_PLAN = "Distributed Plan"; public static final String SYSTEM_MESSAGE = "System Message"; + public static final String EXECUTED_BY_FRONTEND = "Executed By Frontend"; // Execution Summary public static final String EXECUTION_SUMMARY_PROFILE_NAME = "Execution Summary"; public static final String ANALYSIS_TIME = "Analysis Time"; @@ -175,7 +176,8 @@ public class SummaryProfile { PARALLEL_FRAGMENT_EXEC_INSTANCE, TRACE_ID, TRANSACTION_COMMIT_TIME, - SYSTEM_MESSAGE + SYSTEM_MESSAGE, + EXECUTED_BY_FRONTEND ); // Ident of each item. Default is 0, which doesn't need to present in this Map. @@ -905,6 +907,10 @@ public class SummaryProfile { summaryProfile.addInfoString(SYSTEM_MESSAGE, msg); } + public void setExecutedByFrontend(boolean executedByFrontend) { + summaryProfile.addInfoString(EXECUTED_BY_FRONTEND, String.valueOf(executedByFrontend)); + } + public void write(DataOutput output) throws IOException { Text.writeString(output, GsonUtils.GSON.toJson(this)); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java b/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java index f169264a596..90e7404a038 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java +++ b/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java @@ -1783,6 +1783,11 @@ public class StmtExecutor { sendResultSet(resultSet.get(), ((Queriable) parsedStmt).getFieldInfos()); isHandleQueryInFe = true; LOG.info("Query {} finished", DebugUtil.printId(context.queryId)); + if (context.getSessionVariable().enableProfile()) { + if (profile != null) { + this.profile.getSummaryProfile().setExecutedByFrontend(true); + } + } return; } } diff --git a/regression-test/suites/query_profile/test_execute_by_frontend.groovy b/regression-test/suites/query_profile/test_execute_by_frontend.groovy new file mode 100644 index 00000000000..40435e02d99 --- /dev/null +++ b/regression-test/suites/query_profile/test_execute_by_frontend.groovy @@ -0,0 +1,90 @@ +// 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. + +import groovy.json.JsonOutput +import groovy.json.JsonSlurper +import groovy.json.StringEscapeUtils + +def getProfileList = { + def dst = 'http://' + context.config.feHttpAddress + def conn = new URL(dst + "/rest/v1/query_profile").openConnection() + conn.setRequestMethod("GET") + def encoding = Base64.getEncoder().encodeToString((context.config.feHttpUser + ":" + + (context.config.feHttpPassword == null ? "" : context.config.feHttpPassword)).getBytes("UTF-8")) + conn.setRequestProperty("Authorization", "Basic ${encoding}") + return conn.getInputStream().getText() +} + +def getProfile = { id -> + def dst = 'http://' + context.config.feHttpAddress + def conn = new URL(dst + "/api/profile/text/?query_id=$id").openConnection() + conn.setRequestMethod("GET") + def encoding = Base64.getEncoder().encodeToString((context.config.feHttpUser + ":" + + (context.config.feHttpPassword == null ? "" : context.config.feHttpPassword)).getBytes("UTF-8")) + conn.setRequestProperty("Authorization", "Basic ${encoding}") + // set conn parameters + + return conn.getInputStream().getText() + } + +suite('test_execute_by_frontend') { + sql """ + CREATE TABLE if not exists `test_execute_by_frontend` ( + `id` INT, + `name` varchar(32) + )ENGINE=OLAP + UNIQUE KEY(`id`) + DISTRIBUTED BY HASH(`id`) BUCKETS 1 + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1" + ); + """ + + sql "set enable_profile=true" + def simpleSql1 = "select * from test_execute_by_frontend" + sql "${simpleSql1}" + simpleSql2 = """select cast("1" as Int)""" + sql "${simpleSql2}" + def isRecorded = false + def wholeString = getProfileList() + List profileData = new JsonSlurper().parseText(wholeString).data.rows + String queryId1 = ""; + String queryId2 = ""; + + for (final def profileItem in profileData) { + if (profileItem["Sql Statement"].toString() == simpleSql1) { + isRecorded = true + queryId1 = profileItem["Profile ID"].toString() + assertEquals("internal", profileItem["Default Catalog"].toString()) + } + if (profileItem["Sql Statement"].toString() == simpleSql2) { + queryId2 = profileItem["Profile ID"].toString() + } + } + + assertTrue(isRecorded) + + String profileContent1 = getProfile(queryId1) + def executionProfileIdx1 = profileContent1.indexOf("Executed By Frontend: true") + assertTrue(executionProfileIdx1 > 0) + String profileContent2 = getProfile(queryId2) + def executionProfileIdx2 = profileContent2.indexOf("Executed By Frontend: true") + assertTrue(executionProfileIdx2 > 0) + + sql """ SET enable_profile = false """ + sql """ DROP TABLE IF EXISTS test_execute_by_frontend """ +} \ No newline at end of file --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org