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