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]