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 2f996a574f4a71330c02a9e7304a6e938c261a35
Author: feiniaofeiafei <53502832+feiniaofeia...@users.noreply.github.com>
AuthorDate: Wed Apr 24 15:58:13 2024 +0800

    [Feat](nereids) nereids add alter view (#33970)
    
    nereids support alter view stmt.
    e.g. ALTER VIEW example_db.example_view
    (
    c1 COMMENT "column 1",
    c2 COMMENT "column 2",
    c3 COMMENT "column 3"
    )
    AS SELECT k1, k2, SUM(v1) FROM example_table
    GROUP BY k1, k2
---
 .../antlr4/org/apache/doris/nereids/DorisParser.g4 |   2 +
 .../org/apache/doris/analysis/AlterViewStmt.java   |   9 +
 .../doris/nereids/parser/LogicalPlanBuilder.java   |  13 ++
 .../apache/doris/nereids/trees/plans/PlanType.java |   3 +-
 .../trees/plans/commands/AlterViewCommand.java     |  49 +++++
 .../trees/plans/commands/info/AlterViewInfo.java   | 121 +++++++++++
 .../{CreateViewInfo.java => BaseViewInfo.java}     | 112 ++---------
 .../trees/plans/commands/info/CreateViewInfo.java  | 221 +--------------------
 .../trees/plans/visitor/CommandVisitor.java        |   5 +
 .../data/ddl_p0/test_alter_view_nereids.out        |  17 ++
 .../suites/ddl_p0/test_alter_view_nereids.groovy   |  69 +++++++
 11 files changed, 310 insertions(+), 311 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 74870648786..b84f2186b91 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
@@ -63,6 +63,8 @@ statementBase
     | CREATE VIEW (IF NOT EXISTS)? name=multipartIdentifier
         (LEFT_PAREN cols=simpleColumnDefs RIGHT_PAREN)?
         (COMMENT STRING_LITERAL)? AS query                                
#createView
+    | ALTER VIEW name=multipartIdentifier (LEFT_PAREN cols=simpleColumnDefs 
RIGHT_PAREN)?
+        AS query                                                          
#alterView
     | 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/AlterViewStmt.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/AlterViewStmt.java
index 355c9723c8b..39ea2ff1294 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/AlterViewStmt.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/AlterViewStmt.java
@@ -17,6 +17,7 @@
 
 package org.apache.doris.analysis;
 
+import org.apache.doris.catalog.Column;
 import org.apache.doris.catalog.DatabaseIf;
 import org.apache.doris.catalog.Env;
 import org.apache.doris.catalog.TableIf;
@@ -77,6 +78,14 @@ public class AlterViewStmt extends BaseViewStmt {
         createColumnAndViewDefs(analyzer);
     }
 
+    public void setInlineViewDef(String querySql) {
+        inlineViewDef = querySql;
+    }
+
+    public void setFinalColumns(List<Column> columns) {
+        finalCols.addAll(columns);
+    }
+
     @Override
     public String toSql() {
         StringBuilder sb = new StringBuilder();
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 4739e74b262..239d898f02e 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
@@ -48,6 +48,7 @@ import 
org.apache.doris.nereids.DorisParser.AggStateDataTypeContext;
 import org.apache.doris.nereids.DorisParser.AliasQueryContext;
 import org.apache.doris.nereids.DorisParser.AliasedQueryContext;
 import org.apache.doris.nereids.DorisParser.AlterMTMVContext;
+import org.apache.doris.nereids.DorisParser.AlterViewContext;
 import org.apache.doris.nereids.DorisParser.ArithmeticBinaryContext;
 import org.apache.doris.nereids.DorisParser.ArithmeticUnaryContext;
 import org.apache.doris.nereids.DorisParser.ArrayLiteralContext;
@@ -353,6 +354,7 @@ import 
org.apache.doris.nereids.trees.plans.algebra.Aggregate;
 import org.apache.doris.nereids.trees.plans.algebra.SetOperation.Qualifier;
 import org.apache.doris.nereids.trees.plans.commands.AddConstraintCommand;
 import org.apache.doris.nereids.trees.plans.commands.AlterMTMVCommand;
+import org.apache.doris.nereids.trees.plans.commands.AlterViewCommand;
 import org.apache.doris.nereids.trees.plans.commands.CallCommand;
 import org.apache.doris.nereids.trees.plans.commands.CancelMTMVTaskCommand;
 import org.apache.doris.nereids.trees.plans.commands.Command;
@@ -382,6 +384,7 @@ import 
org.apache.doris.nereids.trees.plans.commands.info.AlterMTMVInfo;
 import 
org.apache.doris.nereids.trees.plans.commands.info.AlterMTMVPropertyInfo;
 import org.apache.doris.nereids.trees.plans.commands.info.AlterMTMVRefreshInfo;
 import org.apache.doris.nereids.trees.plans.commands.info.AlterMTMVRenameInfo;
+import org.apache.doris.nereids.trees.plans.commands.info.AlterViewInfo;
 import org.apache.doris.nereids.trees.plans.commands.info.BulkLoadDataDesc;
 import org.apache.doris.nereids.trees.plans.commands.info.BulkStorageDesc;
 import org.apache.doris.nereids.trees.plans.commands.info.CancelMTMVTaskInfo;
@@ -804,6 +807,16 @@ public class LogicalPlanBuilder extends 
DorisParserBaseVisitor<Object> {
         return new AlterMTMVCommand(alterMTMVInfo);
     }
 
+    @Override
+    public LogicalPlan visitAlterView(AlterViewContext ctx) {
+        List<String> nameParts = visitMultipartIdentifier(ctx.name);
+        LogicalPlan logicalPlan = visitQuery(ctx.query());
+        String querySql = getOriginSql(ctx.query());
+        AlterViewInfo info = new AlterViewInfo(new TableNameInfo(nameParts), 
logicalPlan, querySql,
+                ctx.cols == null ? Lists.newArrayList() : 
visitSimpleColumnDefs(ctx.cols));
+        return new AlterViewCommand(info);
+    }
+
     @Override
     public LogicalPlan visitShowConstraint(ShowConstraintContext ctx) {
         List<String> parts = visitMultipartIdentifier(ctx.table);
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 165dcd5e3ca..bf4741cff4e 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
@@ -151,5 +151,6 @@ public enum PlanType {
     DROP_PROCEDURE_COMMAND,
     SHOW_PROCEDURE_COMMAND,
     SHOW_CREATE_PROCEDURE_COMMAND,
-    CREATE_VIEW_COMMAND
+    CREATE_VIEW_COMMAND,
+    ALTER_VIEW_COMMAND
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/AlterViewCommand.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/AlterViewCommand.java
new file mode 100644
index 00000000000..ebcbe280532
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/AlterViewCommand.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.AlterViewStmt;
+import org.apache.doris.catalog.Env;
+import org.apache.doris.nereids.trees.plans.PlanType;
+import org.apache.doris.nereids.trees.plans.commands.info.AlterViewInfo;
+import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor;
+import org.apache.doris.qe.ConnectContext;
+import org.apache.doris.qe.StmtExecutor;
+
+/**AlterViewCommand*/
+public class AlterViewCommand extends Command implements ForwardWithSync {
+    private final AlterViewInfo alterViewInfo;
+
+    public AlterViewCommand(AlterViewInfo alterViewInfo) {
+        super(PlanType.ALTER_VIEW_COMMAND);
+        this.alterViewInfo = alterViewInfo;
+    }
+
+    @Override
+    public void run(ConnectContext ctx, StmtExecutor executor) throws 
Exception {
+        alterViewInfo.init(ctx);
+        alterViewInfo.validate(ctx);
+        AlterViewStmt alterViewStmt = alterViewInfo.translateToLegacyStmt(ctx);
+        Env.getCurrentEnv().alterView(alterViewStmt);
+    }
+
+    @Override
+    public <R, C> R accept(PlanVisitor<R, C> visitor, C context) {
+        return visitor.visitAlterViewCommand(this, context);
+    }
+}
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/AlterViewInfo.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/AlterViewInfo.java
new file mode 100644
index 00000000000..55798377145
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/AlterViewInfo.java
@@ -0,0 +1,121 @@
+// 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.AlterViewStmt;
+import org.apache.doris.analysis.ColWithComment;
+import org.apache.doris.analysis.TableName;
+import org.apache.doris.catalog.Column;
+import org.apache.doris.catalog.DatabaseIf;
+import org.apache.doris.catalog.Env;
+import org.apache.doris.catalog.TableIf;
+import org.apache.doris.catalog.View;
+import org.apache.doris.common.ErrorCode;
+import org.apache.doris.common.ErrorReport;
+import org.apache.doris.common.FeNameFormat;
+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.NereidsPlanner;
+import org.apache.doris.nereids.analyzer.UnboundResultSink;
+import org.apache.doris.nereids.exceptions.AnalysisException;
+import org.apache.doris.nereids.properties.PhysicalProperties;
+import org.apache.doris.nereids.trees.expressions.Slot;
+import 
org.apache.doris.nereids.trees.plans.commands.ExplainCommand.ExplainLevel;
+import org.apache.doris.nereids.trees.plans.logical.LogicalFileSink;
+import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
+import org.apache.doris.qe.ConnectContext;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+import java.util.List;
+import java.util.Set;
+
+/** AlterViewInfo */
+public class AlterViewInfo extends BaseViewInfo {
+    /** constructor*/
+    public AlterViewInfo(TableNameInfo viewName, LogicalPlan logicalQuery,
+            String querySql, List<SimpleColumnDefinition> 
simpleColumnDefinitions) {
+        super(viewName, logicalQuery, querySql, simpleColumnDefinitions);
+        if (logicalQuery instanceof LogicalFileSink) {
+            throw new AnalysisException("Not support OUTFILE clause in ALTER 
VIEW statement");
+        }
+    }
+
+    /** init */
+    public void init(ConnectContext ctx) throws UserException {
+        if (viewName == null) {
+            ErrorReport.reportAnalysisException(ErrorCode.ERR_NO_TABLES_USED);
+        }
+        viewName.analyze(ctx);
+        FeNameFormat.checkTableName(viewName.getTbl());
+        // disallow external catalog
+        Util.prohibitExternalCatalog(viewName.getCtl(), "AlterViewStmt");
+
+        DatabaseIf db = 
Env.getCurrentInternalCatalog().getDbOrAnalysisException(viewName.getDb());
+        TableIf table = db.getTableOrAnalysisException(viewName.getTbl());
+        if (!(table instanceof View)) {
+            throw new org.apache.doris.common.AnalysisException(
+                    String.format("ALTER VIEW not allowed on a table:%s.%s", 
viewName.getDb(), viewName.getTbl()));
+        }
+
+        // check privilege
+        if (!Env.getCurrentEnv().getAccessManager().checkTblPriv(ctx, new 
TableName(viewName.getCtl(), viewName.getDb(),
+                viewName.getTbl()), PrivPredicate.ALTER)) {
+            
ErrorReport.reportAnalysisException(ErrorCode.ERR_TABLE_ACCESS_DENIED_ERROR,
+                    PrivPredicate.ALTER.getPrivs().toString(), 
viewName.getTbl());
+        }
+        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);
+        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 AlterViewStmt translateToLegacyStmt(ConnectContext ctx) {
+        List<ColWithComment> cols = Lists.newArrayList();
+        for (SimpleColumnDefinition def : simpleColumnDefinitions) {
+            cols.add(def.translateToColWithComment());
+        }
+        AlterViewStmt alterViewStmt = new 
AlterViewStmt(viewName.transferToTableName(), cols,
+                null);
+        // expand star(*) in project list and replace table name with qualifier
+        String rewrittenSql = 
rewriteSql(ctx.getStatementContext().getIndexInSqlToString());
+
+        // rewrite project alias
+        rewrittenSql = rewriteProjectsToUserDefineAlias(rewrittenSql);
+
+        alterViewStmt.setInlineViewDef(rewrittenSql);
+        alterViewStmt.setFinalColumns(finalCols);
+        return alterViewStmt;
+    }
+}
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/BaseViewInfo.java
similarity index 67%
copy from 
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/CreateViewInfo.java
copy to 
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/BaseViewInfo.java
index 084fe3af3f4..e0b00edf7fe 100644
--- 
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/BaseViewInfo.java
@@ -17,27 +17,17 @@
 
 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.analysis.TableName;
 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;
@@ -49,16 +39,13 @@ 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;
@@ -66,86 +53,25 @@ 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;
+/** BaseViewInfo */
+public class BaseViewInfo {
+    protected final TableNameInfo viewName;
+    protected final LogicalPlan logicalQuery;
+    protected final String querySql;
+    protected final List<SimpleColumnDefinition> simpleColumnDefinitions;
+    protected final List<Column> finalCols = Lists.newArrayList();
+    protected Plan analyzedPlan;
 
-    /** constructor*/
-    public CreateViewInfo(boolean ifNotExists, TableNameInfo viewName, String 
comment, LogicalPlan logicalQuery,
+    public BaseViewInfo(TableNameInfo viewName, 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 {
-        viewName.analyze(ctx);
-        FeNameFormat.checkTableName(viewName.getTbl());
-        // disallow external catalog
-        Util.prohibitExternalCatalog(viewName.getCtl(), "CreateViewStmt");
-        // check privilege
-        if (!Env.getCurrentEnv().getAccessManager().checkTblPriv(ctx, new 
TableName(viewName.getCtl(), viewName.getDb(),
-                viewName.getTbl()), PrivPredicate.CREATE)) {
-            
ErrorReport.reportAnalysisException(ErrorCode.ERR_TABLE_ACCESS_DENIED_ERROR,
-                    PrivPredicate.CREATE.getPrivs().toString(), 
viewName.getTbl());
-        }
-        NereidsPlanner planner = new NereidsPlanner(ctx.getStatementContext());
-        planner.plan(new UnboundResultSink<>(logicalQuery), 
PhysicalProperties.ANY, ExplainLevel.NONE);
-        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) {
+    protected void analyzeAndFillRewriteSqlMap(String sql, ConnectContext ctx) 
{
         StatementContext stmtCtx = ctx.getStatementContext();
         LogicalPlan parsedViewPlan = new 
NereidsParser().parseForCreateView(sql);
         if (parsedViewPlan instanceof UnboundResultSink) {
@@ -158,7 +84,7 @@ public class CreateViewInfo {
         analyzedPlan = viewContextForStar.getRewritePlan();
     }
 
-    private String rewriteSql(Map<Pair<Integer, Integer>, String> 
indexStringSqlMap) {
+    protected 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()) {
@@ -171,7 +97,7 @@ public class CreateViewInfo {
         return builder.toString();
     }
 
-    private String rewriteProjectsToUserDefineAlias(String resSql) {
+    protected String rewriteProjectsToUserDefineAlias(String resSql) {
         IndexFinder finder = new IndexFinder();
         ParserRuleContext tree = NereidsParser.toAst(resSql, 
DorisParser::singleStatement);
         finder.visit(tree);
@@ -198,7 +124,7 @@ public class CreateViewInfo {
                 finder.getIndex().second + 1);
     }
 
-    private void createFinalCols(List<Slot> outputs) throws 
org.apache.doris.common.AnalysisException {
+    protected 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());
@@ -217,12 +143,15 @@ public class CreateViewInfo {
         }
     }
 
-    private static class OutermostPlanFinderContext {
+    /**OutermostPlanFinderContext*/
+    protected static class OutermostPlanFinderContext {
         public Plan outermostPlan = null;
         public boolean found = false;
     }
 
-    private static class OutermostPlanFinder extends DefaultPlanVisitor<Void, 
OutermostPlanFinderContext> {
+    /**OutermostPlanFinder*/
+    protected static class OutermostPlanFinder extends
+            DefaultPlanVisitor<Void, OutermostPlanFinderContext> {
         public static final OutermostPlanFinder INSTANCE = new 
OutermostPlanFinder();
 
         @Override
@@ -252,7 +181,7 @@ public class CreateViewInfo {
     }
 
     /** traverse ast to find the outermost project list location information 
in sql*/
-    private static class IndexFinder extends DorisParserBaseVisitor<Void> {
+    protected static class IndexFinder extends DorisParserBaseVisitor<Void> {
         private boolean found = false;
         private int startIndex;
         private int stopIndex;
@@ -299,7 +228,8 @@ public class CreateViewInfo {
         }
     }
 
-    private static class AnalyzerForCreateView extends 
AbstractBatchJobExecutor {
+    /**AnalyzerForCreateView*/
+    protected static class AnalyzerForCreateView extends 
AbstractBatchJobExecutor {
         private final List<RewriteJob> jobs;
 
         public AnalyzerForCreateView(CascadesContext cascadesContext) {
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
index 084fe3af3f4..e52f69954ba 100644
--- 
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
@@ -25,74 +25,41 @@ 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 {
+public class CreateViewInfo extends BaseViewInfo {
     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) {
+        super(viewName, logicalQuery, querySql, 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 */
@@ -144,188 +111,4 @@ public class CreateViewInfo {
         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/visitor/CommandVisitor.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/visitor/CommandVisitor.java
index 527ccb1ffe0..d23cb855af6 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
@@ -19,6 +19,7 @@ package org.apache.doris.nereids.trees.plans.visitor;
 
 import org.apache.doris.nereids.trees.plans.commands.AddConstraintCommand;
 import org.apache.doris.nereids.trees.plans.commands.AlterMTMVCommand;
+import org.apache.doris.nereids.trees.plans.commands.AlterViewCommand;
 import org.apache.doris.nereids.trees.plans.commands.CallCommand;
 import org.apache.doris.nereids.trees.plans.commands.CancelMTMVTaskCommand;
 import org.apache.doris.nereids.trees.plans.commands.Command;
@@ -161,4 +162,8 @@ public interface CommandVisitor<R, C> {
     default R visitCreateViewCommand(CreateViewCommand createViewCommand, C 
context) {
         return visitCommand(createViewCommand, context);
     }
+
+    default R visitAlterViewCommand(AlterViewCommand alterViewCommand, C 
context) {
+        return visitCommand(alterViewCommand, context);
+    }
 }
diff --git a/regression-test/data/ddl_p0/test_alter_view_nereids.out 
b/regression-test/data/ddl_p0/test_alter_view_nereids.out
new file mode 100644
index 00000000000..ef50a9c8801
--- /dev/null
+++ b/regression-test/data/ddl_p0/test_alter_view_nereids.out
@@ -0,0 +1,17 @@
+-- This file is automatically generated. You should know what you did if you 
want to edit this
+-- !select --
+1      1
+1      5
+2      1
+2      10
+
+-- !select --
+1      60
+2      70
+
+-- !sql --
+test_alter_view_view_nereids   CREATE VIEW `test_alter_view_view_nereids` 
COMMENT 'test_view' AS SELECT c1 AS `k1`, sum(c3) AS `k2` FROM 
`internal`.`regression_test_ddl_p0`.`test_alter_view_table_nereids` GROUP BY 
c1;      utf8mb4 utf8mb4_0900_bin
+
+-- !sql --
+test_alter_view_view_nereids   CREATE VIEW `test_alter_view_view_nereids` 
COMMENT 'test_view' AS (select 
`internal`.`regression_test_ddl_p0`.`test_alter_view_table_nereids`.`c1`, 
`internal`.`regression_test_ddl_p0`.`test_alter_view_table_nereids`.`c2`, 
`internal`.`regression_test_ddl_p0`.`test_alter_view_table_nereids`.`c3` from 
`internal`.`regression_test_ddl_p0`.`test_alter_view_table_nereids`);       
utf8mb4 utf8mb4_0900_bin
+
diff --git a/regression-test/suites/ddl_p0/test_alter_view_nereids.groovy 
b/regression-test/suites/ddl_p0/test_alter_view_nereids.groovy
new file mode 100644
index 00000000000..6b26d093e56
--- /dev/null
+++ b/regression-test/suites/ddl_p0/test_alter_view_nereids.groovy
@@ -0,0 +1,69 @@
+// 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_alter_view_nereids") {
+    sql "SET enable_nereids_planner=true;"
+    sql "SET enable_fallback_to_original_planner=false;"
+    String tableName = "test_alter_view_table_nereids";
+    String viewName = "test_alter_view_view_nereids";
+    sql " DROP TABLE IF EXISTS ${tableName}"
+    sql """
+        CREATE TABLE IF NOT EXISTS ${tableName}
+        (
+            c1 BIGINT NOT NULL,
+            c2 BIGINT NOT NULL,
+            c3 BIGINT NOT NULL
+        )
+        UNIQUE KEY (`c1`, `c2`)
+        DISTRIBUTED BY HASH(`c1`) BUCKETS 1
+        PROPERTIES
+        (
+            "replication_num" = "1"
+        )
+        """
+    sql """
+        CREATE VIEW IF NOT EXISTS ${viewName} (k1, k2)
+        COMMENT "test_view"
+        AS
+        SELECT c1 as k1, c2 as k2 FROM ${tableName}
+        """
+
+    sql """
+        INSERT INTO ${tableName} VALUES
+        (1, 1, 10),
+        (1, 5, 50),
+        (2, 1, 20),
+        (2, 10, 50)
+        """
+
+    qt_select " SELECT * FROM ${viewName} order by k1, k2 "
+
+    sql """
+        ALTER VIEW ${viewName} (k1, k2)
+        AS
+        SELECT c1 as k1, sum(c3) as k2 FROM ${tableName} GROUP BY c1
+    """
+
+    qt_select " SELECT * FROM ${viewName} order by k1, k2 "
+    qt_sql "show create view ${viewName}"
+
+    sql "alter view ${viewName} as (select * from ${tableName})"
+    qt_sql "show create view ${viewName}"
+
+    sql "DROP VIEW ${viewName}"
+    sql "DROP TABLE ${tableName}"
+}


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


Reply via email to