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

yiguolei pushed a commit to branch branch-2.1
in repository https://gitbox.apache.org/repos/asf/doris.git

commit 0dd9d8f2266b5e7fede40ad6d5f9adb3ff4f735c
Author: feiniaofeiafei <53502832+feiniaofeia...@users.noreply.github.com>
AuthorDate: Fri Apr 12 12:25:13 2024 +0800

    [feat](nereids) support create view in nereids (#32743)
---
 .../antlr4/org/apache/doris/nereids/DorisParser.g4 |   3 +
 .../org/apache/doris/analysis/BaseViewStmt.java    |   2 -
 .../org/apache/doris/analysis/CreateViewStmt.java  |   9 +
 .../org/apache/doris/nereids/StatementContext.java |  14 +
 .../doris/nereids/analyzer/UnboundRelation.java    |  31 +-
 .../apache/doris/nereids/analyzer/UnboundStar.java |  16 +-
 .../doris/nereids/parser/LogicalPlanBuilder.java   |  51 +++-
 .../apache/doris/nereids/parser/NereidsParser.java |  15 +-
 .../nereids/rules/analysis/BindExpression.java     |  14 +
 .../doris/nereids/rules/analysis/BindRelation.java |   8 +
 .../nereids/trees/expressions/SlotReference.java   |   5 +
 .../nereids/trees/expressions/WindowFrame.java     |  28 +-
 .../trees/expressions/functions/scalar/Lambda.java |   2 +-
 .../apache/doris/nereids/trees/plans/PlanType.java |   3 +-
 .../trees/plans/commands/CreateViewCommand.java    |  49 +++
 .../trees/plans/commands/info/CreateViewInfo.java  | 329 +++++++++++++++++++++
 .../commands/info/SimpleColumnDefinition.java      |   6 +
 .../trees/plans/visitor/CommandVisitor.java        |   5 +
 .../java/org/apache/doris/nereids/util/Utils.java  |  17 ++
 .../data/ddl_p0/test_create_view_nereids.out       | 228 ++++++++++++++
 .../test_show_create_table_and_views_nereids.out   |  46 +++
 .../suites/ddl_p0/test_create_view.groovy          |   5 +-
 .../suites/ddl_p0/test_create_view_nereids.groovy  | 280 ++++++++++++++++++
 .../test_show_create_table_and_views.groovy        |   2 +
 ...est_show_create_table_and_views_nereids.groovy} |   8 +-
 25 files changed, 1150 insertions(+), 26 deletions(-)

diff --git a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4 
b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4
index 826112d050d..74870648786 100644
--- a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4
+++ b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4
@@ -60,6 +60,9 @@ statementBase
         properties=propertyClause?
         (BROKER extProperties=propertyClause)?
         (AS query)?                                                    
#createTable
+    | CREATE VIEW (IF NOT EXISTS)? name=multipartIdentifier
+        (LEFT_PAREN cols=simpleColumnDefs RIGHT_PAREN)?
+        (COMMENT STRING_LITERAL)? AS query                                
#createView
     | explain? INSERT (INTO | OVERWRITE TABLE)
         (tableName=multipartIdentifier | DORIS_INTERNAL_TABLE_ID LEFT_PAREN 
tableId=INTEGER_VALUE RIGHT_PAREN)
         partitionSpec?  // partition define
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/BaseViewStmt.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/BaseViewStmt.java
index 8114448f0d4..d8740f03f52 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/BaseViewStmt.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/BaseViewStmt.java
@@ -25,7 +25,6 @@ import org.apache.doris.common.ErrorReport;
 import org.apache.doris.common.UserException;
 import org.apache.doris.common.util.ToSqlContext;
 
-import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 import org.apache.logging.log4j.LogManager;
@@ -50,7 +49,6 @@ public class BaseViewStmt extends DdlStmt {
     protected QueryStmt cloneStmt;
 
     public BaseViewStmt(TableName tableName, List<ColWithComment> cols, 
QueryStmt queryStmt) {
-        Preconditions.checkNotNull(queryStmt);
         this.tableName = tableName;
         this.cols = cols;
         this.viewDefStmt = queryStmt;
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateViewStmt.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateViewStmt.java
index ba5007ccce8..2eed97f0a01 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateViewStmt.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateViewStmt.java
@@ -17,6 +17,7 @@
 
 package org.apache.doris.analysis;
 
+import org.apache.doris.catalog.Column;
 import org.apache.doris.catalog.Env;
 import org.apache.doris.common.ErrorCode;
 import org.apache.doris.common.ErrorReport;
@@ -92,4 +93,12 @@ public class CreateViewStmt extends BaseViewStmt {
             }
         }
     }
+
+    public void setInlineViewDef(String querySql) {
+        inlineViewDef = querySql;
+    }
+
+    public void setFinalColumns(List<Column> columns) {
+        finalCols.addAll(columns);
+    }
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/StatementContext.java 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/StatementContext.java
index 7b444995120..403c605ba75 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/StatementContext.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/StatementContext.java
@@ -54,6 +54,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.TreeMap;
 import javax.annotation.concurrent.GuardedBy;
 
 /**
@@ -121,6 +122,11 @@ public class StatementContext {
 
     private BitSet disableRules;
 
+    // for create view support in nereids
+    // key is the start and end position of the sql substring that needs to be 
replaced,
+    // and value is the new string used for replacement.
+    private TreeMap<Pair<Integer, Integer>, String> indexInSqlToString = new 
TreeMap<>(new Pair.PairComparator<>());
+
     public StatementContext() {
         this.connectContext = ConnectContext.get();
     }
@@ -354,4 +360,12 @@ public class StatementContext {
     public void setHasUnknownColStats(boolean hasUnknownColStats) {
         this.hasUnknownColStats = hasUnknownColStats;
     }
+
+    public TreeMap<Pair<Integer, Integer>, String> getIndexInSqlToString() {
+        return indexInSqlToString;
+    }
+
+    public void addIndexInSqlToString(Pair<Integer, Integer> pair, String 
replacement) {
+        indexInSqlToString.put(pair, replacement);
+    }
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/analyzer/UnboundRelation.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/analyzer/UnboundRelation.java
index 4514ea05bfb..34217b249fc 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/analyzer/UnboundRelation.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/analyzer/UnboundRelation.java
@@ -18,6 +18,7 @@
 package org.apache.doris.nereids.analyzer;
 
 import org.apache.doris.analysis.TableScanParams;
+import org.apache.doris.common.Pair;
 import org.apache.doris.nereids.exceptions.UnboundException;
 import org.apache.doris.nereids.memo.GroupExpression;
 import org.apache.doris.nereids.properties.LogicalProperties;
@@ -55,35 +56,44 @@ public class UnboundRelation extends LogicalRelation 
implements Unbound, BlockFu
     private final Optional<TableSample> tableSample;
     private final Optional<String> indexName;
     private TableScanParams scanParams;
+    // the start and end position of the sql substring(e.g. "t1", "db1.t1", 
"ctl1.db1.t1")
+    private final Optional<Pair<Integer, Integer>> indexInSqlString;
 
     public UnboundRelation(RelationId id, List<String> nameParts) {
         this(id, nameParts, Optional.empty(), Optional.empty(), 
ImmutableList.of(), false, ImmutableList.of(),
-                ImmutableList.of(), Optional.empty(), Optional.empty(), null);
+                ImmutableList.of(), Optional.empty(), Optional.empty(), null, 
Optional.empty());
     }
 
     public UnboundRelation(RelationId id, List<String> nameParts, List<String> 
partNames, boolean isTempPart) {
         this(id, nameParts, Optional.empty(), Optional.empty(), partNames, 
isTempPart, ImmutableList.of(),
-                ImmutableList.of(), Optional.empty(), Optional.empty(), null);
+                ImmutableList.of(), Optional.empty(), Optional.empty(), null, 
Optional.empty());
     }
 
     public UnboundRelation(RelationId id, List<String> nameParts, List<String> 
partNames, boolean isTempPart,
             List<Long> tabletIds, List<String> hints, Optional<TableSample> 
tableSample, Optional<String> indexName) {
         this(id, nameParts, Optional.empty(), Optional.empty(),
-                partNames, isTempPart, tabletIds, hints, tableSample, 
indexName, null);
+                partNames, isTempPart, tabletIds, hints, tableSample, 
indexName, null, Optional.empty());
     }
 
     public UnboundRelation(RelationId id, List<String> nameParts, List<String> 
partNames, boolean isTempPart,
             List<Long> tabletIds, List<String> hints, Optional<TableSample> 
tableSample, Optional<String> indexName,
             TableScanParams scanParams) {
         this(id, nameParts, Optional.empty(), Optional.empty(),
-                partNames, isTempPart, tabletIds, hints, tableSample, 
indexName, scanParams);
+                partNames, isTempPart, tabletIds, hints, tableSample, 
indexName, scanParams, Optional.empty());
     }
 
     public UnboundRelation(RelationId id, List<String> nameParts, 
Optional<GroupExpression> groupExpression,
             Optional<LogicalProperties> logicalProperties, List<String> 
partNames, boolean isTempPart,
             List<Long> tabletIds, List<String> hints, Optional<TableSample> 
tableSample, Optional<String> indexName) {
         this(id, nameParts, groupExpression, logicalProperties, partNames,
-                isTempPart, tabletIds, hints, tableSample, indexName, null);
+                isTempPart, tabletIds, hints, tableSample, indexName, null, 
Optional.empty());
+    }
+
+    public UnboundRelation(RelationId id, List<String> nameParts, List<String> 
partNames, boolean isTempPart,
+            List<Long> tabletIds, List<String> hints, Optional<TableSample> 
tableSample, Optional<String> indexName,
+            TableScanParams scanParams, Optional<Pair<Integer, Integer>> 
indexInSqlString) {
+        this(id, nameParts, Optional.empty(), Optional.empty(),
+                partNames, isTempPart, tabletIds, hints, tableSample, 
indexName, scanParams, indexInSqlString);
     }
 
     /**
@@ -92,7 +102,7 @@ public class UnboundRelation extends LogicalRelation 
implements Unbound, BlockFu
     public UnboundRelation(RelationId id, List<String> nameParts, 
Optional<GroupExpression> groupExpression,
             Optional<LogicalProperties> logicalProperties, List<String> 
partNames, boolean isTempPart,
             List<Long> tabletIds, List<String> hints, Optional<TableSample> 
tableSample, Optional<String> indexName,
-            TableScanParams scanParams) {
+            TableScanParams scanParams, Optional<Pair<Integer, Integer>> 
indexInSqlString) {
         super(id, PlanType.LOGICAL_UNBOUND_RELATION, groupExpression, 
logicalProperties);
         this.nameParts = 
ImmutableList.copyOf(Objects.requireNonNull(nameParts, "nameParts should not 
null"));
         this.partNames = 
ImmutableList.copyOf(Objects.requireNonNull(partNames, "partNames should not 
null"));
@@ -102,6 +112,7 @@ public class UnboundRelation extends LogicalRelation 
implements Unbound, BlockFu
         this.tableSample = tableSample;
         this.indexName = indexName;
         this.scanParams = scanParams;
+        this.indexInSqlString = indexInSqlString;
     }
 
     public List<String> getNameParts() {
@@ -122,14 +133,14 @@ public class UnboundRelation extends LogicalRelation 
implements Unbound, BlockFu
     public Plan withGroupExpression(Optional<GroupExpression> groupExpression) 
{
         return new UnboundRelation(relationId, nameParts,
                 groupExpression, Optional.of(getLogicalProperties()),
-                partNames, isTempPart, tabletIds, hints, tableSample, 
indexName, null);
+                partNames, isTempPart, tabletIds, hints, tableSample, 
indexName, null, indexInSqlString);
     }
 
     @Override
     public Plan withGroupExprLogicalPropChildren(Optional<GroupExpression> 
groupExpression,
             Optional<LogicalProperties> logicalProperties, List<Plan> 
children) {
         return new UnboundRelation(relationId, nameParts, groupExpression, 
logicalProperties, partNames,
-                isTempPart, tabletIds, hints, tableSample, indexName, null);
+                isTempPart, tabletIds, hints, tableSample, indexName, null, 
indexInSqlString);
     }
 
     @Override
@@ -187,4 +198,8 @@ public class UnboundRelation extends LogicalRelation 
implements Unbound, BlockFu
     public TableScanParams getScanParams() {
         return scanParams;
     }
+
+    public Optional<Pair<Integer, Integer>> getIndexInSqlString() {
+        return indexInSqlString;
+    }
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/analyzer/UnboundStar.java 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/analyzer/UnboundStar.java
index 43705611562..cf73f877d60 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/analyzer/UnboundStar.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/analyzer/UnboundStar.java
@@ -17,6 +17,7 @@
 
 package org.apache.doris.nereids.analyzer;
 
+import org.apache.doris.common.Pair;
 import org.apache.doris.nereids.exceptions.UnboundException;
 import org.apache.doris.nereids.trees.expressions.NamedExpression;
 import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
@@ -28,17 +29,26 @@ import com.google.common.collect.ImmutableList;
 
 import java.util.List;
 import java.util.Objects;
+import java.util.Optional;
 
 /**
  * Star expression.
  */
 public class UnboundStar extends NamedExpression implements LeafExpression, 
Unbound, PropagateNullable {
-
     private final List<String> qualifier;
+    // the start and end position of the sql substring(e.g. "*", "table.*")
+    private final Optional<Pair<Integer, Integer>> indexInSqlString;
 
     public UnboundStar(List<String> qualifier) {
         super(ImmutableList.of());
         this.qualifier = 
Objects.requireNonNull(ImmutableList.copyOf(qualifier), "qualifier can not be 
null");
+        this.indexInSqlString = Optional.empty();
+    }
+
+    public UnboundStar(List<String> qualifier, Optional<Pair<Integer, 
Integer>> indexInSqlString) {
+        super(ImmutableList.of());
+        this.qualifier = 
Objects.requireNonNull(ImmutableList.copyOf(qualifier), "qualifier can not be 
null");
+        this.indexInSqlString = indexInSqlString;
     }
 
     @Override
@@ -71,6 +81,10 @@ public class UnboundStar extends NamedExpression implements 
LeafExpression, Unbo
         return qualifier.equals(that.qualifier);
     }
 
+    public Optional<Pair<Integer, Integer>> getIndexInSqlString() {
+        return indexInSqlString;
+    }
+
     @Override
     public int hashCode() {
         return Objects.hash(super.hashCode(), qualifier);
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
index 5087b38dd1e..4739e74b262 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
@@ -77,6 +77,7 @@ import org.apache.doris.nereids.DorisParser.CreateMTMVContext;
 import org.apache.doris.nereids.DorisParser.CreateProcedureContext;
 import org.apache.doris.nereids.DorisParser.CreateRowPolicyContext;
 import org.apache.doris.nereids.DorisParser.CreateTableContext;
+import org.apache.doris.nereids.DorisParser.CreateViewContext;
 import org.apache.doris.nereids.DorisParser.CteContext;
 import org.apache.doris.nereids.DorisParser.DataTypeWithNullableContext;
 import org.apache.doris.nereids.DorisParser.DateCeilContext;
@@ -360,6 +361,7 @@ import 
org.apache.doris.nereids.trees.plans.commands.CreateMTMVCommand;
 import org.apache.doris.nereids.trees.plans.commands.CreatePolicyCommand;
 import org.apache.doris.nereids.trees.plans.commands.CreateProcedureCommand;
 import org.apache.doris.nereids.trees.plans.commands.CreateTableCommand;
+import org.apache.doris.nereids.trees.plans.commands.CreateViewCommand;
 import org.apache.doris.nereids.trees.plans.commands.DeleteFromCommand;
 import org.apache.doris.nereids.trees.plans.commands.DeleteFromUsingCommand;
 import org.apache.doris.nereids.trees.plans.commands.DropConstraintCommand;
@@ -386,6 +388,7 @@ import 
org.apache.doris.nereids.trees.plans.commands.info.CancelMTMVTaskInfo;
 import org.apache.doris.nereids.trees.plans.commands.info.ColumnDefinition;
 import org.apache.doris.nereids.trees.plans.commands.info.CreateMTMVInfo;
 import org.apache.doris.nereids.trees.plans.commands.info.CreateTableInfo;
+import org.apache.doris.nereids.trees.plans.commands.info.CreateViewInfo;
 import org.apache.doris.nereids.trees.plans.commands.info.DMLCommandType;
 import org.apache.doris.nereids.trees.plans.commands.info.DefaultValue;
 import 
org.apache.doris.nereids.trees.plans.commands.info.DistributionDescriptor;
@@ -472,6 +475,15 @@ import java.util.stream.Collectors;
  */
 @SuppressWarnings({"OptionalUsedAsFieldOrParameterType", 
"OptionalGetWithoutIsPresent"})
 public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> {
+    private final boolean forCreateView;
+
+    public LogicalPlanBuilder() {
+        forCreateView = false;
+    }
+
+    public LogicalPlanBuilder(boolean forCreateView) {
+        this.forCreateView = forCreateView;
+    }
 
     @SuppressWarnings("unchecked")
     protected <T> T typedVisit(ParseTree ctx) {
@@ -1329,11 +1341,16 @@ public class LogicalPlanBuilder extends 
DorisParserBaseVisitor<Object> {
             scanParams = new 
TableScanParams(ctx.optScanParams().funcName.getText(), map);
         }
 
+        MultipartIdentifierContext identifier = ctx.multipartIdentifier();
         TableSample tableSample = ctx.sample() == null ? null : (TableSample) 
visit(ctx.sample());
-        LogicalPlan checkedRelation = 
LogicalPlanBuilderAssistant.withCheckPolicy(
+        UnboundRelation relation = forCreateView ? new 
UnboundRelation(StatementScopeIdGenerator.newRelationId(),
+                tableId, partitionNames, isTempPart, tabletIdLists, 
relationHints,
+                Optional.ofNullable(tableSample), indexName, scanParams,
+                Optional.of(Pair.of(identifier.start.getStartIndex(), 
identifier.stop.getStopIndex()))) :
                 new UnboundRelation(StatementScopeIdGenerator.newRelationId(),
                         tableId, partitionNames, isTempPart, tabletIdLists, 
relationHints,
-                        Optional.ofNullable(tableSample), indexName, 
scanParams));
+                        Optional.ofNullable(tableSample), indexName, 
scanParams);
+        LogicalPlan checkedRelation = 
LogicalPlanBuilderAssistant.withCheckPolicy(relation);
         LogicalPlan plan = withTableAlias(checkedRelation, ctx.tableAlias());
         for (LateralViewContext lateralViewContext : ctx.lateralView()) {
             plan = withGenerate(plan, lateralViewContext);
@@ -1382,7 +1399,9 @@ public class LogicalPlanBuilder extends 
DorisParserBaseVisitor<Object> {
             } else {
                 target = ImmutableList.of();
             }
-            return new UnboundStar(target);
+            return forCreateView
+                    ? new UnboundStar(target, 
Optional.of(Pair.of(ctx.start.getStartIndex(), ctx.stop.getStopIndex())))
+                    : new UnboundStar(target);
         });
     }
 
@@ -2413,6 +2432,19 @@ public class LogicalPlanBuilder extends 
DorisParserBaseVisitor<Object> {
      * create table parsing
      * 
********************************************************************************************
 */
 
+    @Override
+    public LogicalPlan visitCreateView(CreateViewContext ctx) {
+        List<String> nameParts = visitMultipartIdentifier(ctx.name);
+        String comment = ctx.STRING_LITERAL() == null ? "" : 
LogicalPlanBuilderAssistant.escapeBackSlash(
+                ctx.STRING_LITERAL().getText().substring(1, 
ctx.STRING_LITERAL().getText().length() - 1));
+        LogicalPlan logicalPlan = visitQuery(ctx.query());
+        String querySql = getOriginSql(ctx.query());
+        CreateViewInfo info = new CreateViewInfo(ctx.EXISTS() != null, new 
TableNameInfo(nameParts),
+                comment, logicalPlan, querySql,
+                ctx.cols == null ? Lists.newArrayList() : 
visitSimpleColumnDefs(ctx.cols));
+        return new CreateViewCommand(info);
+    }
+
     @Override
     public LogicalPlan visitCreateTable(CreateTableContext ctx) {
         String ctlName = null;
@@ -2859,8 +2891,11 @@ public class LogicalPlanBuilder extends 
DorisParserBaseVisitor<Object> {
                     if 
(!expressions.stream().allMatch(UnboundSlot.class::isInstance)) {
                         throw new ParseException("only column name is 
supported in except clause", selectColumnCtx);
                     }
-                    project = new LogicalProject<>(ImmutableList.of(new 
UnboundStar(ImmutableList.of())),
-                        expressions, isDistinct, aggregate);
+                    UnboundStar star = forCreateView ? new 
UnboundStar(ImmutableList.of(),
+                            
Optional.of(Pair.of(selectColumnCtx.start.getStartIndex(),
+                                    selectColumnCtx.stop.getStopIndex())))
+                            : new UnboundStar(ImmutableList.of());
+                    project = new LogicalProject<>(ImmutableList.of(star), 
expressions, isDistinct, aggregate);
                 } else {
                     List<NamedExpression> projects = 
getNamedExpressions(selectColumnCtx.namedExpressionSeq());
                     project = new LogicalProject<>(projects, 
ImmutableList.of(), isDistinct, aggregate);
@@ -3039,8 +3074,10 @@ public class LogicalPlanBuilder extends 
DorisParserBaseVisitor<Object> {
                     if 
(!expressions.stream().allMatch(UnboundSlot.class::isInstance)) {
                         throw new ParseException("only column name is 
supported in except clause", selectCtx);
                     }
-                    return new LogicalProject<>(ImmutableList.of(new 
UnboundStar(ImmutableList.of())),
-                            expressions, isDistinct, input);
+                    UnboundStar star = forCreateView ? new 
UnboundStar(ImmutableList.of(),
+                            
Optional.of(Pair.of(selectCtx.start.getStartIndex(), 
selectCtx.stop.getStopIndex()))) :
+                            new UnboundStar(ImmutableList.of());
+                    return new LogicalProject<>(ImmutableList.of(star), 
expressions, isDistinct, input);
                 } else {
                     List<NamedExpression> projects = 
getNamedExpressions(selectCtx.namedExpressionSeq());
                     return new LogicalProject<>(projects, 
Collections.emptyList(), isDistinct, input);
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/NereidsParser.java 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/NereidsParser.java
index 0ee3f5d068f..da6881a4905 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/NereidsParser.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/NereidsParser.java
@@ -164,7 +164,20 @@ public class NereidsParser {
         return (T) realLogicalPlanBuilder.visit(tree);
     }
 
-    private ParserRuleContext toAst(String sql, Function<DorisParser, 
ParserRuleContext> parseFunction) {
+    public LogicalPlan parseForCreateView(String sql) {
+        return parseForCreateViewInternal(sql, null, 
DorisParser::singleStatement);
+    }
+
+    private <T> T parseForCreateViewInternal(String sql, @Nullable 
LogicalPlanBuilder logicalPlanBuilder,
+            Function<DorisParser, ParserRuleContext> parseFunction) {
+        ParserRuleContext tree = toAst(sql, parseFunction);
+        LogicalPlanBuilder realLogicalPlanBuilder = logicalPlanBuilder == null
+                ? new LogicalPlanBuilder(true) : logicalPlanBuilder;
+        return (T) realLogicalPlanBuilder.visit(tree);
+    }
+
+    /** toAst */
+    public static ParserRuleContext toAst(String sql, Function<DorisParser, 
ParserRuleContext> parseFunction) {
         DorisLexer lexer = new DorisLexer(new 
CaseInsensitiveStream(CharStreams.fromString(sql)));
         CommonTokenStream tokenStream = new CommonTokenStream(lexer);
         DorisParser parser = new DorisParser(tokenStream);
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindExpression.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindExpression.java
index 1d0fd3ed632..e20d3e8d551 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindExpression.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindExpression.java
@@ -28,6 +28,7 @@ import org.apache.doris.nereids.analyzer.UnboundFunction;
 import org.apache.doris.nereids.analyzer.UnboundOneRowRelation;
 import org.apache.doris.nereids.analyzer.UnboundResultSink;
 import org.apache.doris.nereids.analyzer.UnboundSlot;
+import org.apache.doris.nereids.analyzer.UnboundStar;
 import org.apache.doris.nereids.analyzer.UnboundTVFRelation;
 import org.apache.doris.nereids.exceptions.AnalysisException;
 import org.apache.doris.nereids.parser.LogicalPlanBuilder;
@@ -571,6 +572,7 @@ public class BindExpression implements AnalysisRuleFactory {
                 () -> analyzer.analyzeToSet(project.getExcepts()));
 
         Builder<NamedExpression> boundProjections = 
ImmutableList.builderWithExpectedSize(project.arity());
+        StatementContext statementContext = ctx.statementContext;
         for (Expression expression : project.getProjects()) {
             Expression expr = analyzer.analyze(expression);
             if (!(expr instanceof BoundStar)) {
@@ -582,6 +584,13 @@ public class BindExpression implements AnalysisRuleFactory 
{
                     slots = Utils.filterImmutableList(slots, slot -> 
!boundExcepts.get().contains(slot));
                 }
                 boundProjections.addAll(slots);
+
+                // for create view stmt expand star
+                List<Slot> slotsForLambda = slots;
+                UnboundStar unboundStar = (UnboundStar) expression;
+                unboundStar.getIndexInSqlString().ifPresent(pair ->
+                        statementContext.addIndexInSqlToString(pair, 
toSqlWithBackquote(slotsForLambda))
+                );
             }
         }
         return project.withProjects(boundProjections.build());
@@ -975,6 +984,11 @@ public class BindExpression implements AnalysisRuleFactory 
{
         List<? extends Expression> bindSlot(ExpressionAnalyzer analyzer, 
UnboundSlot unboundSlot);
     }
 
+    public String toSqlWithBackquote(List<Slot> slots) {
+        return slots.stream().map(slot -> ((SlotReference) 
slot).getQualifiedNameWithBackquote())
+                .collect(Collectors.joining(", "));
+    }
+
     private boolean hasAggregateFunction(Expression expression, 
FunctionRegistry functionRegistry) {
         return expression.anyMatch(expr -> {
             if (expr instanceof AggregateFunction) {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindRelation.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindRelation.java
index 2a407a00b1b..397d53b78a2 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindRelation.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/BindRelation.java
@@ -31,6 +31,7 @@ import org.apache.doris.datasource.es.EsExternalTable;
 import org.apache.doris.datasource.hive.HMSExternalTable;
 import org.apache.doris.nereids.CTEContext;
 import org.apache.doris.nereids.CascadesContext;
+import org.apache.doris.nereids.StatementContext;
 import org.apache.doris.nereids.analyzer.Unbound;
 import org.apache.doris.nereids.analyzer.UnboundRelation;
 import org.apache.doris.nereids.analyzer.UnboundResultSink;
@@ -62,6 +63,7 @@ import 
org.apache.doris.nereids.trees.plans.logical.LogicalSubQueryAlias;
 import org.apache.doris.nereids.trees.plans.logical.LogicalTestScan;
 import org.apache.doris.nereids.trees.plans.logical.LogicalView;
 import org.apache.doris.nereids.util.RelationUtil;
+import org.apache.doris.nereids.util.Utils;
 import org.apache.doris.qe.ConnectContext;
 
 import com.google.common.base.Preconditions;
@@ -239,6 +241,12 @@ public class BindRelation extends OneAnalysisRuleFactory {
 
     private LogicalPlan getLogicalPlan(TableIf table, UnboundRelation 
unboundRelation,
                                                List<String> tableQualifier, 
CascadesContext cascadesContext) {
+        // for create view stmt replace tablename to ctl.db.tablename
+        unboundRelation.getIndexInSqlString().ifPresent(pair -> {
+            StatementContext statementContext = 
cascadesContext.getStatementContext();
+            statementContext.addIndexInSqlToString(pair,
+                    Utils.qualifiedNameWithBackquote(tableQualifier));
+        });
         List<String> qualifierWithoutTableName = Lists.newArrayList();
         qualifierWithoutTableName.addAll(tableQualifier.subList(0, 
tableQualifier.size() - 1));
         switch (table.getType()) {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/SlotReference.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/SlotReference.java
index 76083645512..3d11a7d011d 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/SlotReference.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/SlotReference.java
@@ -19,6 +19,7 @@ package org.apache.doris.nereids.trees.expressions;
 
 import org.apache.doris.catalog.Column;
 import org.apache.doris.catalog.TableIf;
+import org.apache.doris.nereids.exceptions.UnboundException;
 import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
 import org.apache.doris.nereids.trees.plans.algebra.Relation;
 import org.apache.doris.nereids.types.DataType;
@@ -296,4 +297,8 @@ public class SlotReference extends Slot {
                     internalName.isPresent() ? internalName : 
Optional.of(name.get()));
         }
     }
+
+    public String getQualifiedNameWithBackquote() throws UnboundException {
+        return Utils.qualifiedNameWithBackquote(getQualifier(), getName());
+    }
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/WindowFrame.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/WindowFrame.java
index 90449ed0f86..5cbb93ce374 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/WindowFrame.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/WindowFrame.java
@@ -99,7 +99,7 @@ public class WindowFrame extends Expression implements 
PropagateNullable, LeafEx
         StringBuilder sb = new StringBuilder();
         sb.append(frameUnits + " ");
         if (rightBoundary != null) {
-            sb.append("BETWEEN " + leftBoundary + " AND " + rightBoundary);
+            sb.append("BETWEEN " + leftBoundary.toSql() + " AND " + 
rightBoundary.toSql());
         } else {
             sb.append(leftBoundary);
         }
@@ -215,6 +215,32 @@ public class WindowFrame extends Expression implements 
PropagateNullable, LeafEx
             return sb.toString();
         }
 
+        /** toSql*/
+        public String toSql() {
+            StringBuilder sb = new StringBuilder();
+            boundOffset.ifPresent(value -> sb.append(value + " "));
+            switch (frameBoundType) {
+                case UNBOUNDED_PRECEDING:
+                    sb.append("UNBOUNDED PRECEDING");
+                    break;
+                case UNBOUNDED_FOLLOWING:
+                    sb.append("UNBOUNDED FOLLOWING");
+                    break;
+                case CURRENT_ROW:
+                    sb.append("CURRENT ROW");
+                    break;
+                case PRECEDING:
+                    sb.append("PRECEDING");
+                    break;
+                case FOLLOWING:
+                    sb.append("FOLLOWING");
+                    break;
+                default:
+                    break;
+            }
+            return sb.toString();
+        }
+
         @Override
         public boolean equals(Object o) {
             if (this == o) {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Lambda.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Lambda.java
index 1d6c725db09..e8261f6391d 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Lambda.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Lambda.java
@@ -132,7 +132,7 @@ public class Lambda extends Expression {
         if (argumentNames.size() > 1) {
             argStr = argumentNames.stream().collect(Collectors.joining(", ", 
"(", ")"));
         }
-        builder.append(String.format("%s -> %s", argStr, 
getLambdaFunction().toString()));
+        builder.append(String.format("%s -> %s", argStr, 
getLambdaFunction().toSql()));
         for (int i = 1; i < getArguments().size(); i++) {
             builder.append(", ").append(getArgument(i).toSql());
         }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanType.java 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanType.java
index 1c493deae03..daab18438b4 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanType.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanType.java
@@ -148,5 +148,6 @@ public enum PlanType {
     CREATE_PROCEDURE_COMMAND,
     DROP_PROCEDURE_COMMAND,
     SHOW_PROCEDURE_COMMAND,
-    SHOW_CREATE_PROCEDURE_COMMAND
+    SHOW_CREATE_PROCEDURE_COMMAND,
+    CREATE_VIEW_COMMAND
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CreateViewCommand.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CreateViewCommand.java
new file mode 100644
index 00000000000..d78308664b5
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CreateViewCommand.java
@@ -0,0 +1,49 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.plans.commands;
+
+import org.apache.doris.analysis.CreateViewStmt;
+import org.apache.doris.catalog.Env;
+import org.apache.doris.nereids.trees.plans.PlanType;
+import org.apache.doris.nereids.trees.plans.commands.info.CreateViewInfo;
+import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor;
+import org.apache.doris.qe.ConnectContext;
+import org.apache.doris.qe.StmtExecutor;
+
+/** CreateViewCommand */
+public class CreateViewCommand extends Command {
+    private final CreateViewInfo createViewInfo;
+
+    public CreateViewCommand(CreateViewInfo createViewInfo) {
+        super(PlanType.CREATE_VIEW_COMMAND);
+        this.createViewInfo = createViewInfo;
+    }
+
+    @Override
+    public void run(ConnectContext ctx, StmtExecutor executor) throws 
Exception {
+        createViewInfo.init(ctx);
+        createViewInfo.validate(ctx);
+        CreateViewStmt createViewStmt = 
createViewInfo.translateToLegacyStmt(ctx);
+        Env.getCurrentEnv().createView(createViewStmt);
+    }
+
+    @Override
+    public <R, C> R accept(PlanVisitor<R, C> visitor, C context) {
+        return visitor.visitCreateViewCommand(this, context);
+    }
+}
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/CreateViewInfo.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/CreateViewInfo.java
new file mode 100644
index 00000000000..632e8846856
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/CreateViewInfo.java
@@ -0,0 +1,329 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.plans.commands.info;
+
+import org.apache.doris.analysis.ColWithComment;
+import org.apache.doris.analysis.CreateViewStmt;
+import org.apache.doris.catalog.Column;
+import org.apache.doris.catalog.Env;
+import org.apache.doris.common.ErrorCode;
+import org.apache.doris.common.ErrorReport;
+import org.apache.doris.common.FeNameFormat;
+import org.apache.doris.common.Pair;
+import org.apache.doris.common.UserException;
+import org.apache.doris.common.util.Util;
+import org.apache.doris.mysql.privilege.PrivPredicate;
+import org.apache.doris.nereids.CascadesContext;
+import org.apache.doris.nereids.DorisParser;
+import org.apache.doris.nereids.DorisParser.NamedExpressionContext;
+import org.apache.doris.nereids.DorisParser.NamedExpressionSeqContext;
+import org.apache.doris.nereids.DorisParserBaseVisitor;
+import org.apache.doris.nereids.NereidsPlanner;
+import org.apache.doris.nereids.StatementContext;
+import org.apache.doris.nereids.analyzer.UnboundResultSink;
+import org.apache.doris.nereids.exceptions.AnalysisException;
+import org.apache.doris.nereids.jobs.executor.AbstractBatchJobExecutor;
+import org.apache.doris.nereids.jobs.rewrite.RewriteJob;
+import org.apache.doris.nereids.parser.NereidsParser;
+import org.apache.doris.nereids.properties.PhysicalProperties;
+import org.apache.doris.nereids.rules.analysis.AnalyzeCTE;
+import org.apache.doris.nereids.rules.analysis.BindExpression;
+import org.apache.doris.nereids.rules.analysis.BindRelation;
+import org.apache.doris.nereids.rules.analysis.CheckPolicy;
+import org.apache.doris.nereids.rules.analysis.EliminateLogicalSelectHint;
+import org.apache.doris.nereids.trees.expressions.Slot;
+import org.apache.doris.nereids.trees.plans.Plan;
+import 
org.apache.doris.nereids.trees.plans.commands.ExplainCommand.ExplainLevel;
+import org.apache.doris.nereids.trees.plans.logical.LogicalCTEAnchor;
+import org.apache.doris.nereids.trees.plans.logical.LogicalCTEProducer;
+import org.apache.doris.nereids.trees.plans.logical.LogicalFileSink;
+import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
+import org.apache.doris.nereids.trees.plans.visitor.DefaultPlanVisitor;
+import org.apache.doris.qe.ConnectContext;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import org.antlr.v4.runtime.ParserRuleContext;
+import org.antlr.v4.runtime.tree.ParseTree;
+import org.antlr.v4.runtime.tree.RuleNode;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * CreateViewInfo
+ */
+public class CreateViewInfo {
+    private final boolean ifNotExists;
+    private final TableNameInfo viewName;
+    private final String comment;
+    private final LogicalPlan logicalQuery;
+    private final String querySql;
+    private final List<SimpleColumnDefinition> simpleColumnDefinitions;
+    private final List<Column> finalCols = Lists.newArrayList();
+    private Plan analyzedPlan;
+
+    /** constructor*/
+    public CreateViewInfo(boolean ifNotExists, TableNameInfo viewName, String 
comment, LogicalPlan logicalQuery,
+            String querySql, List<SimpleColumnDefinition> 
simpleColumnDefinitions) {
+        this.ifNotExists = ifNotExists;
+        this.viewName = viewName;
+        this.comment = comment;
+        if (logicalQuery instanceof LogicalFileSink) {
+            throw new AnalysisException("Not support OUTFILE clause in CREATE 
VIEW statement");
+        }
+        this.logicalQuery = logicalQuery;
+        this.querySql = querySql;
+        this.simpleColumnDefinitions = simpleColumnDefinitions;
+    }
+
+    /** init */
+    public void init(ConnectContext ctx) throws UserException {
+        analyzeAndFillRewriteSqlMap(querySql, ctx);
+        OutermostPlanFinderContext outermostPlanFinderContext = new 
OutermostPlanFinderContext();
+        analyzedPlan.accept(OutermostPlanFinder.INSTANCE, 
outermostPlanFinderContext);
+        List<Slot> outputs = 
outermostPlanFinderContext.outermostPlan.getOutput();
+        createFinalCols(outputs);
+    }
+
+    /**validate*/
+    public void validate(ConnectContext ctx) throws UserException {
+        NereidsPlanner planner = new NereidsPlanner(ctx.getStatementContext());
+        planner.plan(new UnboundResultSink<>(logicalQuery), 
PhysicalProperties.ANY, ExplainLevel.NONE);
+        viewName.analyze(ctx);
+        FeNameFormat.checkTableName(viewName.getTbl());
+        // disallow external catalog
+        Util.prohibitExternalCatalog(viewName.getCtl(), "CreateViewStmt");
+        // check privilege
+        if 
(!Env.getCurrentEnv().getAccessManager().checkTblPriv(ConnectContext.get(), 
viewName.getDb(),
+                viewName.getTbl(), PrivPredicate.CREATE)) {
+            
ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, 
"CREATE");
+        }
+        Set<String> colSets = Sets.newTreeSet(String.CASE_INSENSITIVE_ORDER);
+        for (Column col : finalCols) {
+            if (!colSets.add(col.getName())) {
+                
ErrorReport.reportAnalysisException(ErrorCode.ERR_DUP_FIELDNAME, col.getName());
+            }
+        }
+    }
+
+    /**translateToLegacyStmt*/
+    public CreateViewStmt translateToLegacyStmt(ConnectContext ctx) {
+        List<ColWithComment> cols = Lists.newArrayList();
+        for (SimpleColumnDefinition def : simpleColumnDefinitions) {
+            cols.add(def.translateToColWithComment());
+        }
+        CreateViewStmt createViewStmt = new CreateViewStmt(ifNotExists, 
viewName.transferToTableName(), cols, comment,
+                null);
+        // expand star(*) in project list and replace table name with qualifier
+        String rewrittenSql = 
rewriteSql(ctx.getStatementContext().getIndexInSqlToString());
+
+        // rewrite project alias
+        rewrittenSql = rewriteProjectsToUserDefineAlias(rewrittenSql);
+
+        createViewStmt.setInlineViewDef(rewrittenSql);
+        createViewStmt.setFinalColumns(finalCols);
+        return createViewStmt;
+    }
+
+    private void analyzeAndFillRewriteSqlMap(String sql, ConnectContext ctx) {
+        StatementContext stmtCtx = ctx.getStatementContext();
+        LogicalPlan parsedViewPlan = new 
NereidsParser().parseForCreateView(sql);
+        if (parsedViewPlan instanceof UnboundResultSink) {
+            parsedViewPlan = (LogicalPlan) ((UnboundResultSink<?>) 
parsedViewPlan).child();
+        }
+        CascadesContext viewContextForStar = CascadesContext.initContext(
+                stmtCtx, parsedViewPlan, PhysicalProperties.ANY);
+        AnalyzerForCreateView analyzerForStar = new 
AnalyzerForCreateView(viewContextForStar);
+        analyzerForStar.analyze();
+        analyzedPlan = viewContextForStar.getRewritePlan();
+    }
+
+    private String rewriteSql(Map<Pair<Integer, Integer>, String> 
indexStringSqlMap) {
+        StringBuilder builder = new StringBuilder();
+        int beg = 0;
+        for (Map.Entry<Pair<Integer, Integer>, String> entry : 
indexStringSqlMap.entrySet()) {
+            Pair<Integer, Integer> index = entry.getKey();
+            builder.append(querySql, beg, index.first);
+            builder.append(entry.getValue());
+            beg = index.second + 1;
+        }
+        builder.append(querySql, beg, querySql.length());
+        return builder.toString();
+    }
+
+    private String rewriteProjectsToUserDefineAlias(String resSql) {
+        IndexFinder finder = new IndexFinder();
+        ParserRuleContext tree = NereidsParser.toAst(resSql, 
DorisParser::singleStatement);
+        finder.visit(tree);
+        if (simpleColumnDefinitions.isEmpty()) {
+            return resSql;
+        }
+        List<NamedExpressionContext> namedExpressionContexts = 
finder.getNamedExpressionContexts();
+        StringBuilder replaceWithColsBuilder = new StringBuilder();
+        for (int i = 0; i < namedExpressionContexts.size(); ++i) {
+            NamedExpressionContext namedExpressionContext = 
namedExpressionContexts.get(i);
+            int start = 
namedExpressionContext.expression().start.getStartIndex();
+            int stop = namedExpressionContext.expression().stop.getStopIndex();
+            replaceWithColsBuilder.append(resSql, start, stop + 1);
+            replaceWithColsBuilder.append(" AS `");
+            String escapeBacktick = finalCols.get(i).getName().replace("`", 
"``");
+            replaceWithColsBuilder.append(escapeBacktick);
+            replaceWithColsBuilder.append('`');
+            if (i != namedExpressionContexts.size() - 1) {
+                replaceWithColsBuilder.append(", ");
+            }
+        }
+        String replaceWithCols = replaceWithColsBuilder.toString();
+        return StringUtils.overlay(resSql, replaceWithCols, 
finder.getIndex().first,
+                finder.getIndex().second + 1);
+    }
+
+    private void createFinalCols(List<Slot> outputs) throws 
org.apache.doris.common.AnalysisException {
+        if (simpleColumnDefinitions.isEmpty()) {
+            for (Slot output : outputs) {
+                Column column = new Column(output.getName(), 
output.getDataType().toCatalogDataType());
+                finalCols.add(column);
+            }
+        } else {
+            if (outputs.size() != simpleColumnDefinitions.size()) {
+                
ErrorReport.reportAnalysisException(ErrorCode.ERR_VIEW_WRONG_LIST);
+            }
+            for (int i = 0; i < simpleColumnDefinitions.size(); ++i) {
+                Column column = new 
Column(simpleColumnDefinitions.get(i).getName(),
+                        outputs.get(i).getDataType().toCatalogDataType());
+                column.setComment(simpleColumnDefinitions.get(i).getComment());
+                finalCols.add(column);
+            }
+        }
+    }
+
+    private static class OutermostPlanFinderContext {
+        public Plan outermostPlan = null;
+        public boolean found = false;
+    }
+
+    private static class OutermostPlanFinder extends DefaultPlanVisitor<Void, 
OutermostPlanFinderContext> {
+        public static final OutermostPlanFinder INSTANCE = new 
OutermostPlanFinder();
+
+        @Override
+        public Void visit(Plan plan, OutermostPlanFinderContext ctx) {
+            if (ctx.found) {
+                return null;
+            }
+            ctx.outermostPlan = plan;
+            ctx.found = true;
+            return null;
+        }
+
+        @Override
+        public Void visitLogicalCTEAnchor(LogicalCTEAnchor<? extends Plan, ? 
extends Plan> cteAnchor,
+                OutermostPlanFinderContext ctx) {
+            if (ctx.found) {
+                return null;
+            }
+            return super.visit(cteAnchor, ctx);
+        }
+
+        @Override
+        public Void visitLogicalCTEProducer(LogicalCTEProducer<? extends Plan> 
cteProducer,
+                OutermostPlanFinderContext ctx) {
+            return null;
+        }
+    }
+
+    /** traverse ast to find the outermost project list location information 
in sql*/
+    private static class IndexFinder extends DorisParserBaseVisitor<Void> {
+        private boolean found = false;
+        private int startIndex;
+        private int stopIndex;
+        private List<NamedExpressionContext> namedExpressionContexts = 
Lists.newArrayList();
+
+        @Override
+        public Void visitChildren(RuleNode node) {
+            if (found) {
+                return null;
+            }
+            int n = node.getChildCount();
+            for (int i = 0; i < n; ++i) {
+                ParseTree c = node.getChild(i);
+                c.accept(this);
+            }
+            return null;
+        }
+
+        @Override
+        public Void visitCte(DorisParser.CteContext ctx) {
+            return null;
+        }
+
+        @Override
+        public Void 
visitSelectColumnClause(DorisParser.SelectColumnClauseContext ctx) {
+            if (found) {
+                return null;
+            }
+            startIndex = ctx.getStart().getStartIndex();
+            stopIndex = ctx.getStop().getStopIndex();
+            found = true;
+
+            NamedExpressionSeqContext namedExpressionSeqContext = 
ctx.namedExpressionSeq();
+            namedExpressionContexts = 
namedExpressionSeqContext.namedExpression();
+            return null;
+        }
+
+        public Pair<Integer, Integer> getIndex() {
+            return Pair.of(startIndex, stopIndex);
+        }
+
+        public List<NamedExpressionContext> getNamedExpressionContexts() {
+            return namedExpressionContexts;
+        }
+    }
+
+    private static class AnalyzerForCreateView extends 
AbstractBatchJobExecutor {
+        private final List<RewriteJob> jobs;
+
+        public AnalyzerForCreateView(CascadesContext cascadesContext) {
+            super(cascadesContext);
+            jobs = buildAnalyzeViewJobsForStar();
+        }
+
+        public void analyze() {
+            execute();
+        }
+
+        @Override
+        public List<RewriteJob> getJobs() {
+            return jobs;
+        }
+
+        private static List<RewriteJob> buildAnalyzeViewJobsForStar() {
+            return jobs(
+                    topDown(new EliminateLogicalSelectHint()),
+                    topDown(new AnalyzeCTE()),
+                    bottomUp(
+                            new BindRelation(),
+                            new CheckPolicy(),
+                            new BindExpression()
+                    )
+            );
+        }
+    }
+}
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/SimpleColumnDefinition.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/SimpleColumnDefinition.java
index 51080bf45d2..e4e7f2013cb 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/SimpleColumnDefinition.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/SimpleColumnDefinition.java
@@ -17,6 +17,8 @@
 
 package org.apache.doris.nereids.trees.plans.commands.info;
 
+import org.apache.doris.analysis.ColWithComment;
+
 /**
  * column def for mv
  */
@@ -39,4 +41,8 @@ public class SimpleColumnDefinition {
     public String getComment() {
         return comment;
     }
+
+    public ColWithComment translateToColWithComment() {
+        return new ColWithComment(name, comment);
+    }
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/visitor/CommandVisitor.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/visitor/CommandVisitor.java
index 6bcc41e39e4..527ccb1ffe0 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/visitor/CommandVisitor.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/visitor/CommandVisitor.java
@@ -26,6 +26,7 @@ import 
org.apache.doris.nereids.trees.plans.commands.CreateMTMVCommand;
 import org.apache.doris.nereids.trees.plans.commands.CreatePolicyCommand;
 import org.apache.doris.nereids.trees.plans.commands.CreateProcedureCommand;
 import org.apache.doris.nereids.trees.plans.commands.CreateTableCommand;
+import org.apache.doris.nereids.trees.plans.commands.CreateViewCommand;
 import org.apache.doris.nereids.trees.plans.commands.DeleteFromCommand;
 import org.apache.doris.nereids.trees.plans.commands.DeleteFromUsingCommand;
 import org.apache.doris.nereids.trees.plans.commands.DropConstraintCommand;
@@ -156,4 +157,8 @@ public interface CommandVisitor<R, C> {
     default R visitShowCreateProcedureCommand(ShowCreateProcedureCommand 
showCreateProcedureCommand, C context) {
         return visitCommand(showCreateProcedureCommand, context);
     }
+
+    default R visitCreateViewCommand(CreateViewCommand createViewCommand, C 
context) {
+        return visitCommand(createViewCommand, context);
+    }
 }
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 c28b18e697d..852e148ef1d 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
@@ -128,6 +128,23 @@ public class Utils {
         return StringUtils.join(qualifiedNameParts(qualifier, name), ".");
     }
 
+    /** get qualified name with Backtick */
+    public static String qualifiedNameWithBackquote(List<String> qualifiers, 
String name) {
+        List<String> fullName = new ArrayList<>(qualifiers);
+        fullName.add(name);
+        return qualifiedNameWithBackquote(fullName);
+    }
+
+    /** get qualified name with Backtick */
+    public static String qualifiedNameWithBackquote(List<String> qualifiers) {
+        List<String> qualifierWithBackquote = 
Lists.newArrayListWithCapacity(qualifiers.size());
+        for (String qualifier : qualifiers) {
+            String escapeQualifier = qualifier.replace("`", "``");
+            qualifierWithBackquote.add('`' + escapeQualifier + '`');
+        }
+        return StringUtils.join(qualifierWithBackquote, ".");
+    }
+
     /**
      * Get sql string for plan.
      *
diff --git a/regression-test/data/ddl_p0/test_create_view_nereids.out 
b/regression-test/data/ddl_p0/test_create_view_nereids.out
new file mode 100644
index 00000000000..1fda4f63f57
--- /dev/null
+++ b/regression-test/data/ddl_p0/test_create_view_nereids.out
@@ -0,0 +1,228 @@
+-- This file is automatically generated. You should know what you did if you 
want to edit this
+-- !test_view_1 --
+1      [1, 2, 3]
+2      [10, -2, 8]
+3      [-1, 20, 0]
+
+-- !test_view_2 --
+1      [1, 2, 3]       [1, 1, 1]
+2      [10, -2, 8]     [1, 0, 1]
+3      [-1, 20, 0]     [0, 1, 0]
+
+-- !test_view_3 --
+1      [1, 2, 3]       [1, 2, 3]       [1, 2, 3]
+2      [10, -2, 8]     [10, 8] [10, 8]
+3      [-1, 20, 0]     [20]    [20]
+
+-- !test_view_4 --
+1      [1, 2, 3]       [1, 2, 3]       [1, 2, 3]
+2      [10, -2, 8]     [10, 8] [10, 8]
+3      [-1, 20, 0]     [20]    [20]
+
+-- !test_view_5 --
+1      [1, 2, 3]       [1, 1, 1]
+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\n      error_code, \n      1, 
\n      'string', \n      now(), \n      dayofyear(op_time), \n      cast 
(source AS BIGINT), \n      min(`timestamp`) OVER (\n        ORDER BY \n        
  op_time DESC ROWS BETWEEN UNBOUNDED PRECEDING\n          AND 1 FOLLOWING\n    
  ), \n      1 > 2,\n      2 + 3,\n      1 IN (1, 2, 3, 4), \n      remark LIKE 
'%like', \n      CASE WHEN remark = 's' THEN 1 ELSE 2 END,\n      TRUE | FALSE 
\n    FROM \n      `inte [...]
+
+-- !test_with_as --
+1      1       2
+1      1       4
+1      3       6
+2      1       3
+2      1       4
+2      1       7
+2      3       5
+2      3       9
+2      4       2
+3      2       8
+3      5       \N
+3      5       6
+3      5       6
+3      5       8
+4      5       6
+6      \N      6
+6      7       1
+
+-- !test_with_as_sql --
+test_view_with_as      CREATE VIEW `test_view_with_as` COMMENT 'VIEW' AS (\n   
         with t1 as (select 
`internal`.`regression_test_ddl_p0`.`mal_test_view`.`pk`, 
`internal`.`regression_test_ddl_p0`.`mal_test_view`.`a`, 
`internal`.`regression_test_ddl_p0`.`mal_test_view`.`b` from 
`internal`.`regression_test_ddl_p0`.`mal_test_view`),  t2 as (select 
`internal`.`regression_test_ddl_p0`.`mal_test_view`.`pk`, 
`internal`.`regression_test_ddl_p0`.`mal_test_view`.`a`, 
`internal`.`regression_test_dd [...]
+
+-- !test_union --
+1      1       2
+1      1       2
+1      1       4
+1      1       4
+1      3       6
+1      3       6
+2      1       3
+2      1       3
+2      1       4
+2      1       4
+2      1       7
+2      1       7
+2      3       5
+2      3       5
+2      3       9
+2      3       9
+2      4       2
+2      4       2
+3      2       8
+3      2       8
+3      5       \N
+3      5       \N
+3      5       6
+3      5       6
+3      5       6
+3      5       6
+3      5       8
+3      5       8
+4      5       6
+4      5       6
+6      \N      6
+6      \N      6
+6      7       1
+6      7       1
+
+-- !test_union_sql --
+test_view_union        CREATE VIEW `test_view_union` COMMENT 'VIEW' AS (select 
`internal`.`regression_test_ddl_p0`.`mal_test_view`.`pk` AS `c1`, 
`internal`.`regression_test_ddl_p0`.`mal_test_view`.`a` AS `c2`, 
`internal`.`regression_test_ddl_p0`.`mal_test_view`.`b` AS `c3` from 
`internal`.`regression_test_ddl_p0`.`mal_test_view` Union all SELECT 
`internal`.`regression_test_ddl_p0`.`mal_test_view`.`pk`, 
`internal`.`regression_test_ddl_p0`.`mal_test_view`.`a`, 
`internal`.`regression_test_ddl_p0`. [...]
+
+-- !test_count_star --
+17
+
+-- !test_count_star_sql --
+test_view_count_star   CREATE VIEW `test_view_count_star` COMMENT 'VIEW' AS 
(select count(*) AS `c1` from 
`internal`.`regression_test_ddl_p0`.`mal_test_view` having count(*) > 0);    
utf8mb4 utf8mb4_0900_bin
+
+-- !test_expression --
+\N     \N      6
+2      4       2
+2      4       3
+2      4       4
+2      4       4
+2      4       7
+3      5       8
+4      6       5
+4      6       6
+4      6       9
+5      7       2
+6      8       \N
+6      8       6
+6      8       6
+6      8       6
+6      8       8
+8      10      1
+
+-- !test_expression_sql --
+test_view_expression   CREATE VIEW `test_view_expression` COMMENT 'VIEW' AS 
(select a+1 AS `c1`, abs(a)+2+1 AS `c2`, cast(b as varchar(10)) AS `c3` from 
`internal`.`regression_test_ddl_p0`.`mal_test_view`); utf8mb4 utf8mb4_0900_bin
+
+-- !test_alias --
+\N     \N      6
+2      4       2
+2      4       3
+2      4       4
+2      4       4
+2      4       7
+3      5       8
+4      6       5
+4      6       6
+4      6       9
+5      7       2
+6      8       \N
+6      8       6
+6      8       6
+6      8       6
+6      8       8
+8      10      1
+
+-- !test_alias_sql --
+test_view_alias        CREATE VIEW `test_view_alias` COMMENT 'VIEW' AS (\n     
   select c8 AS `c1`, c2 AS `c2`, c1 AS `c3` from (select a+1 c8,abs(a)+2+1 as 
c2, cast(b as varchar(10)) as c1 from 
`internal`.`regression_test_ddl_p0`.`mal_test_view`) t);   utf8mb4 
utf8mb4_0900_bin
+
+-- !test_star_except --
+\N     6
+1      2
+1      3
+1      4
+1      4
+1      7
+2      8
+3      5
+3      6
+3      9
+4      2
+5      \N
+5      6
+5      6
+5      6
+5      8
+7      1
+
+-- !test_star_except_sql --
+test_view_star_except  CREATE VIEW `test_view_star_except` COMMENT 'VIEW' AS 
select `internal`.`regression_test_ddl_p0`.`mal_test_view`.`a`, 
`internal`.`regression_test_ddl_p0`.`mal_test_view`.`b` from 
`internal`.`regression_test_ddl_p0`.`mal_test_view`; utf8mb4 utf8mb4_0900_bin
+
+-- !test_create_view_from_view --
+1      1       2
+1      1       4
+1      3       6
+2      1       3
+2      1       4
+2      1       7
+2      3       5
+2      3       9
+2      4       2
+3      2       8
+3      5       \N
+3      5       6
+3      5       6
+3      5       8
+4      5       6
+6      \N      6
+6      7       1
+
+-- !test_create_view_from_view_sql --
+test_view_from_view    CREATE VIEW `test_view_from_view` COMMENT 'VIEW' AS 
select `internal`.`regression_test_ddl_p0`.`test_view_with_as`.`pk` AS `c1`, 
`internal`.`regression_test_ddl_p0`.`test_view_with_as`.`a` AS `c2`, 
`internal`.`regression_test_ddl_p0`.`test_view_with_as`.`b` AS `c3` from 
`internal`.`regression_test_ddl_p0`.`test_view_with_as`; utf8mb4 
utf8mb4_0900_bin
+
+-- !test_backquote_in_view_define --
+\N     6
+1      2
+1      3
+1      4
+1      4
+1      7
+2      8
+3      5
+3      6
+3      9
+4      2
+5      \N
+5      6
+5      6
+5      6
+5      8
+7      1
+
+-- !test_backquote_in_view_define_sql --
+test_backquote_in_view_define  CREATE VIEW `test_backquote_in_view_define` 
COMMENT 'VIEW' AS select a AS `ab``c`, b AS `c2` from 
`internal`.`regression_test_ddl_p0`.`mal_test_view`;  utf8mb4 utf8mb4_0900_bin
+
+-- !test_backquote_in_table_alias --
+\N     6
+1      2
+1      3
+1      4
+1      4
+1      7
+2      8
+3      5
+3      6
+3      9
+4      2
+5      \N
+5      6
+5      6
+5      6
+5      8
+7      1
+
+-- !test_backquote_in_table_alias_sql --
+test_backquote_in_table_alias  CREATE VIEW `test_backquote_in_table_alias` 
COMMENT 'VIEW' AS select `ab``c`.`a` AS `c1`, `ab``c`.`b` AS `c2` from (select 
a,b from `internal`.`regression_test_ddl_p0`.`mal_test_view`) `ab``c`;       
utf8mb4 utf8mb4_0900_bin
+
diff --git 
a/regression-test/data/show_p0/test_show_create_table_and_views_nereids.out 
b/regression-test/data/show_p0/test_show_create_table_and_views_nereids.out
new file mode 100644
index 00000000000..3a5728d3d9e
--- /dev/null
+++ b/regression-test/data/show_p0/test_show_create_table_and_views_nereids.out
@@ -0,0 +1,46 @@
+-- This file is automatically generated. You should know what you did if you 
want to edit this
+-- !show --
+show_create_table_and_views_nereids_table      CREATE TABLE 
`show_create_table_and_views_nereids_table` (\n  `user_id` LARGEINT NOT NULL,\n 
 `good_id` LARGEINT NOT NULL,\n  `cost` BIGINT SUM NULL DEFAULT "0"\n) 
ENGINE=OLAP\nAGGREGATE KEY(`user_id`, `good_id`)\nCOMMENT 'OLAP'\nPARTITION BY 
RANGE(`good_id`)\n(PARTITION p1 VALUES 
[("-170141183460469231731687303715884105728"), ("100")),\nPARTITION p2 VALUES 
[("100"), ("200")),\nPARTITION p3 VALUES [("200"), ("300")),\nPARTITION p4 
VALUES [("300") [...]
+
+-- !select --
+1      1       30
+1      2       5
+1      3       10
+1      300     2
+2      1       100
+2      2       10
+2      3       44
+2      200     1111
+3      1       10
+3      2       1
+23     900     1
+100    100     1
+200    20      1
+300    20      1
+
+-- !select --
+1      5
+2      10
+3      1
+
+-- !show --
+show_create_table_and_views_nereids_view       CREATE VIEW 
`show_create_table_and_views_nereids_view` COMMENT 'VIEW' AS SELECT user_id AS 
`user_id`, cost AS `cost` FROM 
`internal`.`show_create_table_and_views_nereids_db`.`show_create_table_and_views_nereids_table`\n
        WHERE good_id = 2;   utf8mb4 utf8mb4_0900_bin
+
+-- !select --
+1      47
+2      1265
+3      11
+23     1
+100    1
+200    1
+300    1
+
+-- !show --
+show_create_table_and_views_nereids_table      CREATE TABLE 
`show_create_table_and_views_nereids_table` (\n  `user_id` LARGEINT NOT NULL,\n 
 `good_id` LARGEINT NOT NULL,\n  `cost` BIGINT SUM NULL DEFAULT "0"\n) 
ENGINE=OLAP\nAGGREGATE KEY(`user_id`, `good_id`)\nCOMMENT 'OLAP'\nPARTITION BY 
RANGE(`good_id`)\n(PARTITION p1 VALUES 
[("-170141183460469231731687303715884105728"), ("100")),\nPARTITION p2 VALUES 
[("100"), ("200")),\nPARTITION p3 VALUES [("200"), ("300")),\nPARTITION p4 
VALUES [("300") [...]
+
+-- !show --
+show_create_table_and_views_nereids_like       CREATE TABLE 
`show_create_table_and_views_nereids_like` (\n  `user_id` LARGEINT NOT NULL,\n  
`good_id` LARGEINT NOT NULL,\n  `cost` BIGINT SUM NULL DEFAULT "0"\n) 
ENGINE=OLAP\nAGGREGATE KEY(`user_id`, `good_id`)\nCOMMENT 'OLAP'\nPARTITION BY 
RANGE(`good_id`)\n(PARTITION p1 VALUES 
[("-170141183460469231731687303715884105728"), ("100")),\nPARTITION p2 VALUES 
[("100"), ("200")),\nPARTITION p3 VALUES [("200"), ("300")),\nPARTITION p4 
VALUES [("300"),  [...]
+
+-- !show --
+show_create_table_and_views_nereids_like_with_rollup   CREATE TABLE 
`show_create_table_and_views_nereids_like_with_rollup` (\n  `user_id` LARGEINT 
NOT NULL,\n  `good_id` LARGEINT NOT NULL,\n  `cost` BIGINT SUM NULL DEFAULT 
"0"\n) ENGINE=OLAP\nAGGREGATE KEY(`user_id`, `good_id`)\nCOMMENT 
'OLAP'\nPARTITION BY RANGE(`good_id`)\n(PARTITION p1 VALUES 
[("-170141183460469231731687303715884105728"), ("100")),\nPARTITION p2 VALUES 
[("100"), ("200")),\nPARTITION p3 VALUES [("200"), ("300")),\nPARTIT [...]
+
diff --git a/regression-test/suites/ddl_p0/test_create_view.groovy 
b/regression-test/suites/ddl_p0/test_create_view.groovy
index 6020aa31050..e66798e50bb 100644
--- a/regression-test/suites/ddl_p0/test_create_view.groovy
+++ b/regression-test/suites/ddl_p0/test_create_view.groovy
@@ -16,7 +16,7 @@
 // under the License.
 
 suite("test_create_view") {
-
+    sql "SET enable_nereids_planner=false;"
     sql """DROP TABLE IF EXISTS count_distinct"""
     sql """
         CREATE TABLE IF NOT EXISTS count_distinct
@@ -42,6 +42,7 @@ suite("test_create_view") {
         "dynamic_partition.buckets" = "3"
         );
     """
+    sql "drop view if exists test_count_distinct"
     sql """
     CREATE VIEW IF NOT EXISTS test_count_distinct
     (
@@ -203,4 +204,4 @@ suite("test_create_view") {
       view_column_name_test
     """
     qt_test_view_6 """ SHOW VIEW FROM view_column_name_test;"""
-}
+}
\ No newline at end of file
diff --git a/regression-test/suites/ddl_p0/test_create_view_nereids.groovy 
b/regression-test/suites/ddl_p0/test_create_view_nereids.groovy
new file mode 100644
index 00000000000..48885a47fd1
--- /dev/null
+++ b/regression-test/suites/ddl_p0/test_create_view_nereids.groovy
@@ -0,0 +1,280 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+suite("test_create_view_nereids") {
+    sql "SET enable_nereids_planner=true;"
+    sql "SET enable_fallback_to_original_planner=false;"
+    sql """DROP TABLE IF EXISTS count_distinct_nereids"""
+    sql """
+        CREATE TABLE IF NOT EXISTS count_distinct_nereids
+        (
+            RQ DATE NOT NULL  COMMENT "日期",
+            v1 VARCHAR(100) NOT NULL  COMMENT "字段1",
+            v2 VARCHAR(100) NOT NULL  COMMENT "字段2",
+            v3 VARCHAR(100) REPLACE_IF_NOT_NULL  COMMENT "字段3"
+        )
+        AGGREGATE KEY(RQ,v1,v2)
+        PARTITION BY RANGE(RQ)
+        (
+            PARTITION p20220908 VALUES LESS THAN ('2022-09-09')
+        )
+        DISTRIBUTED BY HASH(v1,v2) BUCKETS 3
+        PROPERTIES(
+        "replication_num" = "1",
+        "dynamic_partition.enable" = "true",
+        "dynamic_partition.time_unit" = "DAY",
+        "dynamic_partition.start" = "-3",
+        "dynamic_partition.end" = "3",
+        "dynamic_partition.prefix" = "p",
+        "dynamic_partition.buckets" = "3"
+        );
+    """
+    sql """
+    CREATE VIEW IF NOT EXISTS test_count_distinct_nereids
+    (
+        RQ comment "日期",
+        v1 comment "v1",
+        v2 comment "v2",
+        v3 comment "v3"
+    )
+    AS
+    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_nereids
+        group by RQ
+    ) aa
+    LEFT JOIN
+    (
+        select RQ, max(v3) as v3
+        from count_distinct_nereids
+        group by RQ
+    ) bb
+    on aa.RQ = bb.RQ;
+    """
+
+    sql """select * from test_count_distinct_nereids"""
+    sql """DROP VIEW IF EXISTS test_count_distinct_nereids"""
+    sql """DROP TABLE IF EXISTS count_distinct_nereids"""
+
+    sql """DROP TABLE IF EXISTS test_view_t1"""
+    sql """
+    CREATE TABLE `test_view_t1` (
+        k1 int,
+        k2 date,
+        v1 int
+        ) ENGINE=OLAP
+        UNIQUE KEY(`k1`,`k2`)
+        COMMENT '测试'
+        PARTITION BY RANGE(k2) (
+        PARTITION p1 VALUES [('2023-07-01'), ('2023-07-10')),
+        PARTITION p2 VALUES [('2023-07-11'), ('2023-07-20'))
+        )
+        DISTRIBUTED BY HASH(`k1`) BUCKETS 3
+        PROPERTIES (
+            "replication_allocation" = "tag.location.default: 1"
+        );"""
+    sql """DROP TABLE IF EXISTS test_view_t2"""
+    sql """
+    CREATE TABLE `test_view_t2` (
+        k1 int,
+        k2 date,
+        v1 int
+        ) ENGINE=OLAP
+        UNIQUE KEY(`k1`,`k2`)
+        COMMENT '测试'
+        PARTITION BY RANGE(k2) (
+        PARTITION p1 VALUES [('2023-07-01'), ('2023-07-05')),
+        PARTITION p2 VALUES [('2023-07-05'), ('2023-07-15'))
+        )
+        DISTRIBUTED BY HASH(`k1`) BUCKETS 3
+        PROPERTIES (
+            "replication_allocation" = "tag.location.default: 1"
+        ); """
+    sql """
+        CREATE VIEW IF NOT EXISTS my_view_nereids AS
+        SELECT test_view_t1.* FROM test_view_t1 PARTITION(p1) JOIN 
test_view_t2 PARTITION(p2) ON test_view_t1.k1 = test_view_t2.k1; """
+    sql """SELECT * FROM my_view_nereids"""
+    sql """DROP VIEW IF EXISTS my_view_nereids"""
+    sql """DROP TABLE IF EXISTS test_view_t1"""
+    sql """DROP TABLE IF EXISTS test_view_t2"""
+
+
+    sql """DROP TABLE IF EXISTS view_baseall_nereids"""
+    sql """DROP VIEW IF EXISTS test_view7_nereids"""
+    sql """DROP VIEW IF EXISTS test_view8"""
+    sql """
+        CREATE TABLE `view_baseall_nereids` (
+            `k1` int(11) NULL,
+            `k3` array<int> NULL
+        ) ENGINE=OLAP
+        DUPLICATE KEY(`k1`)
+        COMMENT 'OLAP'
+        DISTRIBUTED BY HASH(`k1`) BUCKETS 5
+        PROPERTIES (
+        "replication_allocation" = "tag.location.default: 1",
+        "is_being_synced" = "false",
+        "storage_format" = "V2",
+        "light_schema_change" = "true",
+        "disable_auto_compaction" = "false",
+        "enable_single_replica_compaction" = "false"
+        );
+    """
+    sql """insert into view_baseall_nereids values(1,[1,2,3]);"""
+    sql """insert into view_baseall_nereids values(2,[10,-2,8]);"""
+    sql """insert into view_baseall_nereids values(3,[-1,20,0]);"""
+
+    qt_test_view_1 """ select * from view_baseall_nereids order by k1; """
+    qt_test_view_2 """ select *, array_map(x->x>0,k3) from 
view_baseall_nereids order by k1; """
+    qt_test_view_3 """ select *, array_filter(x->x>0,k3),array_filter(`k3`, 
array_map(x -> x > 0, `k3`)) from view_baseall_nereids order by k1; """
+
+
+    sql """
+    create view IF NOT EXISTS test_view7_nereids (k1,k2,k3,k4) as
+            select *, array_filter(x->x>0,k3),array_filter(`k3`, array_map(x 
-> x > 0, `k3`)) from view_baseall_nereids order by k1;
+    """
+    qt_test_view_4 """ select * from test_view7_nereids order by k1; """
+
+    sql """
+    create view IF NOT EXISTS test_view8_nereids (k1,k2,k3) as
+            select *, array_map(x->x>0,k3) from view_baseall_nereids order by 
k1;
+    """
+    qt_test_view_5 """ select * from test_view8_nereids order by k1; """
+
+    sql """DROP TABLE IF EXISTS view_column_name_test_nereids"""
+    sql """
+     CREATE TABLE IF NOT EXISTS view_column_name_test_nereids
+    (
+        `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_nereids
+    """
+    qt_test_view_6 """ SHOW VIEW FROM view_column_name_test_nereids;"""
+
+    // test with as
+    sql """
+          DROP TABLE IF EXISTS mal_test_view
+         """
+
+    sql """
+         create table mal_test_view(pk int, a int, b int) distributed by 
hash(pk) buckets 10
+         properties('replication_num' = '1'); 
+         """
+
+    sql """
+         insert into mal_test_view 
values(2,1,3),(1,1,2),(3,5,6),(6,null,6),(4,5,6),(2,1,4),(2,3,5),(1,1,4)
+        
,(3,5,6),(3,5,null),(6,7,1),(2,1,7),(2,4,2),(2,3,9),(1,3,6),(3,5,8),(3,2,8);
+      """
+    sql "DROP VIEW  if exists test_view_with_as"
+    sql """CREATE VIEW if not exists test_view_with_as AS (
+            with t1 as (select * from mal_test_view),  t2 as (select * from 
mal_test_view),  
+            t3 as (select * from mal_test_view) SELECT * FROM t1);"""
+    qt_test_with_as "select * from test_view_with_as order by pk, a, b"
+    qt_test_with_as_sql "show create view test_view_with_as"
+
+    // test union
+    sql "DROP VIEW  if exists test_view_union"
+    sql """CREATE VIEW test_view_union(c1,c2,c3) AS 
+            (select * from mal_test_view Union all SELECT * FROM 
mal_test_view);"""
+    qt_test_union "select c1,c2,c3 from test_view_union order by c1,c2,c3"
+    qt_test_union_sql "show create view test_view_union"
+
+    // test count(*)
+    sql "drop view if exists test_view_count_star;"
+    sql "CREATE VIEW test_view_count_star(c1) AS (select count(*) from 
mal_test_view having count(*) > 0);"
+    qt_test_count_star "select c1 from test_view_count_star order by c1"
+    qt_test_count_star_sql "show create view test_view_count_star"
+
+    // test expression
+    sql "drop view if exists test_view_expression;"
+    sql """CREATE VIEW test_view_expression(c1,c2,c3) AS (select 
a+1,abs(a)+2+1 as c2, cast(b as varchar(10)) as c1 from mal_test_view);"""
+    qt_test_expression "select * from test_view_expression order by c1,c2,c3"
+    qt_test_expression_sql "show create view test_view_expression;"
+
+    // test alias
+    sql "drop view if exists test_view_alias;"
+    sql """CREATE VIEW test_view_alias(c1,c2,c3) AS (
+        select c8 as c9, c2 as c3, c1 as c4 from (select a+1 c8,abs(a)+2+1 as 
c2, cast(b as varchar(10)) as c1 from mal_test_view) t);"""
+    qt_test_alias "select * from test_view_alias order by c1,c2,c3;"
+    qt_test_alias_sql "show create view test_view_alias;"
+
+    // test * except
+    sql "drop view if exists test_view_star_except;"
+    sql """
+        create view test_view_star_except as select * except(pk) from 
mal_test_view;
+        """
+    qt_test_star_except "select * from test_view_star_except order by a, b;"
+    qt_test_star_except_sql "show create view test_view_star_except;"
+
+    // test create view from view
+    sql "drop view if exists test_view_from_view"
+    sql "create view test_view_from_view(c1,c2,c3) as select * from 
test_view_with_as"
+    qt_test_create_view_from_view "select * from test_view_from_view order by 
c1,c2,c3"
+    qt_test_create_view_from_view_sql "show create view test_view_from_view"
+
+    // test backquote in name
+
+    sql "drop view if exists test_backquote_in_view_define;"
+    sql "create view test_backquote_in_view_define(`ab``c`, c2) as select a,b 
from mal_test_view;"
+    qt_test_backquote_in_view_define "select * from 
test_backquote_in_view_define order by `ab``c`, c2;"
+    qt_test_backquote_in_view_define_sql "show create view 
test_backquote_in_view_define;"
+
+    sql "drop view if exists test_backquote_in_table_alias;"
+    sql "create view test_backquote_in_table_alias(c1, c2) as  select * from 
(select a,b from mal_test_view) `ab``c`;"
+    qt_test_backquote_in_table_alias "select * from 
test_backquote_in_table_alias order by c1, c2;"
+    qt_test_backquote_in_table_alias_sql "show create view 
test_backquote_in_table_alias;"
+}
diff --git 
a/regression-test/suites/show_p0/test_show_create_table_and_views.groovy 
b/regression-test/suites/show_p0/test_show_create_table_and_views.groovy
index 6c6322e5c4a..5872cc95d5a 100644
--- a/regression-test/suites/show_p0/test_show_create_table_and_views.groovy
+++ b/regression-test/suites/show_p0/test_show_create_table_and_views.groovy
@@ -30,6 +30,7 @@ suite("test_show_create_table_and_views", "show") {
     String rollupName = "${suiteName}_rollup"
     String likeName = "${suiteName}_like"
 
+    sql "SET enable_nereids_planner=false;"
     sql "CREATE DATABASE IF NOT EXISTS ${dbName}"
     sql "DROP TABLE IF EXISTS ${dbName}.${tableName}"
     sql """
@@ -76,6 +77,7 @@ suite("test_show_create_table_and_views", "show") {
     qt_show "SHOW CREATE TABLE ${dbName}.${tableName}"
     qt_select "SELECT * FROM ${dbName}.${tableName} ORDER BY user_id, good_id"
 
+    sql "drop view if exists ${dbName}.${viewName};"
     // create view and show
     sql """
         CREATE VIEW IF NOT EXISTS ${dbName}.${viewName} (user_id, cost)
diff --git 
a/regression-test/suites/show_p0/test_show_create_table_and_views.groovy 
b/regression-test/suites/show_p0/test_show_create_table_and_views_nereids.groovy
similarity index 93%
copy from regression-test/suites/show_p0/test_show_create_table_and_views.groovy
copy to 
regression-test/suites/show_p0/test_show_create_table_and_views_nereids.groovy
index 6c6322e5c4a..88fd00444ad 100644
--- a/regression-test/suites/show_p0/test_show_create_table_and_views.groovy
+++ 
b/regression-test/suites/show_p0/test_show_create_table_and_views_nereids.groovy
@@ -15,7 +15,7 @@
 // specific language governing permissions and limitations
 // under the License.
 
-suite("test_show_create_table_and_views", "show") {
+suite("test_show_create_table_and_views_nereids", "show") {
     def ret = sql "SHOW FRONTEND CONFIG like '%enable_feature_binlog%';"
     logger.info("${ret}")
     if (ret.size() != 0 && ret[0].size() > 1 && ret[0][1] == 'false') {
@@ -23,13 +23,16 @@ suite("test_show_create_table_and_views", "show") {
         return
     }
 
-    String suiteName = "show_create_table_and_views"
+    String suiteName = "show_create_table_and_views_nereids"
     String dbName = "${suiteName}_db"
     String tableName = "${suiteName}_table"
     String viewName = "${suiteName}_view"
     String rollupName = "${suiteName}_rollup"
     String likeName = "${suiteName}_like"
 
+    sql "SET enable_nereids_planner=true;"
+    sql "SET enable_fallback_to_original_planner=false;"
+
     sql "CREATE DATABASE IF NOT EXISTS ${dbName}"
     sql "DROP TABLE IF EXISTS ${dbName}.${tableName}"
     sql """
@@ -76,6 +79,7 @@ suite("test_show_create_table_and_views", "show") {
     qt_show "SHOW CREATE TABLE ${dbName}.${tableName}"
     qt_select "SELECT * FROM ${dbName}.${tableName} ORDER BY user_id, good_id"
 
+    sql "drop view if exists ${dbName}.${viewName};"
     // create view and show
     sql """
         CREATE VIEW IF NOT EXISTS ${dbName}.${viewName} (user_id, cost)


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

Reply via email to