You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by mo...@apache.org on 2023/04/03 12:25:03 UTC

[doris] branch branch-1.1-lts updated: [Cherry-Pick][Enhancement](grouping) Add a switch for users to force using alias name in group by and having clause (#18327)

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

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


The following commit(s) were added to refs/heads/branch-1.1-lts by this push:
     new b72892db93 [Cherry-Pick][Enhancement](grouping) Add a switch for users to force using alias name in group by and having clause (#18327)
b72892db93 is described below

commit b72892db93a4ce228ea701f473038f72d2473156
Author: yongkang.zhong <zh...@qq.com>
AuthorDate: Mon Apr 3 20:24:55 2023 +0800

    [Cherry-Pick][Enhancement](grouping) Add a switch for users to force using alias name in group by and having clause (#18327)
    
    cherry-pick from #15748
---
 .../apache/doris/analysis/ExprSubstitutionMap.java | 10 +++++
 .../java/org/apache/doris/analysis/SelectStmt.java | 45 ++++++++++++++++------
 .../java/org/apache/doris/qe/SessionVariable.java  | 10 +++++
 3 files changed, 54 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 9726543f36..f51e3f81f0 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
@@ -99,6 +99,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 9a83d301f2..6968842cd1 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
@@ -997,15 +997,30 @@ public class SelectStmt extends QueryStmt {
              * TODO: the a.key should be replaced by a.k1 instead of unknown column 'key' in 'a'
              */
             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
+                boolean aliasFirst = false;
+                if (analyzer.getContext() != null) {
+                    aliasFirst = analyzer.getContext().getSessionVariable().isGroupByAndHavingUseAliasFirst();
+                }
+                if (!aliasFirst) {
+                    ExprSubstitutionMap excludeAliasSMap = aliasSMap.clone();
+                    List<Expr> havingSlots = Lists.newArrayList();
+                    havingClause.collect(SlotRef.class, havingSlots);
+                    for (Expr expr : havingSlots) {
+                        if (excludeAliasSMap.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
+                            excludeAliasSMap.removeByLhsExpr(expr);
+                        } catch (AnalysisException ex) {
+                            // according to case3, column name do not exist, keep alias name inside alias map
+                        }
+                    }
+                    havingClauseAfterAnaylzed = havingClause.substitute(excludeAliasSMap, analyzer, false);
+                } else {
+                    // If user set force using alias, then having clauses prefer using alias rather than column name
                     havingClauseAfterAnaylzed = havingClause.substitute(aliasSMap, analyzer, false);
                 }
             } else {
@@ -1125,7 +1140,11 @@ public class SelectStmt extends QueryStmt {
                 }
                 groupingInfo.buildRepeat(groupingExprs, groupByClause.getGroupingSetList());
             }
-            substituteOrdinalsAliases(groupingExprs, "GROUP BY", analyzer, false);
+            boolean aliasFirst = false;
+            if (analyzer.getContext() != null) {
+                aliasFirst = analyzer.getContext().getSessionVariable().isGroupByAndHavingUseAliasFirst();
+            }
+            substituteOrdinalsAliases(groupingExprs, "GROUP BY", analyzer, aliasFirst);
 
             if (!groupByClause.isGroupByExtension() && !groupingExprs.isEmpty()) {
                 ArrayList<Expr> tempExprs = new ArrayList<>(groupingExprs);
@@ -1911,7 +1930,11 @@ public class SelectStmt extends QueryStmt {
         }
         // substitute group by
         if (groupByClause != null) {
-            substituteOrdinalsAliases(groupByClause.getGroupingExprs(), "GROUP BY", analyzer, false);
+            boolean aliasFirst = false;
+            if (analyzer.getContext() != null) {
+                aliasFirst = analyzer.getContext().getSessionVariable().isGroupByAndHavingUseAliasFirst();
+            }
+            substituteOrdinalsAliases(groupByClause.getGroupingExprs(), "GROUP BY", analyzer, aliasFirst);
         }
         // substitute having
         if (havingClause != null) {
diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java b/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java
index 6af37a639b..9c4da3c159 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java
@@ -191,6 +191,8 @@ public class SessionVariable implements Serializable, Writable {
 
     public static final String NUM_FREE_BLOCK_IN_SCAN = "num_free_block_in_scan";
 
+    public static final String GROUP_BY_AND_HAVING_USE_ALIAS_FIRST = "group_by_and_having_use_alias_first";
+
     // session origin value
     public Map<Field, String> sessionOriginValue = new HashMap<Field, String>();
     // check stmt is or not [select /*+ SET_VAR(...)*/ ...]
@@ -468,6 +470,10 @@ public class SessionVariable implements Serializable, Writable {
     @VariableMgr.VarAttr(name = NUM_FREE_BLOCK_IN_SCAN)
     public int numFreeBlockInScan = 12;
 
+    // Default value is false, which means the group by and having clause
+    // should first use column name not alias. According to mysql.
+    @VariableMgr.VarAttr(name = GROUP_BY_AND_HAVING_USE_ALIAS_FIRST)
+    public boolean groupByAndHavingUseAliasFirst = false;
 
     public String getBlockEncryptionMode() {
         return blockEncryptionMode;
@@ -934,6 +940,10 @@ public class SessionVariable implements Serializable, Writable {
         this.trimTailingSpacesForExternalTableQuery = trimTailingSpacesForExternalTableQuery;
     }
 
+    public boolean isGroupByAndHavingUseAliasFirst() {
+        return groupByAndHavingUseAliasFirst;
+    }
+
     // Serialize to thrift object
     // used for rest api
     public TQueryOptions toThrift() {


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