From 263631e9832cdd0558806f598335d393a82844b0 Mon Sep 17 00:00:00 2001 From: JingDas <114388747+JingDas@users.noreply.github.com> Date: Mon, 9 Oct 2023 17:14:01 +0800 Subject: [PATCH] [improvement](meta) Infer the column name when create view if the column is expression (#24990) ## Proposed changes Infer the column name when create view if the column is expression ## Further comments expr column name infer strategy as following: | expr | example | column name(before) | Inferred column name(if position is 2) | | ------------- | --------------------------------------- | ------------------------------ | -------------------------------------- | | function | dayofyear() | dayofyear() | __dayofyear_1 | | cast | cast(1 as bigint) | CAST(1 AS BIGINT) | __cast_1 | | anylyticExpr | min() | min() | __min_1 | | predicate | 1 in (1,2,3,4) | 1 IN (1, 2, 3, 4) | __in_predicate_1 | | literal | 1 or 'string_var_name' | 1 or 'string_var_name' | __literal_1 | | arithmeticExpr | & | ... & ... | __arithmetic_expr_1 | | identifier | a or b | a or b | a or b | | case | CASE WHEN remark = 's' THEN 1 ELSE 2 END | CASE WHEN remark = 's' THEN 1 ELSE 2 END | __case_1 | | window | min(timestamp) OVER (...) | min(timestamp) OVER(...) | __min_1 | SQL for example: ```sql CREATE VIEW v1 AS SELECT error_code, 1, 'string', now(), dayofyear(op_time), cast (source AS BIGINT), min(`timestamp`) OVER ( ORDER BY op_time DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING ), 1 > 2, 2 + 3, 1 IN (1, 2, 3, 4), remark LIKE '%like', CASE WHEN remark = 's' THEN 1 ELSE 2 END, TRUE | FALSE FROM db_test.table_test1 ``` the output column name is as following: ``` error_code __literal_1 __literal_2 __now_3 __dayofyear_4 __cast_expr_5 __min_6 __binary_predicate_7 __arithmetic_expr_8 __in_predicate_9 __like_predicate_10 __case_expr_11 __arithmetic_expr_12 ``` --- .../apache/doris/analysis/AnalyticExpr.java | 6 ++ .../apache/doris/analysis/ColumnRefExpr.java | 6 ++ .../java/org/apache/doris/analysis/Expr.java | 9 +++ .../doris/analysis/FunctionCallExpr.java | 6 ++ .../apache/doris/analysis/LiteralExpr.java | 5 ++ .../apache/doris/analysis/SelectListItem.java | 20 ++++++- .../org/apache/doris/analysis/SelectStmt.java | 9 ++- .../org/apache/doris/analysis/SlotRef.java | 5 ++ .../apache/doris/analysis/VirtualSlotRef.java | 5 ++ .../nereids/analyzer/UnboundFunction.java | 6 ++ .../expressions/AggregateExpression.java | 6 ++ .../expressions/AssertNumRowsElement.java | 5 ++ .../nereids/trees/expressions/Expression.java | 10 +++- .../trees/expressions/NamedExpression.java | 5 ++ .../trees/expressions/SubqueryExpr.java | 5 ++ .../expressions/functions/BoundFunction.java | 6 ++ .../trees/expressions/literal/Literal.java | 5 ++ .../org/apache/doris/nereids/util/Utils.java | 14 +++++ .../analysis/CreateTableAsSelectStmtTest.java | 40 ++++++------- .../apache/doris/qe/OlapQueryCacheTest.java | 12 ++-- .../data/ddl_p0/test_create_view.out | 3 + .../suites/ddl_p0/test_create_view.groovy | 56 ++++++++++++++++++- 22 files changed, 210 insertions(+), 34 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/AnalyticExpr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/AnalyticExpr.java index 2a9e9a9c88..2271fc871a 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/AnalyticExpr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/AnalyticExpr.java @@ -29,6 +29,7 @@ import org.apache.doris.catalog.PrimitiveType; import org.apache.doris.catalog.Type; import org.apache.doris.common.AnalysisException; import org.apache.doris.common.TreeNode; +import org.apache.doris.nereids.util.Utils; import org.apache.doris.thrift.TExprNode; import com.google.common.base.Joiner; @@ -144,6 +145,11 @@ public class AnalyticExpr extends Expr { return window; } + @Override + protected String getExprName() { + return Utils.normalizeName(getFnCall().getExprName(), DEFAULT_EXPR_NAME); + } + @Override public int hashCode() { return Objects.hash(super.hashCode(), fnCall, orderByElements, window); diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/ColumnRefExpr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/ColumnRefExpr.java index ef0e37e2fa..d980a67076 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/ColumnRefExpr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/ColumnRefExpr.java @@ -18,6 +18,7 @@ package org.apache.doris.analysis; import org.apache.doris.common.AnalysisException; +import org.apache.doris.nereids.util.Utils; import org.apache.doris.thrift.TColumnRef; import org.apache.doris.thrift.TExprNode; import org.apache.doris.thrift.TExprNodeType; @@ -53,6 +54,11 @@ public class ColumnRefExpr extends Expr { return columnName; } + @Override + protected String getExprName() { + return Utils.normalizeName(getName(), DEFAULT_EXPR_NAME); + } + public void setName(String name) { this.columnName = name; } diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java index c167fdaa42..22d1c7e150 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/Expr.java @@ -37,6 +37,7 @@ import org.apache.doris.common.AnalysisException; import org.apache.doris.common.Config; import org.apache.doris.common.TreeNode; import org.apache.doris.common.io.Writable; +import org.apache.doris.nereids.util.Utils; import org.apache.doris.qe.ConnectContext; import org.apache.doris.rewrite.mvrewrite.MVExprEquivalent; import org.apache.doris.statistics.ExprStats; @@ -82,6 +83,7 @@ public abstract class Expr extends TreeNode implements ParseNode, Cloneabl public static final String AGG_STATE_SUFFIX = "_state"; public static final String AGG_UNION_SUFFIX = "_union"; public static final String AGG_MERGE_SUFFIX = "_merge"; + public static final String DEFAULT_EXPR_NAME = "expr"; protected boolean disableTableName = false; protected boolean needToMysql = false; @@ -292,6 +294,7 @@ public abstract class Expr extends TreeNode implements ParseNode, Cloneabl // Flag to indicate whether to wrap this expr's toSql() in parenthesis. Set by parser. // Needed for properly capturing expr precedences in the SQL string. protected boolean printSqlInParens = false; + protected final String exprName = Utils.normalizeName(this.getClass().getSimpleName(), DEFAULT_EXPR_NAME); protected Expr() { super(); @@ -333,6 +336,12 @@ public abstract class Expr extends TreeNode implements ParseNode, Cloneabl this.id = id; } + // Name of expr, this is used by generating column name automatically when there is no + // alias or is not slotRef + protected String getExprName() { + return this.exprName; + } + public Type getType() { return type; } diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java index 316a2594db..4a3e06f0ee 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java @@ -38,6 +38,7 @@ import org.apache.doris.common.AnalysisException; import org.apache.doris.common.ErrorCode; import org.apache.doris.common.ErrorReport; import org.apache.doris.mysql.privilege.PrivPredicate; +import org.apache.doris.nereids.util.Utils; import org.apache.doris.qe.ConnectContext; import org.apache.doris.thrift.TExprNode; import org.apache.doris.thrift.TExprNodeType; @@ -309,6 +310,11 @@ public class FunctionCallExpr extends Expr { super(); } + @Override + protected String getExprName() { + return Utils.normalizeName(this.getFnName().getFunction(), DEFAULT_EXPR_NAME); + } + public FunctionCallExpr(String functionName, List params) { this(new FunctionName(functionName), new FunctionParams(false, params)); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/LiteralExpr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/LiteralExpr.java index bde041aeef..babcc564c0 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/LiteralExpr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/LiteralExpr.java @@ -357,6 +357,11 @@ public abstract class LiteralExpr extends Expr implements Comparable items = selectList.getItems(); + for (int i = 0; i < items.size(); i++) { + SelectListItem item = items.get(i); if (item.isStar()) { TableName tblName = item.getTblName(); if (tblName == null) { @@ -541,7 +543,8 @@ public class SelectStmt extends QueryStmt { throw new AnalysisException("Subquery is not supported in the select list."); } resultExprs.add(rewriteQueryExprByMvColumnExpr(item.getExpr(), analyzer)); - SlotRef aliasRef = new SlotRef(null, item.toColumnLabel()); + String columnLabel = item.toColumnLabel(i); + SlotRef aliasRef = new SlotRef(null, columnLabel); Expr existingAliasExpr = aliasSMap.get(aliasRef); if (existingAliasExpr != null && !existingAliasExpr.equals(item.getExpr())) { // If we have already seen this alias, it refers to more than one column and @@ -549,7 +552,7 @@ public class SelectStmt extends QueryStmt { ambiguousAliasList.add(aliasRef); } aliasSMap.put(aliasRef, item.getExpr().clone()); - colLabels.add(item.toColumnLabel()); + colLabels.add(columnLabel); } } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/SlotRef.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/SlotRef.java index ae8eeabe63..fd5e27d647 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/SlotRef.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/SlotRef.java @@ -305,6 +305,11 @@ public class SlotRef extends Expr { return col; } + @Override + protected String getExprName() { + return toColumnLabel(); + } + @Override protected void toThrift(TExprNode msg) { msg.node_type = TExprNodeType.SLOT_REF; diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/VirtualSlotRef.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/VirtualSlotRef.java index 4cfd7a62cc..07eba56652 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/VirtualSlotRef.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/VirtualSlotRef.java @@ -121,4 +121,9 @@ public class VirtualSlotRef extends SlotRef { desc = analyzer.registerVirtualColumnRef(super.getColumnName(), type, tupleDescriptor); numDistinctValues = desc.getStats().getNumDistinctValues(); } + + @Override + protected String getExprName() { + return super.getExprName(); + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/analyzer/UnboundFunction.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/analyzer/UnboundFunction.java index fa4b8a8ba4..c5cb960dbe 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/analyzer/UnboundFunction.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/analyzer/UnboundFunction.java @@ -22,6 +22,7 @@ import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.functions.Function; import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable; import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; +import org.apache.doris.nereids.util.Utils; import com.google.common.base.Joiner; @@ -60,6 +61,11 @@ public class UnboundFunction extends Function implements Unbound, PropagateNulla return name; } + @Override + protected String getExpressionName() { + return Utils.normalizeName(getName(), DEFAULT_EXPRESSION_NAME); + } + public String getDbName() { return dbName; } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/AggregateExpression.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/AggregateExpression.java index 223d1798f0..4eb4653ded 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/AggregateExpression.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/AggregateExpression.java @@ -24,6 +24,7 @@ import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; import org.apache.doris.nereids.trees.plans.AggMode; import org.apache.doris.nereids.types.DataType; import org.apache.doris.nereids.types.VarcharType; +import org.apache.doris.nereids.util.Utils; import com.google.common.base.Preconditions; @@ -117,6 +118,11 @@ public class AggregateExpression extends Expression implements UnaryExpression { } } + @Override + protected String getExpressionName() { + return Utils.normalizeName(function.getName(), DEFAULT_EXPRESSION_NAME); + } + @Override public boolean equals(Object o) { if (this == o) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/AssertNumRowsElement.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/AssertNumRowsElement.java index 48a7c6aee4..8744266c86 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/AssertNumRowsElement.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/AssertNumRowsElement.java @@ -87,6 +87,11 @@ public class AssertNumRowsElement extends Expression implements LeafExpression, return toString(); } + @Override + protected String getExpressionName() { + return assertion.name().toLowerCase(); + } + @Override public boolean equals(Object o) { if (this == o) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Expression.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Expression.java index 07c0831a0f..3f0370d7c3 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Expression.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/Expression.java @@ -34,6 +34,7 @@ import org.apache.doris.nereids.types.MapType; import org.apache.doris.nereids.types.StructField; import org.apache.doris.nereids.types.StructType; import org.apache.doris.nereids.types.coercion.AnyDataType; +import org.apache.doris.nereids.util.Utils; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; @@ -49,9 +50,10 @@ import java.util.stream.Collectors; * Abstract class for all Expression in Nereids. */ public abstract class Expression extends AbstractTreeNode implements ExpressionTrait { + public static final String DEFAULT_EXPRESSION_NAME = "expression"; // Mask this expression is generated by rule, should be removed. public boolean isGeneratedIsNotNull = false; - + protected final String exprName = Utils.normalizeName(this.getClass().getSimpleName(), DEFAULT_EXPRESSION_NAME); private final int depth; private final int width; @@ -92,6 +94,12 @@ public abstract class Expression extends AbstractTreeNode implements return new Alias(this, alias); } + // Name of expr, this is used by generating column name automatically when there is no + // alias + protected String getExpressionName() { + return this.exprName; + } + /** * check input data types */ diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/NamedExpression.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/NamedExpression.java index 8707792da3..6c2e14191c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/NamedExpression.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/NamedExpression.java @@ -56,4 +56,9 @@ public abstract class NamedExpression extends Expression { public String getQualifiedName() throws UnboundException { return Utils.qualifiedName(getQualifier(), getName()); } + + @Override + protected String getExpressionName() { + return Utils.normalizeName(getName(), DEFAULT_EXPRESSION_NAME); + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/SubqueryExpr.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/SubqueryExpr.java index 4608d5e96a..6715bed6cc 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/SubqueryExpr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/SubqueryExpr.java @@ -84,6 +84,11 @@ public abstract class SubqueryExpr extends Expression implements LeafExpression return "(" + queryPlan + ")"; } + @Override + protected String getExpressionName() { + return "subquery"; + } + @Override public String toString() { return Utils.toSqlString("SubqueryExpr", diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/BoundFunction.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/BoundFunction.java index f47eccf462..d500874848 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/BoundFunction.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/BoundFunction.java @@ -21,6 +21,7 @@ import org.apache.doris.catalog.FunctionSignature; import org.apache.doris.nereids.exceptions.UnboundException; import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; +import org.apache.doris.nereids.util.Utils; import com.google.common.base.Suppliers; @@ -54,6 +55,11 @@ public abstract class BoundFunction extends Function implements ComputeSignature return name; } + @Override + protected String getExpressionName() { + return Utils.normalizeName(getName(), DEFAULT_EXPRESSION_NAME); + } + public FunctionSignature getSignature() { return signatureCache.get(); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/Literal.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/Literal.java index e12ad49a66..3397d92f5e 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/Literal.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/Literal.java @@ -131,6 +131,11 @@ public abstract class Literal extends Expression implements LeafExpression, Comp return toString(); } + @Override + protected String getExpressionName() { + return "literal"; + } + @Override public boolean nullable() throws UnboundException { return this instanceof NullLiteral; diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/Utils.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/Utils.java index e5d54b4096..456dcafdb2 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/Utils.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/Utils.java @@ -24,6 +24,7 @@ import org.apache.doris.nereids.trees.expressions.Not; import org.apache.doris.nereids.trees.expressions.SlotReference; import org.apache.doris.nereids.trees.expressions.shape.BinaryExpression; +import com.google.common.base.CaseFormat; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; @@ -261,4 +262,17 @@ public class Utils { public static List copyRequiredMutableList(List list) { return Lists.newArrayList(Objects.requireNonNull(list, "non-null list is required")); } + + /** + * Normalize the name to lower underscore style, return default name if the name is empty. + */ + public static String normalizeName(String name, String defaultName) { + if (StringUtils.isEmpty(name)) { + return defaultName; + } + if (name.contains("$")) { + name = name.replace("$", "_"); + } + return CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, name); + } } diff --git a/fe/fe-core/src/test/java/org/apache/doris/analysis/CreateTableAsSelectStmtTest.java b/fe/fe-core/src/test/java/org/apache/doris/analysis/CreateTableAsSelectStmtTest.java index c6c258d0da..854225c742 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/analysis/CreateTableAsSelectStmtTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/CreateTableAsSelectStmtTest.java @@ -106,11 +106,11 @@ public class CreateTableAsSelectStmtTest extends TestWithFeService { if (Config.enable_decimal_conversion) { Assertions.assertEquals( "CREATE TABLE `select_decimal_table_1` (\n" - + " `_col0` DECIMAL(38, 2) NULL\n" + + " `__sum_0` DECIMAL(38, 2) NULL\n" + ") ENGINE=OLAP\n" - + "DUPLICATE KEY(`_col0`)\n" + + "DUPLICATE KEY(`__sum_0`)\n" + "COMMENT 'OLAP'\n" - + "DISTRIBUTED BY HASH(`_col0`) BUCKETS 10\n" + + "DISTRIBUTED BY HASH(`__sum_0`) BUCKETS 10\n" + "PROPERTIES (\n" + "\"replication_allocation\" = \"tag.location.default: 1\",\n" + "\"is_being_synced\" = \"false\",\n" @@ -123,11 +123,11 @@ public class CreateTableAsSelectStmtTest extends TestWithFeService { } else { Assertions.assertEquals( "CREATE TABLE `select_decimal_table_1` (\n" - + " `_col0` decimal(27, 9) NULL\n" + + " `__sum_0` decimal(27, 9) NULL\n" + ") ENGINE=OLAP\n" - + "DUPLICATE KEY(`_col0`)\n" + + "DUPLICATE KEY(`__sum_0`)\n" + "COMMENT 'OLAP'\n" - + "DISTRIBUTED BY HASH(`_col0`) BUCKETS 10\n" + + "DISTRIBUTED BY HASH(`__sum_0`) BUCKETS 10\n" + "PROPERTIES (\n" + "\"replication_allocation\" = \"tag.location.default: 1\",\n" + "\"is_being_synced\" = \"false\",\n" @@ -182,11 +182,11 @@ public class CreateTableAsSelectStmtTest extends TestWithFeService { ShowResultSet showResultSet1 = showCreateTableByName("select_function_1"); Assertions.assertEquals( "CREATE TABLE `select_function_1` (\n" - + " `_col0` bigint(20) NULL\n" + + " `__count_0` bigint(20) NULL\n" + ") ENGINE=OLAP\n" - + "DUPLICATE KEY(`_col0`)\n" + + "DUPLICATE KEY(`__count_0`)\n" + "COMMENT 'OLAP'\n" - + "DISTRIBUTED BY HASH(`_col0`) BUCKETS 10\n" + + "DISTRIBUTED BY HASH(`__count_0`) BUCKETS 10\n" + "PROPERTIES (\n" + "\"replication_allocation\" = \"tag.location.default: 1\",\n" + "\"is_being_synced\" = \"false\",\n" @@ -204,15 +204,15 @@ public class CreateTableAsSelectStmtTest extends TestWithFeService { ShowResultSet showResultSet2 = showCreateTableByName("select_function_2"); Assertions.assertEquals( "CREATE TABLE `select_function_2` (\n" - + " `_col0` bigint(20) NULL,\n" - + " `_col1` bigint(20) NULL,\n" - + " `_col2` bigint(20) NULL,\n" - + " `_col3` bigint(20) NULL,\n" - + " `_col4` bigint(20) NULL\n" + + " `__sum_0` bigint(20) NULL,\n" + + " `__sum_1` bigint(20) NULL,\n" + + " `__sum_2` bigint(20) NULL,\n" + + " `__count_3` bigint(20) NULL,\n" + + " `__count_4` bigint(20) NULL\n" + ") ENGINE=OLAP\n" - + "DUPLICATE KEY(`_col0`, `_col1`, `_col2`)\n" + + "DUPLICATE KEY(`__sum_0`, `__sum_1`, `__sum_2`)\n" + "COMMENT 'OLAP'\n" - + "DISTRIBUTED BY HASH(`_col0`) BUCKETS 10\n" + + "DISTRIBUTED BY HASH(`__sum_0`) BUCKETS 10\n" + "PROPERTIES (\n" + "\"replication_allocation\" = \"tag.location.default: 1\",\n" + "\"is_being_synced\" = \"false\",\n" @@ -587,13 +587,13 @@ public class CreateTableAsSelectStmtTest extends TestWithFeService { String showStr = showResultSet.getResultRows().get(0).get(1); Assertions.assertEquals( "CREATE TABLE `varchar_len1` (\n" - + " `_col0` varchar(*) NULL,\n" - + " `_col1` varchar(*) NULL,\n" + + " `__literal_0` varchar(*) NULL,\n" + + " `__concat_1` varchar(*) NULL,\n" + " `userId` varchar(255) NOT NULL\n" + ") ENGINE=OLAP\n" - + "DUPLICATE KEY(`_col0`)\n" + + "DUPLICATE KEY(`__literal_0`)\n" + "COMMENT 'OLAP'\n" - + "DISTRIBUTED BY HASH(`_col0`) BUCKETS 10\n" + + "DISTRIBUTED BY HASH(`__literal_0`) BUCKETS 10\n" + "PROPERTIES (\n" + "\"replication_allocation\" = \"tag.location.default: 1\",\n" + "\"is_being_synced\" = \"false\",\n" diff --git a/fe/fe-core/src/test/java/org/apache/doris/qe/OlapQueryCacheTest.java b/fe/fe-core/src/test/java/org/apache/doris/qe/OlapQueryCacheTest.java index a0a3c95652..934521a094 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/qe/OlapQueryCacheTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/qe/OlapQueryCacheTest.java @@ -1023,7 +1023,7 @@ public class OlapQueryCacheTest { cache.rewriteSelectStmt(null); LOG.warn("Sub nokey={}", cache.getNokeyStmt().toSql()); Assert.assertEquals(cache.getNokeyStmt().toSql(), - "SELECT `eventdate` AS `eventdate`, sum(`pv`) AS `sum(``pv``)` FROM (" + "SELECT `eventdate` AS `eventdate`, sum(`pv`) AS `__sum_1` FROM (" + "SELECT `eventdate` AS `eventdate`, count(`userid`) AS `pv` FROM " + "`testCluster:testDb`.`appevent` WHERE `eventid` = 1" + " GROUP BY `eventdate`) tbl GROUP BY `eventdate`"); @@ -1045,7 +1045,7 @@ public class OlapQueryCacheTest { sql = ca.getRewriteStmt().toSql(); LOG.warn("Sub rewrite={}", sql); Assert.assertEquals(sql, - "SELECT `eventdate` AS `eventdate`, sum(`pv`) AS `sum(``pv``)` FROM (" + "SELECT `eventdate` AS `eventdate`, sum(`pv`) AS `__sum_1` FROM (" + "SELECT `eventdate` AS `eventdate`, count(`userid`) AS `pv` FROM " + "`testCluster:testDb`.`appevent` WHERE " + "`eventdate` > '2020-01-13' AND `eventdate` < '2020-01-16' AND `eventid` = 1 GROUP BY " @@ -1102,7 +1102,7 @@ public class OlapQueryCacheTest { SqlCache sqlCache = (SqlCache) ca.getCache(); String cacheKey = sqlCache.getSqlWithViewStmt(); Assert.assertEquals(cacheKey, "SELECT `eventdate` AS `eventdate`, count(`userid`) AS " - + "`count(``userid``)` FROM `testCluster:testDb`.`appevent` WHERE `eventdate` >= '2020-01-12' AND " + + "`__count_1` FROM `testCluster:testDb`.`appevent` WHERE `eventdate` >= '2020-01-12' AND " + "`eventdate` <= '2020-01-14' GROUP BY `eventdate`|"); Assert.assertEquals(selectedPartitionIds.size(), sqlCache.getSumOfPartitionNum()); } @@ -1141,7 +1141,7 @@ public class OlapQueryCacheTest { SqlCache sqlCache = (SqlCache) ca.getCache(); String cacheKey = sqlCache.getSqlWithViewStmt(); Assert.assertEquals(cacheKey, "SELECT `testCluster:testDb`.`view1`.`eventdate` AS `eventdate`, `testCluster:testDb`.`view1`." - + "`count(`userid`)` AS `count(``userid``)` FROM `testCluster:testDb`.`view1`|select eventdate, COUNT(userid) " + + "`__count_1` AS `__count_1` FROM `testCluster:testDb`.`view1`|select eventdate, COUNT(userid) " + "FROM appevent WHERE eventdate>=\"2020-01-12\" and eventdate<=\"2020-01-14\" GROUP BY eventdate"); Assert.assertEquals(selectedPartitionIds.size(), sqlCache.getSumOfPartitionNum()); } @@ -1239,7 +1239,7 @@ public class OlapQueryCacheTest { cache.rewriteSelectStmt(null); Assert.assertEquals(cache.getNokeyStmt().getWhereClause(), null); Assert.assertEquals(cache.getSqlWithViewStmt(), "SELECT `testCluster:testDb`.`view3`.`eventdate` AS " - + "`eventdate`, `testCluster:testDb`.`view3`.`count(`userid`)` AS `count(``userid``)` FROM " + + "`eventdate`, `testCluster:testDb`.`view3`.`__count_1` AS `__count_1` FROM " + "`testCluster:testDb`.`view3`|select eventdate, COUNT(userid) FROM appevent WHERE eventdate>=" + "\"2020-01-12\" and eventdate<=\"2020-01-15\" GROUP BY eventdate"); } catch (Exception e) { @@ -1295,7 +1295,7 @@ public class OlapQueryCacheTest { SqlCache sqlCache = (SqlCache) ca.getCache(); String cacheKey = sqlCache.getSqlWithViewStmt(); Assert.assertEquals(cacheKey, "SELECT `testCluster:testDb`.`view4`.`eventdate` AS `eventdate`, " - + "`testCluster:testDb`.`view4`.`count(`userid`)` AS `count(``userid``)` FROM `testCluster:testDb`.`view4`|select " + + "`testCluster:testDb`.`view4`.`__count_1` AS `__count_1` FROM `testCluster:testDb`.`view4`|select " + "eventdate, COUNT(userid) FROM view2 WHERE eventdate>=\"2020-01-12\" and " + "eventdate<=\"2020-01-14\" GROUP BY eventdate|select eventdate, userid FROM appevent"); Assert.assertEquals(selectedPartitionIds.size(), sqlCache.getSumOfPartitionNum()); diff --git a/regression-test/data/ddl_p0/test_create_view.out b/regression-test/data/ddl_p0/test_create_view.out index f55b7fa598..9c03e9633c 100644 --- a/regression-test/data/ddl_p0/test_create_view.out +++ b/regression-test/data/ddl_p0/test_create_view.out @@ -24,3 +24,6 @@ 2 [10, -2, 8] [1, 0, 1] 3 [-1, 20, 0] [0, 1, 0] +-- !test_view_6 -- +v1 CREATE VIEW `v1` COMMENT 'VIEW' AS SELECT `error_code` AS `error_code`, 1 AS `__literal_1`, 'string' AS `__literal_2`, now() AS `__now_3`, dayofyear(`op_time`) AS `__dayofyear_4`, CAST(`source` AS BIGINT) AS `__cast_expr_5`, min(`timestamp`) OVER (ORDER BY `op_time` DESC NULLS LAST ROWS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING) AS `__min_6`, 1 > 2 AS `__binary_predicate_7`, (2 + 3) AS `__arithmetic_expr_8`, 1 IN (1, 2, 3, 4) AS `__in_predicate_9`, `remark` LIKE '%like' AS `__like_predicate_10`, CASE WHEN `remark` = 's' THEN 1 ELSE 2 END AS `__case_expr_11`, (CAST(TRUE AS BIGINT) | CAST(FALSE AS BIGINT)) AS `__arithmetic_expr_12` FROM `default_cluster:regression_test_ddl_p0`.`view_column_name_test`; + diff --git a/regression-test/suites/ddl_p0/test_create_view.groovy b/regression-test/suites/ddl_p0/test_create_view.groovy index a2c7090e6d..6020aa3105 100644 --- a/regression-test/suites/ddl_p0/test_create_view.groovy +++ b/regression-test/suites/ddl_p0/test_create_view.groovy @@ -54,13 +54,13 @@ suite("test_create_view") { select aa.RQ as RQ, aa.v1 as v1,aa.v2 as v2 , bb.v3 as v3 from ( select RQ, count(distinct v1) as v1 , count(distinct v2 ) as v2 - from count_distinct + from count_distinct group by RQ ) aa LEFT JOIN ( - select RQ, max(v3) as v3 - from count_distinct + select RQ, max(v3) as v3 + from count_distinct group by RQ ) bb on aa.RQ = bb.RQ; @@ -153,4 +153,54 @@ suite("test_create_view") { select *, array_map(x->x>0,k3) from view_baseall order by k1; """ qt_test_view_5 """ select * from test_view8 order by k1; """ + + sql """DROP TABLE IF EXISTS view_column_name_test""" + sql """ + CREATE TABLE IF NOT EXISTS view_column_name_test + ( + `timestamp` DATE NOT NULL COMMENT "['0000-01-01', '9999-12-31']", + `type` TINYINT NOT NULL COMMENT "[-128, 127]", + `error_code` INT COMMENT "[-2147483648, 2147483647]", + `error_msg` VARCHAR(300) COMMENT "[1-65533]", + `op_id` BIGINT COMMENT "[-9223372036854775808, 9223372036854775807]", + `op_time` DATETIME COMMENT "['0000-01-01 00:00:00', '9999-12-31 23:59:59']", + `target` float COMMENT "4 字节", + `source` double COMMENT "8 字节", + `lost_cost` decimal(12,2) COMMENT "", + `remark` string COMMENT "1m size", + `op_userid` LARGEINT COMMENT "[-2^127 + 1 ~ 2^127 - 1]", + `plate` SMALLINT COMMENT "[-32768, 32767]", + `iscompleted` boolean COMMENT "true 或者 false" + ) + DISTRIBUTED BY HASH(`type`) BUCKETS 1 + PROPERTIES ('replication_num' = '1'); + """ + + sql """ + DROP VIEW IF EXISTS v1 + """ + sql """ + CREATE VIEW v1 AS + SELECT + error_code, + 1, + 'string', + now(), + dayofyear(op_time), + cast (source AS BIGINT), + min(`timestamp`) OVER ( + ORDER BY + op_time DESC ROWS BETWEEN UNBOUNDED PRECEDING + AND 1 FOLLOWING + ), + 1 > 2, + 2 + 3, + 1 IN (1, 2, 3, 4), + remark LIKE '%like', + CASE WHEN remark = 's' THEN 1 ELSE 2 END, + TRUE | FALSE + FROM + view_column_name_test + """ + qt_test_view_6 """ SHOW VIEW FROM view_column_name_test;""" }