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

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


The following commit(s) were added to refs/heads/branch-2.0 by this push:
     new be5fc631051 [feature](Nereids) add expr depth limit and expr children 
limit in Nereids (#23569) (#33905)
be5fc631051 is described below

commit be5fc631051ded8b19008a8fd1d52bb6834cb750
Author: 谢健 <[email protected]>
AuthorDate: Sat Apr 20 00:14:49 2024 +0800

    [feature](Nereids) add expr depth limit and expr children limit in Nereids 
(#23569) (#33905)
    
    #### `expr_depth_limit`
    
    Default:3000
    
    IsMutable:true
    
    Limit on the depth of an expr tree.  Exceed this limit may cause long 
analysis time while holding db read lock.  Do not set this if you know what you 
are doing
    
    #### `expr_children_limit`
    
    Default:10000
    
    IsMutable:true
    
    Limit on the number of expr children of an expr tree.  Exceed this limit 
may cause long analysis time while holding database read lock.
---
 .../nereids/trees/expressions/Expression.java      | 38 ++++++++++++++++++++++
 .../doris/nereids/parser/NereidsParserTest.java    | 11 +++++++
 2 files changed, 49 insertions(+)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Expression.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Expression.java
index 8eb89da772d..9f36ddf3088 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Expression.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Expression.java
@@ -17,6 +17,7 @@
 
 package org.apache.doris.nereids.trees.expressions;
 
+import org.apache.doris.common.Config;
 import org.apache.doris.nereids.analyzer.Unbound;
 import org.apache.doris.nereids.analyzer.UnboundVariable;
 import org.apache.doris.nereids.exceptions.AnalysisException;
@@ -42,6 +43,7 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
 import org.apache.commons.lang3.StringUtils;
 
+import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
@@ -53,12 +55,40 @@ import java.util.stream.Collectors;
  */
 public abstract class Expression extends AbstractTreeNode<Expression> 
implements ExpressionTrait {
 
+    private final int depth;
+    private final int width;
+
     protected Expression(Expression... children) {
         super(children);
+        depth = Arrays.stream(children)
+                .mapToInt(e -> e.depth)
+                .max().orElse(0) + 1;
+        width = Arrays.stream(children)
+                .mapToInt(e -> e.width)
+                .sum() + (children.length == 0 ? 1 : 0);
+        checkLimit();
     }
 
     protected Expression(List<Expression> children) {
         super(Optional.empty(), children);
+        depth = children.stream()
+                .mapToInt(e -> e.depth)
+                .max().orElse(0) + 1;
+        width = children.stream()
+                .mapToInt(e -> e.width)
+                .sum() + (children.isEmpty() ? 1 : 0);
+        checkLimit();
+    }
+
+    private void checkLimit() {
+        if (depth > Config.expr_depth_limit) {
+            throw new AnalysisException(String.format("Exceeded the maximum 
depth of an "
+                    + "expression tree (%s).", Config.expr_depth_limit));
+        }
+        if (width > Config.expr_children_limit) {
+            throw new AnalysisException(String.format("Exceeded the maximum 
children of an "
+                    + "expression tree (%s).", Config.expr_children_limit));
+        }
     }
 
     public Alias alias(String alias) {
@@ -126,6 +156,14 @@ public abstract class Expression extends 
AbstractTreeNode<Expression> implements
         return children.get(index);
     }
 
+    public int getWidth() {
+        return width;
+    }
+
+    public int getDepth() {
+        return depth;
+    }
+
     @Override
     public Expression withChildren(List<Expression> children) {
         throw new RuntimeException();
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/parser/NereidsParserTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/parser/NereidsParserTest.java
index 31cf7710021..1c11e74fcc8 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/parser/NereidsParserTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/parser/NereidsParserTest.java
@@ -377,4 +377,15 @@ public class NereidsParserTest extends ParserTestBase {
             Assertions.assertEquals(6, decimalV2Type.getScale());
         }
     }
+
+    @Test
+    void testParseExprDepthWidth() {
+        String sql = "SELECT 1+2 = 3 from t";
+        NereidsParser nereidsParser = new NereidsParser();
+        LogicalPlan logicalPlan = (LogicalPlan) 
nereidsParser.parseSingle(sql).child(0);
+        System.out.println(logicalPlan);
+        // alias (1 + 2 = 3)
+        Assertions.assertEquals(4, 
logicalPlan.getExpressions().get(0).getDepth());
+        Assertions.assertEquals(3, 
logicalPlan.getExpressions().get(0).getWidth());
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to