This is an automated email from the ASF dual-hosted git repository. starocean999 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 bedec814816 [fix](nereids)TableQueryPlanAction can't work when having empty relation (#49178) bedec814816 is described below commit bedec814816b870f7121df8ef532875c0420a0e3 Author: starocean999 <li...@selectdb.com> AuthorDate: Mon Mar 24 09:12:57 2025 +0800 [fix](nereids)TableQueryPlanAction can't work when having empty relation (#49178) the bug is introduced by https://github.com/apache/doris/pull/39627 --- .../doris/httpv2/rest/TableQueryPlanAction.java | 8 ++++-- .../doris/http/TableQueryPlanActionTest.java | 33 ++++++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/TableQueryPlanAction.java b/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/TableQueryPlanAction.java index 8e03fef07f5..4dc221d2945 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/TableQueryPlanAction.java +++ b/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/TableQueryPlanAction.java @@ -36,6 +36,7 @@ import org.apache.doris.nereids.parser.NereidsParser; import org.apache.doris.nereids.properties.PhysicalProperties; import org.apache.doris.nereids.trees.plans.commands.Command; import org.apache.doris.nereids.trees.plans.commands.ExplainCommand; +import org.apache.doris.nereids.trees.plans.logical.LogicalEmptyRelation; import org.apache.doris.nereids.trees.plans.logical.LogicalFilter; import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan; import org.apache.doris.nereids.trees.plans.logical.LogicalPlan; @@ -239,7 +240,7 @@ public class TableQueryPlanAction extends RestBaseController { PhysicalProperties.GATHER, ExplainCommand.ExplainLevel.REWRITTEN_PLAN); if (!rewrittenPlan.allMatch(planTreeNode -> planTreeNode instanceof LogicalOlapScan || planTreeNode instanceof LogicalFilter || planTreeNode instanceof LogicalProject - || planTreeNode instanceof LogicalResultSink)) { + || planTreeNode instanceof LogicalResultSink || planTreeNode instanceof LogicalEmptyRelation)) { throw new DorisHttpException(HttpResponseStatus.BAD_REQUEST, "only support single table filter-prune-scan, but found [ " + sql + "]"); } @@ -254,11 +255,12 @@ public class TableQueryPlanAction extends RestBaseController { // acquire ScanNode to obtain pruned tablet // in this way, just retrieve only one scannode List<ScanNode> scanNodes = planner.getScanNodes(); - if (scanNodes.size() != 1) { + if (scanNodes.size() > 1) { throw new DorisHttpException(HttpResponseStatus.INTERNAL_SERVER_ERROR, "Planner should plan just only one ScanNode but found [ " + scanNodes.size() + "]"); } - List<TScanRangeLocations> scanRangeLocations = scanNodes.get(0).getScanRangeLocations(0); + List<TScanRangeLocations> scanRangeLocations = scanNodes.size() == 1 + ? scanNodes.get(0).getScanRangeLocations(0) : new ArrayList<>(); // acquire the PlanFragment which the executable template List<PlanFragment> fragments = planner.getFragments(); if (fragments.size() != 1) { diff --git a/fe/fe-core/src/test/java/org/apache/doris/http/TableQueryPlanActionTest.java b/fe/fe-core/src/test/java/org/apache/doris/http/TableQueryPlanActionTest.java index 23549e0c98c..6aca7291b4b 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/http/TableQueryPlanActionTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/http/TableQueryPlanActionTest.java @@ -79,6 +79,39 @@ public class TableQueryPlanActionTest extends DorisHttpTestCase { System.out.println(tQueryPlanInfo); } + @Test + public void testQueryPlanActionEmptyRelation() throws IOException, TException { + RequestBody body = RequestBody.create( + "{ \"sql\" : \" select k1,k2 from " + DB_NAME + "." + TABLE_NAME + " where false \" }", JSON); + Request request = new Request.Builder() + .post(body) + .addHeader("Authorization", rootAuth) + .url(URI + PATH_URI) + .build(); + Response response = networkClient.newCall(request).execute(); + Assert.assertNotNull(response.body()); + String respStr = response.body().string(); + JSONObject jsonObject = (JSONObject) JSONValue.parse(respStr); + Assert.assertEquals(200, (long) ((JSONObject) jsonObject.get("data")).get("status")); + + JSONObject partitionsObject = (JSONObject) ((JSONObject) jsonObject.get("data")).get("partitions"); + Assert.assertNotNull(partitionsObject); + for (Object tabletKey : partitionsObject.keySet()) { + JSONObject tabletObject = (JSONObject) partitionsObject.get(tabletKey); + Assert.assertNotNull(tabletObject.get("routings")); + Assert.assertEquals(3, ((JSONArray) tabletObject.get("routings")).size()); + Assert.assertEquals(testStartVersion, (long) tabletObject.get("version")); + } + String queryPlan = (String) ((JSONObject) jsonObject.get("data")).get("opaqued_query_plan"); + Assert.assertNotNull(queryPlan); + byte[] binaryPlanInfo = Base64.getDecoder().decode(queryPlan); + TDeserializer deserializer = new TDeserializer(); + TQueryPlanInfo tQueryPlanInfo = new TQueryPlanInfo(); + deserializer.deserialize(tQueryPlanInfo, binaryPlanInfo); + expectThrowsNoException(() -> deserializer.deserialize(tQueryPlanInfo, binaryPlanInfo)); + System.out.println(tQueryPlanInfo); + } + @Test public void testNoSqlFailure() throws IOException { RequestBody body = RequestBody.create(JSON, "{}"); --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org