This is an automated email from the ASF dual-hosted git repository.

morrysnow pushed a commit to branch branch-2.1
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-2.1 by this push:
     new 4deda2fce73 [improvement](nereids) Simplify ScanNode projection 
handling by removing redundant conditions (#40801) (#41315)
4deda2fce73 is described below

commit 4deda2fce738db0a6c0db0a0f9b430e61a267d41
Author: zy-kkk <zhongy...@gmail.com>
AuthorDate: Thu Sep 26 10:35:01 2024 +0800

    [improvement](nereids) Simplify ScanNode projection handling by removing 
redundant conditions (#40801) (#41315)
    
    pick from master #40801
    
    This PR simplifies the handling of `ScanNode` projection logic.
    Previously, the code included multiple conditional checks to determine
    whether a `projectionTuple` should be generated. These conditions have
    been removed, and now `projectionTuple `is always generated for
    `ScanNode`, ensuring a consistent projection setup. Additionally,
    redundant handling of `SlotId` and `SlotRef` has been eliminated, making
    the code cleaner and easier to maintain. The behavior for `OlapScanNode`
    remains unchanged.
---
 .../glue/translator/PhysicalPlanTranslator.java    | 49 +++++-----------------
 .../jdbc/test_doris_jdbc_catalog.out               |  8 ++++
 .../jdbc/test_doris_jdbc_catalog.groovy            |  4 ++
 3 files changed, 23 insertions(+), 38 deletions(-)

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 7cfeb3dbaff..a3d3a1885f3 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
@@ -1951,21 +1951,10 @@ public class PhysicalPlanTranslator extends 
DefaultPlanVisitor<PlanFragment, Pla
             // slotIdsByOrder is used to ensure the ScanNode's output order is 
same with current Project
             // if we change the output order in translate project, the upper 
node will receive wrong order
             // tuple, since they get the order from project.getOutput() not 
scan.getOutput()./
-            List<SlotId> slotIdsByOrder = Lists.newArrayList();
-            if (requiredByProjectSlotIdSet.size() != requiredSlotIdSet.size()
-                    || new HashSet<>(projectionExprs).size() != 
projectionExprs.size()
-                    || projectionExprs.stream().anyMatch(expr -> !(expr 
instanceof SlotRef))) {
-                projectionTuple = generateTupleDesc(slots,
-                        ((ScanNode) inputPlanNode).getTupleDesc().getTable(), 
context);
-                inputPlanNode.setProjectList(projectionExprs);
-                inputPlanNode.setOutputTupleDesc(projectionTuple);
-            } else {
-                for (int i = 0; i < slots.size(); ++i) {
-                    context.addExprIdSlotRefPair(slots.get(i).getExprId(),
-                            (SlotRef) projectionExprs.get(i));
-                    slotIdsByOrder.add(((SlotRef) 
projectionExprs.get(i)).getSlotId());
-                }
-            }
+            projectionTuple = generateTupleDesc(slots,
+                    ((ScanNode) inputPlanNode).getTupleDesc().getTable(), 
context);
+            inputPlanNode.setProjectList(projectionExprs);
+            inputPlanNode.setOutputTupleDesc(projectionTuple);
 
             // TODO: this is a temporary scheme to support two phase read when 
has project.
             //  we need to refactor all topn opt into rbo stage.
@@ -1975,20 +1964,16 @@ public class PhysicalPlanTranslator extends 
DefaultPlanVisitor<PlanFragment, Pla
                 SlotDescriptor lastSlot = 
olapScanSlots.get(olapScanSlots.size() - 1);
                 if (lastSlot.getColumn() != null
                         && 
lastSlot.getColumn().getName().equals(Column.ROWID_COL)) {
-                    if (projectionTuple != null) {
-                        injectRowIdColumnSlot(projectionTuple);
-                        SlotRef slotRef = new SlotRef(lastSlot);
-                        inputPlanNode.getProjectList().add(slotRef);
-                        requiredByProjectSlotIdSet.add(lastSlot.getId());
-                    } else {
-                        slotIdsByOrder.add(lastSlot.getId());
-                    }
+                    injectRowIdColumnSlot(projectionTuple);
+                    SlotRef slotRef = new SlotRef(lastSlot);
+                    inputPlanNode.getProjectList().add(slotRef);
+                    requiredByProjectSlotIdSet.add(lastSlot.getId());
                     requiredSlotIdSet.add(lastSlot.getId());
                 }
                 ((OlapScanNode) inputPlanNode).updateRequiredSlots(context, 
requiredByProjectSlotIdSet);
             }
             updateScanSlotsMaterialization((ScanNode) inputPlanNode, 
requiredSlotIdSet,
-                    requiredByProjectSlotIdSet, slotIdsByOrder, context);
+                    requiredByProjectSlotIdSet, context);
         } else {
             TupleDescriptor tupleDescriptor = generateTupleDesc(slots, null, 
context);
             inputPlanNode.setProjectList(projectionExprs);
@@ -2434,22 +2419,10 @@ public class PhysicalPlanTranslator extends 
DefaultPlanVisitor<PlanFragment, Pla
 
     private void updateScanSlotsMaterialization(ScanNode scanNode,
             Set<SlotId> requiredSlotIdSet, Set<SlotId> 
requiredByProjectSlotIdSet,
-            List<SlotId> slotIdsByOrder, PlanTranslatorContext context) {
+            PlanTranslatorContext context) {
         // TODO: use smallest slot if do not need any slot in upper node
         SlotDescriptor smallest = scanNode.getTupleDesc().getSlots().get(0);
-        if (CollectionUtils.isNotEmpty(slotIdsByOrder)) {
-            // if we eliminate project above scan, we should ensure the slot 
order of scan's output is same with
-            // the projection's output. So, we need to reorder the output slot 
in scan's tuple.
-            Map<SlotId, SlotDescriptor> idToSlotDescMap = 
scanNode.getTupleDesc().getSlots().stream()
-                    .filter(s -> requiredSlotIdSet.contains(s.getId()))
-                    .collect(Collectors.toMap(SlotDescriptor::getId, s -> s));
-            scanNode.getTupleDesc().getSlots().clear();
-            for (SlotId slotId : slotIdsByOrder) {
-                
scanNode.getTupleDesc().getSlots().add(idToSlotDescMap.get(slotId));
-            }
-        } else {
-            scanNode.getTupleDesc().getSlots().removeIf(s -> 
!requiredSlotIdSet.contains(s.getId()));
-        }
+        scanNode.getTupleDesc().getSlots().removeIf(s -> 
!requiredSlotIdSet.contains(s.getId()));
         if (scanNode.getTupleDesc().getSlots().isEmpty()) {
             scanNode.getTupleDesc().getSlots().add(smallest);
         }
diff --git 
a/regression-test/data/external_table_p0/jdbc/test_doris_jdbc_catalog.out 
b/regression-test/data/external_table_p0/jdbc/test_doris_jdbc_catalog.out
index 3fec3f8a574..9695f628fee 100644
--- a/regression-test/data/external_table_p0/jdbc/test_doris_jdbc_catalog.out
+++ b/regression-test/data/external_table_p0/jdbc/test_doris_jdbc_catalog.out
@@ -141,6 +141,14 @@ char_col   char(85)        Yes     true    \N      NONE
 varchar_col    char(85)        Yes     true    \N      NONE
 json_col       text    Yes     true    \N      NONE
 
+-- !sql --
+\N     \N
+a      1
+
+-- !sql --
+\N     \N
+1      a
+
 -- !sql --
 doris_jdbc_catalog
 
diff --git 
a/regression-test/suites/external_table_p0/jdbc/test_doris_jdbc_catalog.groovy 
b/regression-test/suites/external_table_p0/jdbc/test_doris_jdbc_catalog.groovy
index 2051a4ad54d..c4fce17c62c 100644
--- 
a/regression-test/suites/external_table_p0/jdbc/test_doris_jdbc_catalog.groovy
+++ 
b/regression-test/suites/external_table_p0/jdbc/test_doris_jdbc_catalog.groovy
@@ -231,6 +231,10 @@ suite("test_doris_jdbc_catalog", 
"p0,external,doris,external_docker,external_doc
     // test query tvf
     qt_sql """desc function query("catalog" = "doris_jdbc_catalog", "query" = 
"select * from regression_test_jdbc_catalog_p0.base");"""
 
+    order_qt_sql """ select varchar_col,tinyint_col from query("catalog" = 
"doris_jdbc_catalog", "query" = "select varchar_col,tinyint_col from 
regression_test_jdbc_catalog_p0.base");"""
+
+    order_qt_sql """ select tinyint_col,varchar_col from query("catalog" = 
"doris_jdbc_catalog", "query" = "select varchar_col,tinyint_col from 
regression_test_jdbc_catalog_p0.base");"""
+
     //clean
     qt_sql """select current_catalog()"""
     sql "switch internal"


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to