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

lingmiao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-doris.git


The following commit(s) were added to refs/heads/master by this push:
     new a7e1c08  Report error when subquery in case-when returns empty set 
(#3558)
a7e1c08 is described below

commit a7e1c08624bdc13069df8d8c0e4f6572dddcab2d
Author: yangzhg <[email protected]>
AuthorDate: Fri May 15 12:32:05 2020 +0800

    Report error when subquery in case-when returns empty set (#3558)
    
    The doris rewrite the subquery in case-when to inline view.
    So it the result is different between subquery in case-when and inline view.
    We could not support the empty set of subquery in case-when.
    This commit forbidden this case.
---
 .../java/org/apache/doris/analysis/CaseExpr.java   | 17 ++++++++++++
 .../java/org/apache/doris/analysis/SelectStmt.java | 32 ++++++----------------
 .../apache/doris/planner/AssertNumRowsNode.java    |  6 ++--
 3 files changed, 28 insertions(+), 27 deletions(-)

diff --git a/fe/src/main/java/org/apache/doris/analysis/CaseExpr.java 
b/fe/src/main/java/org/apache/doris/analysis/CaseExpr.java
index ffe0d88..9261266 100644
--- a/fe/src/main/java/org/apache/doris/analysis/CaseExpr.java
+++ b/fe/src/main/java/org/apache/doris/analysis/CaseExpr.java
@@ -24,6 +24,7 @@ import org.apache.doris.thrift.TExprNode;
 import org.apache.doris.thrift.TExprNodeType;
 
 import com.google.common.base.Preconditions;
+import com.google.common.base.Predicates;
 import com.google.common.collect.Lists;
 
 import java.util.ArrayList;
@@ -156,6 +157,9 @@ public class CaseExpr extends Expr {
             loopStart = 1;
             caseExpr = children.get(0);
             caseExpr.analyze(analyzer);
+            if (caseExpr instanceof Subquery && 
!caseExpr.getType().isScalarType()) {
+                throw new AnalysisException("Subquery in case-when must return 
scala type");
+            }
             whenType = caseExpr.getType();
             lastCompatibleWhenExpr = children.get(0);
         } else {
@@ -183,14 +187,27 @@ public class CaseExpr extends Expr {
                     castChild(Type.BOOLEAN, i);
                 }
             }
+            if (whenExpr instanceof Subquery && 
!whenExpr.getType().isScalarType()) {
+                throw new AnalysisException("Subquery in case-when must return 
scala type");
+            }
+            if (whenExpr.contains(Predicates.instanceOf(Subquery.class))
+                    && !((hasCaseExpr() && whenExpr instanceof Subquery || 
whenExpr instanceof BinaryPredicate))) {
+                throw new AnalysisException("Only support subquery in binary 
predicate in case statement.");
+            }
             // Determine maximum compatible type of the then exprs seen so far.
             // We will add casts to them at the very end.
             Expr thenExpr = children.get(i + 1);
+            if (thenExpr instanceof Subquery && 
!thenExpr.getType().isScalarType()) {
+                throw new AnalysisException("Subquery in case-when must return 
scala type");
+            }
             returnType = analyzer.getCompatibleType(returnType, 
lastCompatibleThenExpr, thenExpr);
             lastCompatibleThenExpr = thenExpr;
         }
         if (hasElseExpr) {
             Expr elseExpr = children.get(children.size() - 1);
+            if (elseExpr instanceof Subquery && 
!elseExpr.getType().isScalarType()) {
+                throw new AnalysisException("Subquery in case-when must return 
scala type");
+            }
             returnType = analyzer.getCompatibleType(returnType, 
lastCompatibleThenExpr, elseExpr);
         }
 
diff --git a/fe/src/main/java/org/apache/doris/analysis/SelectStmt.java 
b/fe/src/main/java/org/apache/doris/analysis/SelectStmt.java
index d70333c..f705651 100644
--- a/fe/src/main/java/org/apache/doris/analysis/SelectStmt.java
+++ b/fe/src/main/java/org/apache/doris/analysis/SelectStmt.java
@@ -1382,29 +1382,9 @@ public class SelectStmt extends QueryStmt {
 
     private void rewriteSelectList(ExprRewriter rewriter) throws 
AnalysisException {
         for (SelectListItem item : selectList.getItems()) {
-            if (!(item.getExpr() instanceof CaseExpr)) {
-                continue;
-            }
-            if 
(!item.getExpr().contains(Predicates.instanceOf(Subquery.class))) {
-                continue;
-            }
-            CaseExpr caseExpr = (CaseExpr) item.getExpr();
-
-            int childIdx = 0;
-            if (caseExpr.hasCaseExpr()
-                    && 
caseExpr.getChild(childIdx++).contains(Predicates.instanceOf(Subquery.class))) {
-                throw new AnalysisException("Only support subquery in binary 
predicate in case statement.");
-            }
-            while (childIdx + 2 <= caseExpr.getChildren().size()) {
-                Expr child = caseExpr.getChild(childIdx++);
-                // when
-                if (!(child instanceof BinaryPredicate) && 
child.contains(Predicates.instanceOf(Subquery.class))) {
-                    throw new AnalysisException("Only support subquery in 
binary predicate in case statement.");
-                }
-                // then
-                childIdx++;
+            if (item.getExpr() instanceof CaseExpr && 
item.getExpr().contains(Predicates.instanceOf(Subquery.class))) {
+                rewriteSubquery(item.getExpr(), analyzer);
             }
-            rewriteSubquery(item.getExpr(), analyzer);
         }
         selectList.rewriteExprs(rewriter, analyzer);
     }
@@ -1447,13 +1427,17 @@ public class SelectStmt extends QueryStmt {
             throws AnalysisException {
         if (expr instanceof Subquery) {
             if (!(((Subquery) expr).getStatement() instanceof SelectStmt)) {
-                throw new AnalysisException("Only support select subquery in 
case statement.");
+                throw new AnalysisException("Only support select subquery in 
case-when clause.");
+            }
+            if (expr.isCorrelatedPredicate(getTableRefIds())) {
+                throw new AnalysisException("The correlated subquery in 
case-when clause is not supported");
             }
             SelectStmt subquery = (SelectStmt) ((Subquery) 
expr).getStatement();
             if (subquery.resultExprs.size() != 1 || 
!subquery.returnsSingleRow()) {
-                throw new AnalysisException("Only support select subquery 
produce one column in case statement.");
+                throw new AnalysisException("Subquery in case-when must return 
scala type");
             }
             subquery.reset();
+            subquery.setAssertNumRowsElement(1, 
AssertNumRowsElement.Assertion.EQ);
             String alias = getTableAliasGenerator().getNextAlias();
             String colAlias = getColumnAliasGenerator().getNextAlias();
             InlineViewRef inlineViewRef = new InlineViewRef(alias, subquery, 
Arrays.asList(colAlias));
diff --git a/fe/src/main/java/org/apache/doris/planner/AssertNumRowsNode.java 
b/fe/src/main/java/org/apache/doris/planner/AssertNumRowsNode.java
index e0a6c5a..97c1bc1 100644
--- a/fe/src/main/java/org/apache/doris/planner/AssertNumRowsNode.java
+++ b/fe/src/main/java/org/apache/doris/planner/AssertNumRowsNode.java
@@ -41,9 +41,9 @@ public class AssertNumRowsNode extends PlanNode {
         this.subqueryString = assertNumRowsElement.getSubqueryString();
         this.assertion = assertNumRowsElement.getAssertion();
         this.children.add(input);
-        this.tupleIds = input.getTupleIds();
-        this.tblRefIds = input.getTblRefIds();
-        this.nullableTupleIds = input.getNullableTupleIds();
+        this.tupleIds.addAll(input.getTupleIds());
+        this.tblRefIds.addAll(input.getTblRefIds());
+        this.nullableTupleIds.addAll(input.getNullableTupleIds());
     }
 
     @Override


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

Reply via email to