You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by kx...@apache.org on 2023/08/21 14:10:38 UTC
[doris] 05/05: [Fix](planner) fix incorrect nullable in ctas. (#22770)
This is an automated email from the ASF dual-hosted git repository.
kxiao pushed a commit to branch branch-2.0
in repository https://gitbox.apache.org/repos/asf/doris.git
commit 56199ebcca4c1490e2679f1f14f4a1821f4e172a
Author: mch_ucchi <41...@users.noreply.github.com>
AuthorDate: Mon Aug 21 11:46:27 2023 +0800
[Fix](planner) fix incorrect nullable in ctas. (#22770)
ctas with outer join like
```sql
create table a (
id int not null,
name varchar(20) not null
)
distributed by hash(id) buckets 4
properties (
"replication_num"="1"
);
create table b (
id int not null,
age int not null
)
distributed by hash(id) buckets 4
properties (
"replication_num"="1"
);
insert into a values(1, 'ww'), (2, 'zs');
insert into b values(1, 22);
create table c properties("replication_num"="1") as select a.id, a.name, b.age from a left join b on a.id = b.id;
```
the column 'age' in c is not null, but nullable is expected, we fix it by use the nullable mode of the outputs of root plan fragment.
---
.../doris/analysis/CreateTableAsSelectStmt.java | 16 +++++++++++
.../apache/doris/planner/SingleNodePlanner.java | 2 +-
regression-test/suites/ddl_p0/test_ctas.groovy | 33 ++++++++++++++++++++++
.../suites/delete_p0/test_delete.groovy | 2 +-
4 files changed, 51 insertions(+), 2 deletions(-)
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateTableAsSelectStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateTableAsSelectStmt.java
index 2d6ee678db..942c3cce70 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateTableAsSelectStmt.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateTableAsSelectStmt.java
@@ -20,7 +20,11 @@ package org.apache.doris.analysis;
import org.apache.doris.common.ErrorCode;
import org.apache.doris.common.ErrorReport;
import org.apache.doris.common.UserException;
+import org.apache.doris.planner.OriginalPlanner;
+import org.apache.doris.planner.PlanFragment;
+import org.apache.doris.qe.ConnectContext;
+import com.google.common.base.Preconditions;
import lombok.Getter;
import java.util.ArrayList;
@@ -67,6 +71,18 @@ public class CreateTableAsSelectStmt extends DdlStmt {
QueryStmt tmpStmt = queryStmt.clone();
tmpStmt.analyze(dummyRootAnalyzer);
this.queryStmt = tmpStmt;
+ // to adjust the nullable of the result expression, we have to create plan fragment from the query stmt.
+ OriginalPlanner planner = new OriginalPlanner(dummyRootAnalyzer);
+ planner.createPlanFragments(queryStmt, dummyRootAnalyzer, ConnectContext.get().getSessionVariable().toThrift());
+ PlanFragment root = planner.getFragments().get(0);
+ List<Expr> outputs = root.getOutputExprs();
+ Preconditions.checkArgument(outputs.size() == queryStmt.getResultExprs().size());
+ for (int i = 0; i < outputs.size(); ++i) {
+ if (queryStmt.getResultExprs().get(i).getSrcSlotRef() != null) {
+ queryStmt.getResultExprs().get(i).getSrcSlotRef().getColumn()
+ .setIsAllowNull(outputs.get(i).isNullable());
+ }
+ }
ArrayList<Expr> resultExprs = getQueryStmt().getResultExprs();
if (columnNames != null && columnNames.size() != resultExprs.size()) {
ErrorReport.reportAnalysisException(ErrorCode.ERR_COL_NUMBER_NOT_MATCH);
diff --git a/fe/fe-core/src/main/java/org/apache/doris/planner/SingleNodePlanner.java b/fe/fe-core/src/main/java/org/apache/doris/planner/SingleNodePlanner.java
index e3fa6978b5..faeb6183c0 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/SingleNodePlanner.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/planner/SingleNodePlanner.java
@@ -1055,7 +1055,7 @@ public class SingleNodePlanner {
// reset assigned conjuncts of analyzer in every compare
analyzer.setAssignedConjuncts(root.getAssignedConjuncts());
PlanNode candidate = createJoinNode(analyzer, root, rootPlanNodeOfCandidate, tblRefOfCandidate);
- // (ML): 这里还需要吗?应该不会返回null吧
+ // it may not return null, but protect.
if (candidate == null) {
continue;
}
diff --git a/regression-test/suites/ddl_p0/test_ctas.groovy b/regression-test/suites/ddl_p0/test_ctas.groovy
index 35bd4f2726..7c093aa479 100644
--- a/regression-test/suites/ddl_p0/test_ctas.groovy
+++ b/regression-test/suites/ddl_p0/test_ctas.groovy
@@ -205,6 +205,39 @@ suite("test_ctas") {
DROP TABLE IF EXISTS ctas_113815
"""
}
+
+ try {
+ sql '''create table a (
+ id int not null,
+ name varchar(20) not null
+ )
+ distributed by hash(id) buckets 4
+ properties (
+ "replication_num"="1"
+ );
+ '''
+
+ sql '''create table b (
+ id int not null,
+ age int not null
+ )
+ distributed by hash(id) buckets 4
+ properties (
+ "replication_num"="1"
+ );
+ '''
+
+ sql 'insert into a values(1, \'ww\'), (2, \'zs\');'
+ sql 'insert into b values(1, 22);'
+ sql 'create table c properties("replication_num"="1") as select a.id, a.name, b.age from a left join b on a.id = b.id;'
+
+ String desc = sql 'desc c'
+ assertTrue(desc.contains('Yes'))
+ } finally {
+ sql 'drop table a'
+ sql 'drop table b'
+ sql 'drop table c'
+ }
}
diff --git a/regression-test/suites/delete_p0/test_delete.groovy b/regression-test/suites/delete_p0/test_delete.groovy
index c19884b411..bcd648c2fd 100644
--- a/regression-test/suites/delete_p0/test_delete.groovy
+++ b/regression-test/suites/delete_p0/test_delete.groovy
@@ -233,7 +233,7 @@ suite("test_delete") {
PROPERTIES (
"replication_num" = "1",
"enable_unique_key_merge_on_write" = "true"
- );
+ );
'''
sql 'insert into test1 values("a", "a"), ("bb", "bb"), ("ccc", "ccc")'
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org