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

morningman pushed a commit to branch branch-1.2-lts
in repository https://gitbox.apache.org/repos/asf/doris.git

commit 26c8b663ddb343a7a7e3064b55494a657268ec24
Author: camby <104178...@qq.com>
AuthorDate: Thu Jan 5 10:15:15 2023 +0800

    [fix](having-clause) having clause do not works correct with same alias 
name (#15143)
---
 .../apache/doris/analysis/ExprSubstitutionMap.java | 10 ++++++
 .../java/org/apache/doris/analysis/SelectStmt.java | 38 ++++++++++++++++------
 .../correctness_p0/test_group_having_alias.out     | 10 ++++++
 .../correctness_p0/test_group_having_alias.groovy  | 25 +++++++++++++-
 4 files changed, 72 insertions(+), 11 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/ExprSubstitutionMap.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/ExprSubstitutionMap.java
index b1806f3dbf..5f60d15e1d 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/ExprSubstitutionMap.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/ExprSubstitutionMap.java
@@ -103,6 +103,16 @@ public final class ExprSubstitutionMap {
         return null;
     }
 
+    public void removeByLhsExpr(Expr lhsExpr) {
+        for (int i = 0; i < lhs.size(); ++i) {
+            if (lhs.get(i).equals(lhsExpr)) {
+                lhs.remove(i);
+                rhs.remove(i);
+                break;
+            }
+        }
+    }
+
     public void removeByRhsExpr(Expr rhsExpr) {
         for (int i = 0; i < rhs.size(); ++i) {
             if (rhs.get(i).equals(rhsExpr)) {
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/SelectStmt.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/SelectStmt.java
index 0950b3d839..eac2cd4c26 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/SelectStmt.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/SelectStmt.java
@@ -995,18 +995,36 @@ public class SelectStmt extends QueryStmt {
              *                     (select min(k1) from table b where 
a.key=b.k2);
              * TODO: the a.key should be replaced by a.k1 instead of unknown 
column 'key' in 'a'
              */
+
+            // according to mysql
+            // having clause should use column name inside group by clause, 
prior to alias.
+            // case1: having clause use column name table.v1, because v1 
inside group by clause
+            //     select id, sum(v1) v1 from table group by id,v1 
having(v1>1);
+            // case2: having clause use alias name v2, because v2 is not 
inside group by clause
+            //     select id, sum(v1) v1, sum(v2) v2 from table group by id,v1 
having(v1>1 AND v2>1);
+            // case3: having clause use alias name v, because table do not 
have column name v
+            //     select id, floor(v1) v, sum(v2) v2 from table group by id,v 
having(v>1 AND v2>1);
             if (groupByClause != null) {
-                // according to mysql
-                // if there is a group by clause, the having clause should use 
column name not alias
-                // this is the same as group by clause
-                try {
-                    // use col name from tableRefs first
-                    havingClauseAfterAnaylzed = havingClause.clone();
-                    havingClauseAfterAnaylzed.analyze(analyzer);
-                } catch (AnalysisException ex) {
-                    // then consider alias name
-                    havingClauseAfterAnaylzed = 
havingClause.substitute(aliasSMap, analyzer, false);
+                ExprSubstitutionMap excludeGroupByaliasSMap = 
aliasSMap.clone();
+                // according to case2, maybe some having slots inside group by 
clause, some do not
+                List<Expr> groupBySlots = Lists.newArrayList();
+                for (Expr expr : groupByClause.getGroupingExprs()) {
+                    expr.collect(SlotRef.class, groupBySlots);
+                }
+                for (Expr expr : groupBySlots) {
+                    if (excludeGroupByaliasSMap.get(expr) == null) {
+                        continue;
+                    }
+                    try {
+                        // try to use column name firstly
+                        expr.clone().analyze(analyzer);
+                        // analyze success means column name exist, do not use 
alias name
+                        excludeGroupByaliasSMap.removeByLhsExpr(expr);
+                    } catch (AnalysisException ex) {
+                        // according to case3, column name do not exist, keep 
alias name inside alias map
+                    }
                 }
+                havingClauseAfterAnaylzed = 
havingClause.substitute(excludeGroupByaliasSMap, analyzer, false);
             } else {
                 // according to mysql
                 // if there is no group by clause, the having clause should 
use alias
diff --git a/regression-test/data/correctness_p0/test_group_having_alias.out 
b/regression-test/data/correctness_p0/test_group_having_alias.out
index fa1e177399..8d3629b5f5 100644
--- a/regression-test/data/correctness_p0/test_group_having_alias.out
+++ b/regression-test/data/correctness_p0/test_group_having_alias.out
@@ -10,3 +10,13 @@
 202245
 202245
 
+-- !case1 --
+2      2
+2      3
+
+-- !case2 --
+2      3       3
+
+-- !case3 --
+2      1       3
+
diff --git 
a/regression-test/suites/correctness_p0/test_group_having_alias.groovy 
b/regression-test/suites/correctness_p0/test_group_having_alias.groovy
index 1ff8dbbad8..45350026e2 100644
--- a/regression-test/suites/correctness_p0/test_group_having_alias.groovy
+++ b/regression-test/suites/correctness_p0/test_group_having_alias.groovy
@@ -74,4 +74,27 @@
     sql """
         DROP TABLE IF EXISTS `tb_holiday`;
     """
- } 
\ No newline at end of file
+
+    sql """ DROP TABLE IF EXISTS `test_having_alias_tb`; """
+    sql """
+         CREATE TABLE `test_having_alias_tb` (
+          `id` int(11) NULL,
+          `v1` bigint(20) NULL,
+          `v2` bigint(20) NULL
+        ) ENGINE=OLAP
+        DUPLICATE KEY(`id`)
+        COMMENT 'OLAP'
+        DISTRIBUTED BY HASH(`id`) BUCKETS 1
+        PROPERTIES (
+        "replication_allocation" = "tag.location.default: 1",
+        "in_memory" = "false",
+        "storage_format" = "V2",
+        "disable_auto_compaction" = "false"
+        );
+    """
+    sql """ INSERT INTO test_having_alias_tb values(1,1,1),(2,2,2),(2,3,3); """
+    qt_case1 """ SELECT id, sum(v1) v1 FROM test_having_alias_tb GROUP BY 
id,v1 having(v1>1) ORDER BY id,v1; """
+    qt_case2 """ SELECT id, sum(v1) v1, sum(v2) v2 FROM test_having_alias_tb 
GROUP BY id,v1 having(v1!=2 AND v2>1) ORDER BY id,v1; """
+    qt_case3 """ SELECT id, v1-2 as v, sum(v2) v2 FROM test_having_alias_tb 
GROUP BY id,v having(v>0 AND v2>1) ORDER BY id,v; """
+    sql """ DROP TABLE IF EXISTS `test_having_alias_tb`; """
+ } 


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to