From ff97a44ad7ef736cccc15c31a16b1c0f71eacab7 Mon Sep 17 00:00:00 2001 From: caiconghui1 Date: Fri, 3 Dec 2021 20:24:59 +0800 Subject: [PATCH 1/3] [fix](select outer join) Make selected slotRef nullable when slotRef is from nullable tuple in outer join sql block --- be/src/exprs/aggregate_functions.cpp | 1 - .../src/main/java/org/apache/doris/analysis/Analyzer.java | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/be/src/exprs/aggregate_functions.cpp b/be/src/exprs/aggregate_functions.cpp index 231a0fdc669364..035f57ed93637a 100644 --- a/be/src/exprs/aggregate_functions.cpp +++ b/be/src/exprs/aggregate_functions.cpp @@ -838,7 +838,6 @@ void AggregateFunctions::string_concat_update(FunctionContext* ctx, const String if (result->is_null || !result->ptr) { // Header of the intermediate state holds the length of the first separator. const auto header_len = sizeof(StringConcatHeader); - DCHECK(header_len == sizeof(sep->len)); *result = StringVal(ctx->allocate(header_len), header_len); *reinterpret_cast(result->ptr) = sep->len; } diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/Analyzer.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/Analyzer.java index 33c259b7b2dc2f..c13c2bdc894af3 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/Analyzer.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/Analyzer.java @@ -660,7 +660,7 @@ public SlotDescriptor registerColumnRef(TableName tblName, String colName) throw } result = globalState.descTbl.addSlotDescriptor(d); result.setColumn(col); - if (true == col.isAllowNull()) { + if (col.isAllowNull() || globalState.outerJoinedTupleIds.containsKey(d.getId())) { result.setIsNullable(true); } else { result.setIsNullable(false); From ea293807ff6ded71c177fc02e0604f099002ab97 Mon Sep 17 00:00:00 2001 From: caiconghui1 Date: Sat, 4 Dec 2021 12:41:55 +0800 Subject: [PATCH 2/3] add fe ut --- .../org/apache/doris/analysis/SelectStmtTest.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/fe/fe-core/src/test/java/org/apache/doris/analysis/SelectStmtTest.java b/fe/fe-core/src/test/java/org/apache/doris/analysis/SelectStmtTest.java index 103ab9895fbb1c..9dce62f175c859 100755 --- a/fe/fe-core/src/test/java/org/apache/doris/analysis/SelectStmtTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/SelectStmtTest.java @@ -111,7 +111,7 @@ public static void setUp() throws Exception { String tbl2 = "CREATE TABLE db1.table2 (\n" + " `siteid` int(11) NULL DEFAULT \"10\" COMMENT \"\",\n" + " `citycode` smallint(6) NULL COMMENT \"\",\n" + - " `username` varchar(32) NULL DEFAULT \"\" COMMENT \"\",\n" + + " `username` varchar(32) NOT NULL DEFAULT \"\" COMMENT \"\",\n" + " `pv` bigint(20) NULL DEFAULT \"0\" COMMENT \"\"\n" + ") ENGINE=OLAP\n" + "UNIQUE KEY(`siteid`, `citycode`, `username`)\n" + @@ -755,4 +755,13 @@ public void testWithUnionToSql() throws Exception { Assert.assertTrue(stmt2.toSql().contains("WITH v1 AS (SELECT `t1`.`k1` AS `k1` FROM " + "`default_cluster:db1`.`tbl1` t1),v2 AS (SELECT `t2`.`k1` AS `k1` FROM `default_cluster:db1`.`tbl1` t2)")); } + + @Test + public void testSelectOuterJoinSql() throws Exception { + ConnectContext ctx = UtFrameUtils.createDefaultCtx(); + String sql1 = "select l.citycode, group_concat(r.username) from db1.table1 l left join db1.table2 r on l.citycode=r.citycode group by l.citycode"; + SelectStmt stmt1 = (SelectStmt) UtFrameUtils.parseAndAnalyzeStmt(sql1, ctx); + Assert.assertTrue(stmt1.getAnalyzer().getSlotDesc(new SlotId(2)).getIsNullable()); + Assert.assertTrue(stmt1.getAnalyzer().getSlotDescriptor("r.username").getIsNullable()); + } } From 65ac396a5c086afe26ecb1683b5d99e12b118dc6 Mon Sep 17 00:00:00 2001 From: caiconghui1 Date: Mon, 6 Dec 2021 16:12:13 +0800 Subject: [PATCH 3/3] fix --- be/src/exprs/aggregate_functions.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/be/src/exprs/aggregate_functions.cpp b/be/src/exprs/aggregate_functions.cpp index 035f57ed93637a..231a0fdc669364 100644 --- a/be/src/exprs/aggregate_functions.cpp +++ b/be/src/exprs/aggregate_functions.cpp @@ -838,6 +838,7 @@ void AggregateFunctions::string_concat_update(FunctionContext* ctx, const String if (result->is_null || !result->ptr) { // Header of the intermediate state holds the length of the first separator. const auto header_len = sizeof(StringConcatHeader); + DCHECK(header_len == sizeof(sep->len)); *result = StringVal(ctx->allocate(header_len), header_len); *reinterpret_cast(result->ptr) = sep->len; }