From 61edb9e4d88d1c10e778883454bfbfa48a901521 Mon Sep 17 00:00:00 2001 From: zhangdong <493738387@qq.com> Date: Fri, 3 Nov 2023 11:57:00 +0800 Subject: [PATCH] [feature](mtmv)(2)Implementing mtmv using antlr (#26102) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implementing mtmv using antlr, No specific business logic was implemented, therefore an exception was thrown during execution ``` throw new AnalysisException("current not support."); ``` --- .../org/apache/doris/nereids/DorisLexer.g4 | 2 + .../org/apache/doris/nereids/DorisParser.g4 | 44 ++++- .../java/org/apache/doris/mtmv/EnvInfo.java | 43 +++++ .../apache/doris/mtmv/MTMVRefreshEnum.java | 66 +++++++ .../apache/doris/mtmv/MTMVRefreshInfo.java | 109 ++++++++++++ .../doris/mtmv/MTMVRefreshSchedule.java | 101 +++++++++++ .../doris/mtmv/MTMVRefreshTriggerInfo.java | 89 ++++++++++ .../nereids/parser/LogicalPlanBuilder.java | 166 +++++++++++++++++ .../doris/nereids/trees/plans/PlanType.java | 6 +- .../plans/commands/AlterMTMVCommand.java | 58 ++++++ .../plans/commands/CreateMTMVCommand.java | 59 ++++++ .../trees/plans/commands/DropMTMVCommand.java | 50 ++++++ .../plans/commands/RefreshMTMVCommand.java | 50 ++++++ .../plans/commands/info/AlterMTMVInfo.java | 62 +++++++ .../commands/info/AlterMTMVPropertyInfo.java | 53 ++++++ .../commands/info/AlterMTMVRefreshInfo.java | 54 ++++++ .../commands/info/AlterMTMVRenameInfo.java | 59 ++++++ .../plans/commands/info/CreateMTMVInfo.java | 82 +++++++++ .../plans/commands/info/DropMTMVInfo.java | 52 ++++++ .../plans/commands/info/RefreshMTMVInfo.java | 48 +++++ .../commands/info/SimpleColumnDefinition.java | 42 +++++ .../plans/commands/info/TableNameInfo.java | 168 ++++++++++++++++++ .../trees/plans/visitor/CommandVisitor.java | 20 +++ 23 files changed, 1481 insertions(+), 2 deletions(-) create mode 100644 fe/fe-core/src/main/java/org/apache/doris/mtmv/EnvInfo.java create mode 100644 fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRefreshEnum.java create mode 100644 fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRefreshInfo.java create mode 100644 fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRefreshSchedule.java create mode 100644 fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRefreshTriggerInfo.java create mode 100644 fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/AlterMTMVCommand.java create mode 100644 fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CreateMTMVCommand.java create mode 100644 fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/DropMTMVCommand.java create mode 100644 fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/RefreshMTMVCommand.java create mode 100644 fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/AlterMTMVInfo.java create mode 100644 fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/AlterMTMVPropertyInfo.java create mode 100644 fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/AlterMTMVRefreshInfo.java create mode 100644 fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/AlterMTMVRenameInfo.java create mode 100644 fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/CreateMTMVInfo.java create mode 100644 fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/DropMTMVInfo.java create mode 100644 fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/RefreshMTMVInfo.java create mode 100644 fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/SimpleColumnDefinition.java create mode 100644 fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/TableNameInfo.java diff --git a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisLexer.g4 b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisLexer.g4 index 6bfc38d76116c8..81b6c5e351dc7f 100644 --- a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisLexer.g4 +++ b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisLexer.g4 @@ -331,6 +331,7 @@ LOCATION: 'LOCATION'; LOCK: 'LOCK'; LOGICAL: 'LOGICAL'; LOW_PRIORITY: 'LOW_PRIORITY'; +MANUAL: 'MANUAL'; MAP: 'MAP'; MATCH: 'MATCH'; MATCH_ALL: 'MATCH_ALL'; @@ -447,6 +448,7 @@ ROW: 'ROW'; ROWS: 'ROWS'; S3: 'S3'; SAMPLE: 'SAMPLE'; +SCHEDULE: 'SCHEDULE'; SCHEDULER: 'SCHEDULER'; SCHEMA: 'SCHEMA'; SCHEMAS: 'SCHEMAS'; 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 8a1896a3d0c8d0..7e2f4237e14433 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 @@ -83,6 +83,19 @@ statement TO filePath=STRING_LITERAL (propertyClause)? (withRemoteStorageSystem)? #export + | CREATE MATERIALIZED VIEW (IF NOT EXISTS)? mvName=multipartIdentifier + (LEFT_PAREN cols=simpleColumnDefs RIGHT_PAREN)? buildMode? + (REFRESH refreshMethod? refreshTrigger?)? + (KEY keys=identifierList)? + (COMMENT STRING_LITERAL)? + (DISTRIBUTED BY (HASH hashKeys=identifierList | RANDOM) (BUCKETS (INTEGER_VALUE | AUTO))?)? + propertyClause? + AS query #createMTMV + | REFRESH MATERIALIZED VIEW mvName=multipartIdentifier #refreshMTMV + | ALTER MATERIALIZED VIEW mvName=multipartIdentifier ((RENAME newName=identifier) + | (REFRESH (refreshMethod | refreshTrigger | refreshMethod refreshTrigger)) + | (SET LEFT_PAREN fileProperties=propertyItemList RIGHT_PAREN)) #alterMTMV + | DROP MATERIALIZED VIEW (IF EXISTS)? mvName=multipartIdentifier #dropMTMV ; dataDesc @@ -110,6 +123,26 @@ dataDesc ; // -----------------Command accessories----------------- +buildMode + : BUILD (IMMEDIATE | DEFERRED) + ; + +refreshTrigger + : ON MANUAL + | ON SCHEDULE refreshSchedule + ; + +refreshSchedule + : EVERY INTEGER_VALUE mvRefreshUnit (STARTS STRING_LITERAL)? + ; + +mvRefreshUnit + : SECOND | MINUTE | HOUR | DAY | WEEK + ; + +refreshMethod + : COMPLETE + ; identifierOrText : errorCapturingIdentifier @@ -413,7 +446,14 @@ multipartIdentifier ; // ----------------Create Table Fields---------- - +simpleColumnDefs + : cols+=simpleColumnDef (COMMA cols+=simpleColumnDef)* + ; + +simpleColumnDef + : colName=identifier (COMMENT comment=STRING_LITERAL)? + ; + columnDefs : cols+=columnDef (COMMA cols+=columnDef)* ; @@ -958,6 +998,7 @@ nonReserved | LOCATION | LOCK | LOGICAL + | MANUAL | MAP | MATERIALIZED | MAX @@ -1033,6 +1074,7 @@ nonReserved | ROUTINE | S3 | SAMPLE + | SCHEDULE | SCHEDULER | SCHEMA | SECOND diff --git a/fe/fe-core/src/main/java/org/apache/doris/mtmv/EnvInfo.java b/fe/fe-core/src/main/java/org/apache/doris/mtmv/EnvInfo.java new file mode 100644 index 00000000000000..c5c92a15db90ce --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/mtmv/EnvInfo.java @@ -0,0 +1,43 @@ +// 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.mtmv; + +import com.google.gson.annotations.SerializedName; + +/** + * EnvInfo + */ +public class EnvInfo { + @SerializedName("cn") + private String ctlName; + @SerializedName("dn") + private String dbName; + + public EnvInfo(String ctlName, String dbName) { + this.ctlName = ctlName; + this.dbName = dbName; + } + + public String getCtlName() { + return ctlName; + } + + public String getDbName() { + return dbName; + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRefreshEnum.java b/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRefreshEnum.java new file mode 100644 index 00000000000000..6f14a2ba014e7b --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRefreshEnum.java @@ -0,0 +1,66 @@ +// 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.mtmv; + +/** + * refresh enum + */ +public class MTMVRefreshEnum { + + /** + * RefreshMethod + */ + public enum RefreshMethod { + COMPLETE //complete + } + + /** + * BuildMode + */ + public enum BuildMode { + IMMEDIATE, //right now + DEFERRED // deferred + } + + /** + * RefreshTrigger + */ + public enum RefreshTrigger { + MANUAL, //manual + SCHEDULE // schedule + } + + /** + * MTMVState + */ + public enum MTMVState { + INIT, + NORMAL, + SCHEMA_CHANGE + } + + /** + * MTMVRefreshState + */ + public enum MTMVRefreshState { + INIT, + REFRESHING, + FAIL, + SUCCESS + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRefreshInfo.java b/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRefreshInfo.java new file mode 100644 index 00000000000000..c49bcbc190a345 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRefreshInfo.java @@ -0,0 +1,109 @@ +// 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.mtmv; + +import org.apache.doris.mtmv.MTMVRefreshEnum.BuildMode; +import org.apache.doris.mtmv.MTMVRefreshEnum.RefreshMethod; + +import com.google.gson.annotations.SerializedName; + +import java.util.Objects; + +/** + * refresh info + */ +public class MTMVRefreshInfo { + @SerializedName("bm") + private BuildMode buildMode; + @SerializedName("rm") + private RefreshMethod refreshMethod; + @SerializedName("rti") + private MTMVRefreshTriggerInfo refreshTriggerInfo; + + public MTMVRefreshInfo() { + } + + public MTMVRefreshInfo(BuildMode buildMode, + RefreshMethod refreshMethod, + MTMVRefreshTriggerInfo refreshTriggerInfo) { + this.buildMode = Objects.requireNonNull(buildMode, "require buildMode object"); + this.refreshMethod = Objects.requireNonNull(refreshMethod, "require refreshMethod object"); + this.refreshTriggerInfo = Objects.requireNonNull(refreshTriggerInfo, "require refreshTriggerInfo object"); + } + + public void validate() { + if (refreshTriggerInfo != null) { + refreshTriggerInfo.validate(); + } + } + + public BuildMode getBuildMode() { + return buildMode; + } + + public RefreshMethod getRefreshMethod() { + return refreshMethod; + } + + public MTMVRefreshTriggerInfo getRefreshTriggerInfo() { + return refreshTriggerInfo; + } + + public void setBuildMode(BuildMode buildMode) { + this.buildMode = buildMode; + } + + public void setRefreshMethod(RefreshMethod refreshMethod) { + this.refreshMethod = refreshMethod; + } + + public void setRefreshTriggerInfo( + MTMVRefreshTriggerInfo refreshTriggerInfo) { + this.refreshTriggerInfo = refreshTriggerInfo; + } + + /** + * update refreshInfo + */ + public MTMVRefreshInfo updateNotNull(MTMVRefreshInfo newRefreshInfo) { + Objects.requireNonNull(newRefreshInfo); + if (newRefreshInfo.buildMode != null) { + this.buildMode = newRefreshInfo.buildMode; + } + if (newRefreshInfo.refreshMethod != null) { + this.refreshMethod = newRefreshInfo.refreshMethod; + } + if (newRefreshInfo.refreshTriggerInfo != null) { + this.refreshTriggerInfo = newRefreshInfo.refreshTriggerInfo; + } + return this; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("BUILD "); + builder.append(buildMode); + builder.append(" REFRESH "); + builder.append(refreshMethod); + builder.append(" "); + builder.append(refreshTriggerInfo); + return builder.toString(); + } + +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRefreshSchedule.java b/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRefreshSchedule.java new file mode 100644 index 00000000000000..2f4aa5f96c82fb --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRefreshSchedule.java @@ -0,0 +1,101 @@ +// 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.mtmv; + +import org.apache.doris.common.util.TimeUtils; +import org.apache.doris.nereids.exceptions.AnalysisException; +import org.apache.doris.scheduler.common.IntervalUnit; + +import com.google.gson.annotations.SerializedName; +import org.apache.commons.lang3.StringUtils; + +import java.util.Objects; + +/** + * refresh schedule in mtmv + */ +public class MTMVRefreshSchedule { + @SerializedName("st") + private String startTime; + @SerializedName("i") + private long interval; + @SerializedName("tu") + private IntervalUnit timeUnit; + + // For deserialization + public MTMVRefreshSchedule() { + } + + public MTMVRefreshSchedule(String startTime, int interval, IntervalUnit timeUnit) { + this.startTime = startTime; + this.interval = Objects.requireNonNull(interval, "require interval object"); + this.timeUnit = Objects.requireNonNull(timeUnit, "require timeUnit object"); + } + + /** + * getStartTime + * @return startTime + */ + public String getStartTime() { + return startTime; + } + + /** + * getInterval + * @return interval + */ + public long getInterval() { + return interval; + } + + /** + * getTimeUnit + * @return timeUnit + */ + public IntervalUnit getTimeUnit() { + return timeUnit; + } + + /** + * validate + */ + public void validate() { + if (interval <= 0) { + throw new AnalysisException("interval must be greater than 0"); + } + if (!StringUtils.isEmpty(startTime)) { + long startsTimeMillis = TimeUtils.timeStringToLong(startTime); + if (startsTimeMillis < System.currentTimeMillis()) { + throw new AnalysisException("starts time must be greater than current time"); + } + } + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder("EVERY "); + builder.append(interval); + builder.append(" "); + builder.append(timeUnit); + if (!StringUtils.isEmpty(startTime)) { + builder.append(" STARTS "); + builder.append(startTime); + } + return builder.toString(); + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRefreshTriggerInfo.java b/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRefreshTriggerInfo.java new file mode 100644 index 00000000000000..08058dd225e869 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRefreshTriggerInfo.java @@ -0,0 +1,89 @@ +// 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.mtmv; + +import org.apache.doris.mtmv.MTMVRefreshEnum.RefreshTrigger; +import org.apache.doris.nereids.exceptions.AnalysisException; + +import com.google.gson.annotations.SerializedName; + +import java.util.Objects; + +/** + * refresh trigger info in mtmv + */ +public class MTMVRefreshTriggerInfo { + @SerializedName("rt") + private RefreshTrigger refreshTrigger; + @SerializedName("it") + private MTMVRefreshSchedule intervalTrigger; + + // For deserialization + public MTMVRefreshTriggerInfo() { + } + + public MTMVRefreshTriggerInfo(RefreshTrigger trigger) { + this(trigger, null); + } + + public MTMVRefreshTriggerInfo(RefreshTrigger refreshTrigger, MTMVRefreshSchedule intervalTrigger) { + this.refreshTrigger = Objects.requireNonNull(refreshTrigger, "require refreshTrigger object"); + this.intervalTrigger = intervalTrigger; + } + + /** + * getRefreshTrigger + * + * @return RefreshTrigger + */ + public RefreshTrigger getRefreshTrigger() { + return refreshTrigger; + } + + /** + * getIntervalTrigger + * + * @return MTMVRefreshSchedule + */ + public MTMVRefreshSchedule getIntervalTrigger() { + return intervalTrigger; + } + + /** + * validate + */ + public void validate() { + if (refreshTrigger.equals(RefreshTrigger.SCHEDULE)) { + if (intervalTrigger == null) { + throw new AnalysisException("require intervalTrigger object."); + } + intervalTrigger.validate(); + } + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder("ON "); + builder.append(refreshTrigger); + if (intervalTrigger != null) { + builder.append(" "); + builder.append(intervalTrigger); + } + return builder.toString(); + } +} 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 a05e24b6944100..a8204f1ea97ae1 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 @@ -29,10 +29,17 @@ import org.apache.doris.common.FeConstants; import org.apache.doris.common.Pair; import org.apache.doris.load.loadv2.LoadTask; +import org.apache.doris.mtmv.MTMVRefreshEnum.BuildMode; +import org.apache.doris.mtmv.MTMVRefreshEnum.RefreshMethod; +import org.apache.doris.mtmv.MTMVRefreshEnum.RefreshTrigger; +import org.apache.doris.mtmv.MTMVRefreshInfo; +import org.apache.doris.mtmv.MTMVRefreshSchedule; +import org.apache.doris.mtmv.MTMVRefreshTriggerInfo; import org.apache.doris.nereids.DorisParser; import org.apache.doris.nereids.DorisParser.AggClauseContext; 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.ArithmeticBinaryContext; import org.apache.doris.nereids.DorisParser.ArithmeticUnaryContext; import org.apache.doris.nereids.DorisParser.ArrayLiteralContext; @@ -42,6 +49,7 @@ import org.apache.doris.nereids.DorisParser.BooleanLiteralContext; import org.apache.doris.nereids.DorisParser.BracketJoinHintContext; import org.apache.doris.nereids.DorisParser.BracketRelationHintContext; +import org.apache.doris.nereids.DorisParser.BuildModeContext; import org.apache.doris.nereids.DorisParser.CollateContext; import org.apache.doris.nereids.DorisParser.ColumnDefContext; import org.apache.doris.nereids.DorisParser.ColumnDefsContext; @@ -54,6 +62,7 @@ import org.apache.doris.nereids.DorisParser.ComplexDataTypeContext; import org.apache.doris.nereids.DorisParser.ConstantContext; import org.apache.doris.nereids.DorisParser.ConstantSeqContext; +import org.apache.doris.nereids.DorisParser.CreateMTMVContext; import org.apache.doris.nereids.DorisParser.CreateRowPolicyContext; import org.apache.doris.nereids.DorisParser.CreateTableContext; import org.apache.doris.nereids.DorisParser.CteContext; @@ -64,6 +73,7 @@ import org.apache.doris.nereids.DorisParser.DecimalLiteralContext; import org.apache.doris.nereids.DorisParser.DeleteContext; import org.apache.doris.nereids.DorisParser.DereferenceContext; +import org.apache.doris.nereids.DorisParser.DropMTMVContext; import org.apache.doris.nereids.DorisParser.ElementAtContext; import org.apache.doris.nereids.DorisParser.ExistContext; import org.apache.doris.nereids.DorisParser.ExplainContext; @@ -98,6 +108,7 @@ import org.apache.doris.nereids.DorisParser.MapLiteralContext; import org.apache.doris.nereids.DorisParser.MultiStatementsContext; import org.apache.doris.nereids.DorisParser.MultipartIdentifierContext; +import org.apache.doris.nereids.DorisParser.MvRefreshUnitContext; import org.apache.doris.nereids.DorisParser.NamedExpressionContext; import org.apache.doris.nereids.DorisParser.NamedExpressionSeqContext; import org.apache.doris.nereids.DorisParser.NullLiteralContext; @@ -118,6 +129,10 @@ import org.apache.doris.nereids.DorisParser.QueryContext; import org.apache.doris.nereids.DorisParser.QueryOrganizationContext; import org.apache.doris.nereids.DorisParser.QueryTermContext; +import org.apache.doris.nereids.DorisParser.RefreshMTMVContext; +import org.apache.doris.nereids.DorisParser.RefreshMethodContext; +import org.apache.doris.nereids.DorisParser.RefreshScheduleContext; +import org.apache.doris.nereids.DorisParser.RefreshTriggerContext; import org.apache.doris.nereids.DorisParser.RegularQuerySpecificationContext; import org.apache.doris.nereids.DorisParser.RelationContext; import org.apache.doris.nereids.DorisParser.RollupDefContext; @@ -130,6 +145,8 @@ import org.apache.doris.nereids.DorisParser.SelectColumnClauseContext; import org.apache.doris.nereids.DorisParser.SelectHintContext; import org.apache.doris.nereids.DorisParser.SetOperationContext; +import org.apache.doris.nereids.DorisParser.SimpleColumnDefContext; +import org.apache.doris.nereids.DorisParser.SimpleColumnDefsContext; import org.apache.doris.nereids.DorisParser.SingleStatementContext; import org.apache.doris.nereids.DorisParser.SortClauseContext; import org.apache.doris.nereids.DorisParser.SortItemContext; @@ -290,30 +307,43 @@ import org.apache.doris.nereids.trees.plans.Plan; 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.AlterMTMVCommand; import org.apache.doris.nereids.trees.plans.commands.Command; +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.CreateTableCommand; import org.apache.doris.nereids.trees.plans.commands.DeleteCommand; +import org.apache.doris.nereids.trees.plans.commands.DropMTMVCommand; import org.apache.doris.nereids.trees.plans.commands.ExplainCommand; import org.apache.doris.nereids.trees.plans.commands.ExplainCommand.ExplainLevel; import org.apache.doris.nereids.trees.plans.commands.ExportCommand; import org.apache.doris.nereids.trees.plans.commands.InsertIntoTableCommand; import org.apache.doris.nereids.trees.plans.commands.LoadCommand; +import org.apache.doris.nereids.trees.plans.commands.RefreshMTMVCommand; import org.apache.doris.nereids.trees.plans.commands.UpdateCommand; +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.BulkLoadDataDesc; import org.apache.doris.nereids.trees.plans.commands.info.BulkStorageDesc; 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.DefaultValue; import org.apache.doris.nereids.trees.plans.commands.info.DistributionDescriptor; +import org.apache.doris.nereids.trees.plans.commands.info.DropMTMVInfo; import org.apache.doris.nereids.trees.plans.commands.info.FixedRangePartition; import org.apache.doris.nereids.trees.plans.commands.info.InPartition; import org.apache.doris.nereids.trees.plans.commands.info.IndexDefinition; import org.apache.doris.nereids.trees.plans.commands.info.LessThanPartition; import org.apache.doris.nereids.trees.plans.commands.info.PartitionDefinition; import org.apache.doris.nereids.trees.plans.commands.info.PartitionDefinition.MaxValue; +import org.apache.doris.nereids.trees.plans.commands.info.RefreshMTMVInfo; import org.apache.doris.nereids.trees.plans.commands.info.RollupDefinition; +import org.apache.doris.nereids.trees.plans.commands.info.SimpleColumnDefinition; import org.apache.doris.nereids.trees.plans.commands.info.StepPartition; +import org.apache.doris.nereids.trees.plans.commands.info.TableNameInfo; import org.apache.doris.nereids.trees.plans.logical.LogicalAggregate; import org.apache.doris.nereids.trees.plans.logical.LogicalCTE; import org.apache.doris.nereids.trees.plans.logical.LogicalExcept; @@ -344,6 +374,7 @@ import org.apache.doris.policy.PolicyTypeEnum; import org.apache.doris.qe.ConnectContext; import org.apache.doris.qe.SqlModeHelper; +import org.apache.doris.scheduler.common.IntervalUnit; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -441,6 +472,141 @@ public LogicalPlan visitInsertIntoQuery(InsertIntoQueryContext ctx) { return new InsertIntoTableCommand(sink, Optional.ofNullable(labelName), isOverwrite); } + @Override + public CreateMTMVCommand visitCreateMTMV(CreateMTMVContext ctx) { + List nameParts = visitMultipartIdentifier(ctx.mvName); + + BuildMode buildMode = visitBuildMode(ctx.buildMode()); + RefreshMethod refreshMethod = visitRefreshMethod(ctx.refreshMethod()); + MTMVRefreshTriggerInfo refreshTriggerInfo = visitRefreshTrigger(ctx.refreshTrigger()); + LogicalPlan logicalPlan = visitQuery(ctx.query()); + String querySql = getOriginSql(ctx.query()); + + boolean isHash = ctx.HASH() != null || ctx.RANDOM() == null; + int bucketNum = FeConstants.default_bucket_num; + if (isHash && ctx.INTEGER_VALUE() != null) { + bucketNum = Integer.parseInt(ctx.INTEGER_VALUE().getText()); + } + DistributionDescriptor desc = new DistributionDescriptor(isHash, ctx.AUTO() != null, + bucketNum, ctx.HASH() != null ? visitIdentifierList(ctx.hashKeys) : null); + Map properties = ctx.propertyClause() != null + ? Maps.newHashMap(visitPropertyClause(ctx.propertyClause())) : Maps.newHashMap(); + return new CreateMTMVCommand(new CreateMTMVInfo(ctx.EXISTS() != null, new TableNameInfo(nameParts), + ctx.keys != null ? visitIdentifierList(ctx.keys) : ImmutableList.of(), + ctx.STRING_LITERAL() != null ? ctx.STRING_LITERAL().getText() : null, + desc, properties, logicalPlan, querySql, + new MTMVRefreshInfo(buildMode, refreshMethod, refreshTriggerInfo), + ctx.cols == null ? Lists.newArrayList() : visitSimpleColumnDefs(ctx.cols) + )); + } + + @Override + public List visitSimpleColumnDefs(SimpleColumnDefsContext ctx) { + if (ctx == null) { + return null; + } + return ctx.cols.stream() + .map(this::visitSimpleColumnDef) + .collect(ImmutableList.toImmutableList()); + } + + @Override + public SimpleColumnDefinition visitSimpleColumnDef(SimpleColumnDefContext ctx) { + return new SimpleColumnDefinition(ctx.colName.getText().toLowerCase(), + ctx.STRING_LITERAL() != null ? ctx.STRING_LITERAL().getText() : null); + } + + /** + * get originSql + * + * @param ctx context + * @return originSql + */ + private String getOriginSql(ParserRuleContext ctx) { + int startIndex = ctx.start.getStartIndex(); + int stopIndex = ctx.stop.getStopIndex(); + org.antlr.v4.runtime.misc.Interval interval = new org.antlr.v4.runtime.misc.Interval(startIndex, stopIndex); + return ctx.start.getInputStream().getText(interval); + } + + @Override + public MTMVRefreshTriggerInfo visitRefreshTrigger(RefreshTriggerContext ctx) { + if (ctx.MANUAL() != null) { + return new MTMVRefreshTriggerInfo(RefreshTrigger.MANUAL); + } + if (ctx.SCHEDULE() != null) { + return new MTMVRefreshTriggerInfo(RefreshTrigger.SCHEDULE, visitRefreshSchedule(ctx.refreshSchedule())); + } + return new MTMVRefreshTriggerInfo(RefreshTrigger.MANUAL); + } + + @Override + public MTMVRefreshSchedule visitRefreshSchedule(RefreshScheduleContext ctx) { + int interval = Integer.parseInt(ctx.INTEGER_VALUE().getText()); + String startTime = ctx.STARTS() == null ? null + : ctx.STRING_LITERAL().getText().substring(1, ctx.STRING_LITERAL().getText().length() - 1); + IntervalUnit unit = visitMvRefreshUnit(ctx.mvRefreshUnit()); + return new MTMVRefreshSchedule(startTime, interval, unit); + } + + @Override + public IntervalUnit visitMvRefreshUnit(MvRefreshUnitContext ctx) { + return IntervalUnit.valueOf(ctx.getText().toUpperCase()); + } + + @Override + public RefreshMethod visitRefreshMethod(RefreshMethodContext ctx) { + if (ctx == null) { + return RefreshMethod.COMPLETE; + } + return RefreshMethod.valueOf(ctx.getText().toUpperCase()); + } + + @Override + public BuildMode visitBuildMode(BuildModeContext ctx) { + if (ctx.DEFERRED() != null) { + return BuildMode.DEFERRED; + } else if (ctx.IMMEDIATE() != null) { + return BuildMode.IMMEDIATE; + } + return BuildMode.IMMEDIATE; + } + + @Override + public RefreshMTMVCommand visitRefreshMTMV(RefreshMTMVContext ctx) { + List nameParts = visitMultipartIdentifier(ctx.mvName); + return new RefreshMTMVCommand(new RefreshMTMVInfo(new TableNameInfo(nameParts))); + } + + @Override + public DropMTMVCommand visitDropMTMV(DropMTMVContext ctx) { + List nameParts = visitMultipartIdentifier(ctx.mvName); + return new DropMTMVCommand(new DropMTMVInfo(new TableNameInfo(nameParts), ctx.EXISTS() != null)); + } + + @Override + public AlterMTMVCommand visitAlterMTMV(AlterMTMVContext ctx) { + List nameParts = visitMultipartIdentifier(ctx.mvName); + TableNameInfo mvName = new TableNameInfo(nameParts); + AlterMTMVInfo alterMTMVInfo = null; + if (ctx.RENAME() != null) { + alterMTMVInfo = new AlterMTMVRenameInfo(mvName, ctx.newName.getText()); + } else if (ctx.REFRESH() != null) { + MTMVRefreshInfo refreshInfo = new MTMVRefreshInfo(); + if (ctx.refreshMethod() != null) { + refreshInfo.setRefreshMethod(visitRefreshMethod(ctx.refreshMethod())); + } + if (ctx.refreshTrigger() != null) { + refreshInfo.setRefreshTriggerInfo(visitRefreshTrigger(ctx.refreshTrigger())); + } + alterMTMVInfo = new AlterMTMVRefreshInfo(mvName, refreshInfo); + } else if (ctx.SET() != null) { + alterMTMVInfo = new AlterMTMVPropertyInfo(mvName, + Maps.newHashMap(visitPropertyItemList(ctx.fileProperties))); + } + return new AlterMTMVCommand(alterMTMVInfo); + } + @Override public LogicalPlan visitUpdate(UpdateContext ctx) { LogicalPlan query = LogicalPlanBuilderAssistant.withCheckPolicy(new UnboundRelation( 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 c1ed61ce1ce987..c2db676a1a7eca 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 @@ -123,5 +123,9 @@ public enum PlanType { INSERT_INTO_TABLE_COMMAND, LOAD_COMMAND, SELECT_INTO_OUTFILE_COMMAND, - UPDATE_COMMAND + UPDATE_COMMAND, + CREATE_MTMV_COMMAND, + ALTER_MTMV_COMMAND, + REFRESH_MTMV_COMMAND, + DROP_MTMV_COMMAND } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/AlterMTMVCommand.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/AlterMTMVCommand.java new file mode 100644 index 00000000000000..9aadf0f1cf0c6b --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/AlterMTMVCommand.java @@ -0,0 +1,58 @@ +// 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.nereids.trees.plans.PlanType; +import org.apache.doris.nereids.trees.plans.commands.info.AlterMTMVInfo; +import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor; +import org.apache.doris.qe.ConnectContext; +import org.apache.doris.qe.StmtExecutor; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.Objects; + +/** + * alter multi table materialized view + */ +public class AlterMTMVCommand extends Command implements ForwardWithSync { + + public static final Logger LOG = LogManager.getLogger(AlterMTMVCommand.class); + private final AlterMTMVInfo alterMTMVInfo; + + /** + * constructor + */ + public AlterMTMVCommand(AlterMTMVInfo alterMTMVInfo) { + super(PlanType.ALTER_MTMV_COMMAND); + this.alterMTMVInfo = Objects.requireNonNull(alterMTMVInfo, "require AlterMTMVInfo object"); + } + + @Override + public void run(ConnectContext ctx, StmtExecutor executor) throws Exception { + alterMTMVInfo.analyze(ctx); + alterMTMVInfo.run(); + } + + @Override + public R accept(PlanVisitor visitor, C context) { + return visitor.visitAlterMTMVCommand(this, context); + } + +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CreateMTMVCommand.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CreateMTMVCommand.java new file mode 100644 index 00000000000000..76a646fc819f92 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CreateMTMVCommand.java @@ -0,0 +1,59 @@ +// 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.nereids.exceptions.AnalysisException; +import org.apache.doris.nereids.trees.plans.PlanType; +import org.apache.doris.nereids.trees.plans.commands.info.CreateMTMVInfo; +import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor; +import org.apache.doris.qe.ConnectContext; +import org.apache.doris.qe.StmtExecutor; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.Objects; + +/** + * create multi table materialized view + */ +public class CreateMTMVCommand extends Command implements ForwardWithSync { + + public static final Logger LOG = LogManager.getLogger(CreateMTMVCommand.class); + private final CreateMTMVInfo createMTMVInfo; + + /** + * constructor + */ + public CreateMTMVCommand(CreateMTMVInfo createMTMVInfo) { + super(PlanType.CREATE_MTMV_COMMAND); + this.createMTMVInfo = Objects.requireNonNull(createMTMVInfo, "require CreateMTMVInfo object"); + } + + @Override + public void run(ConnectContext ctx, StmtExecutor executor) throws Exception { + createMTMVInfo.analyze(ctx); + throw new AnalysisException("current not support."); + } + + @Override + public R accept(PlanVisitor visitor, C context) { + return visitor.visitCreateMTMVCommand(this, context); + } + +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/DropMTMVCommand.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/DropMTMVCommand.java new file mode 100644 index 00000000000000..0a6494edeac586 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/DropMTMVCommand.java @@ -0,0 +1,50 @@ +// 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.nereids.exceptions.AnalysisException; +import org.apache.doris.nereids.trees.plans.PlanType; +import org.apache.doris.nereids.trees.plans.commands.info.DropMTMVInfo; +import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor; +import org.apache.doris.qe.ConnectContext; +import org.apache.doris.qe.StmtExecutor; + +import java.util.Objects; + +/** + * refresh mtmv + */ +public class DropMTMVCommand extends Command implements ForwardWithSync { + private final DropMTMVInfo dropMTMVInfo; + + public DropMTMVCommand(DropMTMVInfo dropMTMVInfo) { + super(PlanType.DROP_MTMV_COMMAND); + this.dropMTMVInfo = Objects.requireNonNull(dropMTMVInfo, "require dropMTMVInfo object"); + } + + @Override + public void run(ConnectContext ctx, StmtExecutor executor) throws Exception { + dropMTMVInfo.analyze(ctx); + throw new AnalysisException("current not support."); + } + + @Override + public R accept(PlanVisitor visitor, C context) { + return visitor.visitDropMTMVCommand(this, context); + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/RefreshMTMVCommand.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/RefreshMTMVCommand.java new file mode 100644 index 00000000000000..352801f5d83a46 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/RefreshMTMVCommand.java @@ -0,0 +1,50 @@ +// 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.nereids.exceptions.AnalysisException; +import org.apache.doris.nereids.trees.plans.PlanType; +import org.apache.doris.nereids.trees.plans.commands.info.RefreshMTMVInfo; +import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor; +import org.apache.doris.qe.ConnectContext; +import org.apache.doris.qe.StmtExecutor; + +import java.util.Objects; + +/** + * refresh mtmv + */ +public class RefreshMTMVCommand extends Command implements ForwardWithSync { + private final RefreshMTMVInfo refreshMTMVInfo; + + public RefreshMTMVCommand(RefreshMTMVInfo refreshMTMVInfo) { + super(PlanType.REFRESH_MTMV_COMMAND); + this.refreshMTMVInfo = Objects.requireNonNull(refreshMTMVInfo, "require refreshMTMVInfo object"); + } + + @Override + public void run(ConnectContext ctx, StmtExecutor executor) throws Exception { + refreshMTMVInfo.analyze(ctx); + throw new AnalysisException("current not support."); + } + + @Override + public R accept(PlanVisitor visitor, C context) { + return visitor.visitRefreshMTMVCommand(this, context); + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/AlterMTMVInfo.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/AlterMTMVInfo.java new file mode 100644 index 00000000000000..542ebca6ac083c --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/AlterMTMVInfo.java @@ -0,0 +1,62 @@ +// 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.catalog.Env; +import org.apache.doris.common.ErrorCode; +import org.apache.doris.common.UserException; +import org.apache.doris.mysql.privilege.PrivPredicate; +import org.apache.doris.nereids.exceptions.AnalysisException; +import org.apache.doris.qe.ConnectContext; + +import java.util.Objects; + +/** + * MTMV info in alter MTMV. + */ +public abstract class AlterMTMVInfo { + protected final TableNameInfo mvName; + + /** + * constructor for alter MTMV + */ + public AlterMTMVInfo(TableNameInfo mvName) { + this.mvName = Objects.requireNonNull(mvName, "require mvName object"); + } + + /** + * analyze alter table info + */ + public void analyze(ConnectContext ctx) throws AnalysisException { + mvName.analyze(ctx); + if (!Env.getCurrentEnv().getAccessManager().checkTblPriv(ConnectContext.get(), mvName.getDb(), + mvName.getTbl(), PrivPredicate.ALTER)) { + String message = ErrorCode.ERR_TABLEACCESS_DENIED_ERROR.formatErrorMsg("ALTER", + ConnectContext.get().getQualifiedUser(), ConnectContext.get().getRemoteIP(), + mvName.getDb() + ": " + mvName.getTbl()); + throw new AnalysisException(message); + } + } + + public abstract void run() throws UserException; + + public TableNameInfo getMvName() { + return mvName; + } + +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/AlterMTMVPropertyInfo.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/AlterMTMVPropertyInfo.java new file mode 100644 index 00000000000000..a7ddfb8f83c544 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/AlterMTMVPropertyInfo.java @@ -0,0 +1,53 @@ +// 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.common.UserException; +import org.apache.doris.nereids.exceptions.AnalysisException; +import org.apache.doris.qe.ConnectContext; + +import java.util.Map; +import java.util.Objects; + +/** + * rename + */ +public class AlterMTMVPropertyInfo extends AlterMTMVInfo { + private final Map properties; + + /** + * constructor for alter MTMV + */ + public AlterMTMVPropertyInfo(TableNameInfo mvName, Map properties) { + super(mvName); + this.properties = Objects.requireNonNull(properties, "require properties object"); + } + + public void analyze(ConnectContext ctx) throws AnalysisException { + super.analyze(ctx); + } + + @Override + public void run() throws UserException { + throw new org.apache.doris.nereids.exceptions.AnalysisException("current not support."); + } + + public Map getProperties() { + return properties; + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/AlterMTMVRefreshInfo.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/AlterMTMVRefreshInfo.java new file mode 100644 index 00000000000000..b54bba1ece35dd --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/AlterMTMVRefreshInfo.java @@ -0,0 +1,54 @@ +// 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.common.UserException; +import org.apache.doris.mtmv.MTMVRefreshInfo; +import org.apache.doris.nereids.exceptions.AnalysisException; +import org.apache.doris.qe.ConnectContext; + +import java.util.Objects; + +/** + * rename + */ +public class AlterMTMVRefreshInfo extends AlterMTMVInfo { + private final MTMVRefreshInfo refreshInfo; + + /** + * constructor for alter MTMV + */ + public AlterMTMVRefreshInfo(TableNameInfo mvName, MTMVRefreshInfo refreshInfo) { + super(mvName); + this.refreshInfo = Objects.requireNonNull(refreshInfo, "require refreshInfo object"); + } + + public void analyze(ConnectContext ctx) throws AnalysisException { + super.analyze(ctx); + refreshInfo.validate(); + } + + @Override + public void run() throws UserException { + throw new AnalysisException("current not support."); + } + + public MTMVRefreshInfo getRefreshInfo() { + return refreshInfo; + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/AlterMTMVRenameInfo.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/AlterMTMVRenameInfo.java new file mode 100644 index 00000000000000..c9e09e29187438 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/AlterMTMVRenameInfo.java @@ -0,0 +1,59 @@ +// 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.common.DdlException; +import org.apache.doris.common.FeNameFormat; +import org.apache.doris.nereids.exceptions.AnalysisException; +import org.apache.doris.qe.ConnectContext; + +import java.util.Objects; + +/** + * rename + */ +public class AlterMTMVRenameInfo extends AlterMTMVInfo { + private final String newName; + + /** + * constructor for alter MTMV + */ + public AlterMTMVRenameInfo(TableNameInfo mvName, String newName) { + super(mvName); + this.newName = Objects.requireNonNull(newName, "require newName object"); + } + + /** + * analyze + * @param ctx ctx + * @throws AnalysisException AnalysisException + */ + public void analyze(ConnectContext ctx) throws AnalysisException { + super.analyze(ctx); + try { + FeNameFormat.checkTableName(newName); + } catch (org.apache.doris.common.AnalysisException e) { + throw new AnalysisException(e.getMessage(), e); + } + } + + @Override + public void run() throws DdlException { + throw new AnalysisException("current not support."); + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/CreateMTMVInfo.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/CreateMTMVInfo.java new file mode 100644 index 00000000000000..1b255adc528ccc --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/CreateMTMVInfo.java @@ -0,0 +1,82 @@ +// 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.mtmv.EnvInfo; +import org.apache.doris.mtmv.MTMVRefreshInfo; +import org.apache.doris.nereids.trees.plans.logical.LogicalPlan; +import org.apache.doris.nereids.util.Utils; +import org.apache.doris.qe.ConnectContext; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; + +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * MTMV info in creating MTMV. + */ +public class CreateMTMVInfo { + private final boolean ifNotExists; + private final TableNameInfo mvName; + private List keys; + private final String comment; + private final DistributionDescriptor distribution; + private Map properties; + private Map mvProperties = Maps.newHashMap(); + + private final LogicalPlan logicalQuery; + private final String querySql; + private final MTMVRefreshInfo refreshInfo; + private final List columns = Lists.newArrayList(); + private final List simpleColumnDefinitions; + private final EnvInfo envInfo; + + /** + * constructor for create MTMV + */ + public CreateMTMVInfo(boolean ifNotExists, TableNameInfo mvName, + List keys, String comment, + DistributionDescriptor distribution, Map properties, + LogicalPlan logicalQuery, String querySql, + MTMVRefreshInfo refreshInfo, + List simpleColumnDefinitions) { + this.ifNotExists = Objects.requireNonNull(ifNotExists, "require ifNotExists object"); + this.mvName = Objects.requireNonNull(mvName, "require mvName object"); + this.keys = Utils.copyRequiredList(keys); + this.comment = comment; + this.distribution = Objects.requireNonNull(distribution, "require distribution object"); + this.properties = Objects.requireNonNull(properties, "require properties object"); + this.logicalQuery = Objects.requireNonNull(logicalQuery, "require logicalQuery object"); + this.querySql = Objects.requireNonNull(querySql, "require querySql object"); + this.refreshInfo = Objects.requireNonNull(refreshInfo, "require refreshInfo object"); + this.simpleColumnDefinitions = Objects + .requireNonNull(simpleColumnDefinitions, "require simpleColumnDefinitions object"); + this.envInfo = new EnvInfo(ConnectContext.get().getDefaultCatalog(), ConnectContext.get().getDatabase()); + } + + /** + * analyze create table info + */ + public void analyze(ConnectContext ctx) { + + } + +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/DropMTMVInfo.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/DropMTMVInfo.java new file mode 100644 index 00000000000000..958d6315c39dd8 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/DropMTMVInfo.java @@ -0,0 +1,52 @@ +// 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.qe.ConnectContext; + +import java.util.Objects; + +/** + * drop mtmv info + */ +public class DropMTMVInfo { + private final TableNameInfo mvName; + private final boolean ifExists; + + public DropMTMVInfo(TableNameInfo mvName, boolean ifExists) { + this.mvName = Objects.requireNonNull(mvName, "require mvName object"); + this.ifExists = Objects.requireNonNull(ifExists, "require ifExists object"); + } + + /** + * analyze drop info + * + * @param ctx ConnectContext + */ + public void analyze(ConnectContext ctx) { + } + + /** + * getMvName + * + * @return TableNameInfo + */ + public TableNameInfo getMvName() { + return mvName; + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/RefreshMTMVInfo.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/RefreshMTMVInfo.java new file mode 100644 index 00000000000000..8439ed2ad0acfb --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/RefreshMTMVInfo.java @@ -0,0 +1,48 @@ +// 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.qe.ConnectContext; + +import java.util.Objects; + +/** + * refresh mtmv info + */ +public class RefreshMTMVInfo { + private final TableNameInfo mvName; + + public RefreshMTMVInfo(TableNameInfo mvName) { + this.mvName = Objects.requireNonNull(mvName, "require mvName object"); + } + + /** + * analyze refresh info + * @param ctx ConnectContext + */ + public void analyze(ConnectContext ctx) { + } + + /** + * getMvName + * @return TableNameInfo + */ + public TableNameInfo getMvName() { + return mvName; + } +} 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 new file mode 100644 index 00000000000000..51080bf45d2372 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/SimpleColumnDefinition.java @@ -0,0 +1,42 @@ +// 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; + +/** + * column def for mv + */ +public class SimpleColumnDefinition { + private final String name; + private final String comment; + + /** + * constructor + */ + public SimpleColumnDefinition(String name, String comment) { + this.name = name; + this.comment = comment; + } + + public String getName() { + return name; + } + + public String getComment() { + return comment; + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/TableNameInfo.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/TableNameInfo.java new file mode 100644 index 00000000000000..d565b4f318be69 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/TableNameInfo.java @@ -0,0 +1,168 @@ +// 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. +// This file is copied from +// https://github.com/apache/impala/blob/branch-2.9.0/fe/src/main/java/org/apache/impala/TableName.java +// and modified by Doris + +package org.apache.doris.nereids.trees.plans.commands.info; + +import org.apache.doris.analysis.TableName; +import org.apache.doris.catalog.Env; +import org.apache.doris.cluster.ClusterNamespace; +import org.apache.doris.common.io.Text; +import org.apache.doris.common.io.Writable; +import org.apache.doris.datasource.InternalCatalog; +import org.apache.doris.nereids.exceptions.AnalysisException; +import org.apache.doris.persist.gson.GsonUtils; +import org.apache.doris.qe.ConnectContext; + +import com.google.common.base.Preconditions; +import com.google.common.base.Strings; +import com.google.gson.annotations.SerializedName; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.List; +import java.util.Objects; + +/** + * table name info + */ +public class TableNameInfo implements Writable { + @SerializedName(value = "c") + private String ctl; + @SerializedName(value = "t") + private String tbl; + @SerializedName(value = "d") + private String db; + + public TableNameInfo() { + + } + + /** + * TableNameInfo + * @param parts like [ctl1,db1,tbl1] or [db1,tbl1] or [tbl1] + */ + public TableNameInfo(List parts) { + Objects.requireNonNull(parts, "require parts object"); + int size = parts.size(); + Preconditions.checkArgument(size > 0, "table name can't be empty"); + tbl = parts.get(size - 1); + if (Env.isStoredTableNamesLowerCase() && !Strings.isNullOrEmpty(tbl)) { + tbl = tbl.toLowerCase(); + } + if (size >= 2) { + db = parts.get(size - 2); + } + if (size >= 3) { + ctl = parts.get(size - 3); + } + } + + /** + * TableNameInfo + * @param db dbName + * @param tbl tblName + */ + public TableNameInfo(String db, String tbl) { + Objects.requireNonNull(tbl, "require tbl object"); + Objects.requireNonNull(db, "require db object"); + this.ctl = InternalCatalog.INTERNAL_CATALOG_NAME; + this.tbl = tbl; + if (Env.isStoredTableNamesLowerCase()) { + this.tbl = tbl.toLowerCase(); + } + this.db = db; + } + + /** + * analyze tableNameInfo + * @param ctx ctx + */ + public void analyze(ConnectContext ctx) { + if (Strings.isNullOrEmpty(ctl)) { + ctl = ctx.getDefaultCatalog(); + if (Strings.isNullOrEmpty(ctl)) { + ctl = InternalCatalog.INTERNAL_CATALOG_NAME; + } + } + if (Strings.isNullOrEmpty(db)) { + db = ClusterNamespace.getFullName(ctx.getClusterName(), ctx.getDatabase()); + if (Strings.isNullOrEmpty(db)) { + throw new AnalysisException("No database selected"); + } + } else { + db = ClusterNamespace.getFullName(ctx.getClusterName(), db); + } + + if (Strings.isNullOrEmpty(tbl)) { + throw new AnalysisException("Table name is null"); + } + } + + /** + * get catalog name + * @return ctlName + */ + public String getCtl() { + return ctl; + } + + /** + * get db name + * @return dbName + */ + public String getDb() { + return db; + } + + /** + * get table name + * @return tableName + */ + public String getTbl() { + return tbl; + } + + /** + * transferToTableName + * @return TableName + */ + public TableName transferToTableName() { + return new TableName(ctl, db, tbl); + } + + @Override + public void write(DataOutput out) throws IOException { + String json = GsonUtils.GSON.toJson(this); + Text.writeString(out, json); + } + + /** + * read from json + * @param in DataInput + * @throws IOException IOException + */ + public void readFields(DataInput in) throws IOException { + TableNameInfo fromJson = GsonUtils.GSON.fromJson(Text.readString(in), TableNameInfo.class); + ctl = fromJson.ctl; + db = fromJson.db; + tbl = fromJson.tbl; + } +} 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 c055da5735b4be..4e42b6f6593303 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 @@ -17,14 +17,18 @@ package org.apache.doris.nereids.trees.plans.visitor; +import org.apache.doris.nereids.trees.plans.commands.AlterMTMVCommand; import org.apache.doris.nereids.trees.plans.commands.Command; +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.CreateTableCommand; import org.apache.doris.nereids.trees.plans.commands.DeleteCommand; +import org.apache.doris.nereids.trees.plans.commands.DropMTMVCommand; import org.apache.doris.nereids.trees.plans.commands.ExplainCommand; import org.apache.doris.nereids.trees.plans.commands.ExportCommand; import org.apache.doris.nereids.trees.plans.commands.InsertIntoTableCommand; import org.apache.doris.nereids.trees.plans.commands.LoadCommand; +import org.apache.doris.nereids.trees.plans.commands.RefreshMTMVCommand; import org.apache.doris.nereids.trees.plans.commands.UpdateCommand; /** CommandVisitor. */ @@ -64,4 +68,20 @@ default R visitExportCommand(ExportCommand exportCommand, C context) { default R visitCreateTableCommand(CreateTableCommand createTableCommand, C context) { return visitCommand(createTableCommand, context); } + + default R visitCreateMTMVCommand(CreateMTMVCommand createMTMVCommand, C context) { + return visitCommand(createMTMVCommand, context); + } + + default R visitAlterMTMVCommand(AlterMTMVCommand alterMTMVCommand, C context) { + return visitCommand(alterMTMVCommand, context); + } + + default R visitRefreshMTMVCommand(RefreshMTMVCommand refreshMTMVCommand, C context) { + return visitCommand(refreshMTMVCommand, context); + } + + default R visitDropMTMVCommand(DropMTMVCommand dropMTMVCommand, C context) { + return visitCommand(dropMTMVCommand, context); + } }