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 <[email protected]> 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: [email protected] For additional commands, e-mail: [email protected]
