From 077fda4259907125432f6f894315f9ad951c8357 Mon Sep 17 00:00:00 2001 From: zhangdong <493738387@qq.com> Date: Wed, 3 Jul 2024 22:48:43 +0800 Subject: [PATCH] [enhance](mtmv)show create materialized view (#36188) (#37125) pick: https://github.com/apache/doris/pull/36188 --- .../org/apache/doris/nereids/DorisParser.g4 | 1 + fe/fe-core/src/main/cup/sql_parser.cup | 4 + .../doris/analysis/ShowCreateMTMVStmt.java | 95 ++++ .../doris/analysis/ShowCreateTableStmt.java | 6 + .../java/org/apache/doris/catalog/Env.java | 499 ++++++++++-------- .../nereids/parser/LogicalPlanBuilder.java | 9 + .../doris/nereids/trees/plans/PlanType.java | 1 + .../plans/commands/ShowCreateMTMVCommand.java | 49 ++ .../commands/info/ShowCreateMTMVInfo.java | 106 ++++ .../trees/plans/visitor/CommandVisitor.java | 5 + .../org/apache/doris/qe/ShowExecutor.java | 21 + .../org/apache/doris/qe/StmtExecutor.java | 9 + .../test_alter_distribution_type_mtmv.groovy | 2 +- .../mtmv_p0/test_bloom_filter_mtmv.groovy | 6 +- .../suites/mtmv_p0/test_build_mtmv.groovy | 8 + .../mtmv_p0/test_compression_mtmv.groovy | 2 +- .../mtmv_p0/test_show_create_mtmv.groovy | 104 ++++ 17 files changed, 713 insertions(+), 214 deletions(-) create mode 100644 fe/fe-core/src/main/java/org/apache/doris/analysis/ShowCreateMTMVStmt.java create mode 100644 fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowCreateMTMVCommand.java create mode 100644 fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/ShowCreateMTMVInfo.java create mode 100644 regression-test/suites/mtmv_p0/test_show_create_mtmv.groovy 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 d2a947b725..809538ca8a 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 @@ -114,6 +114,7 @@ statementBase | PAUSE MATERIALIZED VIEW JOB ON mvName=multipartIdentifier #pauseMTMV | RESUME MATERIALIZED VIEW JOB ON mvName=multipartIdentifier #resumeMTMV | CANCEL MATERIALIZED VIEW TASK taskId=INTEGER_VALUE ON mvName=multipartIdentifier #cancelMTMVTask + | SHOW CREATE MATERIALIZED VIEW mvName=multipartIdentifier #showCreateMTMV | ALTER TABLE table=multipartIdentifier ADD CONSTRAINT constraintName=errorCapturingIdentifier constraint #addConstraint diff --git a/fe/fe-core/src/main/cup/sql_parser.cup b/fe/fe-core/src/main/cup/sql_parser.cup index 871c0261e0..30d7963d8a 100644 --- a/fe/fe-core/src/main/cup/sql_parser.cup +++ b/fe/fe-core/src/main/cup/sql_parser.cup @@ -4052,6 +4052,10 @@ show_param ::= {: RESULT = new ShowCreateTableStmt(table, true, false); :} + | KW_CREATE KW_MATERIALIZED KW_VIEW table_name:table + {: + RESULT = new ShowCreateMTMVStmt(table); + :} /* Create database */ | KW_CREATE KW_DATABASE db_name:db {: diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowCreateMTMVStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowCreateMTMVStmt.java new file mode 100644 index 0000000000..fb8e69e779 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowCreateMTMVStmt.java @@ -0,0 +1,95 @@ +// 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.analysis; + +import org.apache.doris.catalog.Column; +import org.apache.doris.catalog.Env; +import org.apache.doris.catalog.MTMV; +import org.apache.doris.catalog.ScalarType; +import org.apache.doris.catalog.TableIf; +import org.apache.doris.common.AnalysisException; +import org.apache.doris.common.ErrorCode; +import org.apache.doris.common.ErrorReport; +import org.apache.doris.mysql.privilege.PrivPredicate; +import org.apache.doris.qe.ConnectContext; +import org.apache.doris.qe.ShowResultSetMetaData; + +// SHOW CREATE Materialized View statement. +public class ShowCreateMTMVStmt extends ShowStmt { + private static final ShowResultSetMetaData META_DATA = + ShowResultSetMetaData.builder() + .addColumn(new Column("Materialized View", ScalarType.createVarchar(20))) + .addColumn(new Column("Create Materialized View", ScalarType.createVarchar(30))) + .build(); + + private TableName tbl; + + public ShowCreateMTMVStmt(TableName tbl) { + this.tbl = tbl; + } + + + public String getCtl() { + return tbl.getCtl(); + } + + public String getDb() { + return tbl.getDb(); + } + + public String getTable() { + return tbl.getTbl(); + } + + @Override + public void analyze(Analyzer analyzer) throws AnalysisException { + if (tbl == null) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_NO_TABLES_USED); + } + tbl.analyze(analyzer); + + TableIf tableIf = Env.getCurrentEnv().getCatalogMgr() + .getCatalogOrAnalysisException(tbl.getCtl()) + .getDbOrAnalysisException(tbl.getDb()).getTableOrAnalysisException(tbl.getTbl()); + + if (!(tableIf instanceof MTMV)) { + ErrorReport.reportAnalysisException("only support async materialized view"); + } + + if (!Env.getCurrentEnv().getAccessManager().checkTblPriv(ConnectContext.get(), tbl.getCtl(), tbl.getDb(), + tbl.getTbl(), PrivPredicate.SHOW)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_TABLE_ACCESS_DENIED_ERROR, + PrivPredicate.SHOW.getPrivs().toString(), getTable()); + } + } + + @Override + public String toSql() { + return "SHOW CREATE MATERIALIZED VIEW " + tbl; + } + + @Override + public String toString() { + return toSql(); + } + + @Override + public ShowResultSetMetaData getMetaData() { + return META_DATA; + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowCreateTableStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowCreateTableStmt.java index ea3b442fbc..1a8ec38080 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowCreateTableStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowCreateTableStmt.java @@ -19,6 +19,7 @@ package org.apache.doris.analysis; import org.apache.doris.catalog.Column; import org.apache.doris.catalog.Env; +import org.apache.doris.catalog.MTMV; import org.apache.doris.catalog.ScalarType; import org.apache.doris.catalog.TableIf; import org.apache.doris.catalog.View; @@ -109,6 +110,11 @@ public class ShowCreateTableStmt extends ShowStmt { .getCatalogOrAnalysisException(tbl.getCtl()) .getDbOrAnalysisException(tbl.getDb()).getTableOrAnalysisException(tbl.getTbl()); + if (tableIf instanceof MTMV) { + ErrorReport.reportAnalysisException("not support async materialized view, " + + "please use `show create materialized view`"); + } + PrivPredicate wanted; if (tableIf instanceof View) { wanted = PrivPredicate.SHOW_VIEW; diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java index 6f8cd9e727..dabe2131c8 100755 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java @@ -182,6 +182,8 @@ import org.apache.doris.master.PartitionInfoCollector; import org.apache.doris.meta.MetaContext; import org.apache.doris.metric.MetricRepo; import org.apache.doris.mtmv.MTMVAlterOpType; +import org.apache.doris.mtmv.MTMVPartitionInfo; +import org.apache.doris.mtmv.MTMVPartitionInfo.MTMVPartitionType; import org.apache.doris.mtmv.MTMVRefreshPartitionSnapshot; import org.apache.doris.mtmv.MTMVRelation; import org.apache.doris.mtmv.MTMVService; @@ -310,6 +312,7 @@ import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Optional; import java.util.Set; import java.util.TreeMap; @@ -3175,6 +3178,292 @@ public class Env { hidePassword, false, specificVersion, false, true); } + public static String getMTMVDdl(MTMV mtmv) { + StringBuilder sb = new StringBuilder("CREATE MATERIALIZED VIEW "); + sb.append(mtmv.getName()); + addMTMVCols(mtmv, sb); + sb.append("\n"); + sb.append(mtmv.getRefreshInfo()); + addMTMVKeyInfo(mtmv, sb); + addTableComment(mtmv, sb); + addMTMVPartitionInfo(mtmv, sb); + DistributionInfo distributionInfo = mtmv.getDefaultDistributionInfo(); + sb.append("\n").append(distributionInfo.toSql()); + // properties + sb.append("\nPROPERTIES (\n"); + addOlapTablePropertyInfo(mtmv, sb, false, false, null); + addMTMVPropertyInfo(mtmv, sb); + sb.append("\n)"); + sb.append("\nAS "); + sb.append(mtmv.getQuerySql()); + return sb.toString(); + } + + private static void addMTMVKeyInfo(MTMV mtmv, StringBuilder sb) { + if (!mtmv.isDuplicateWithoutKey()) { + String keySql = mtmv.getKeysType().toSql(); + sb.append("\n").append(keySql).append("("); + List keysColumnNames = Lists.newArrayList(); + for (Column column : mtmv.getBaseSchema()) { + if (column.isKey()) { + keysColumnNames.add("`" + column.getName() + "`"); + } + } + sb.append(Joiner.on(", ").join(keysColumnNames)).append(")"); + } + } + + private static void addMTMVPartitionInfo(MTMV mtmv, StringBuilder sb) { + MTMVPartitionInfo mvPartitionInfo = mtmv.getMvPartitionInfo(); + if (mvPartitionInfo.getPartitionType() == MTMVPartitionType.SELF_MANAGE) { + return; + } + sb.append("\n").append("PARTITION BY ("); + if (mvPartitionInfo.getPartitionType() == MTMVPartitionType.FOLLOW_BASE_TABLE) { + sb.append("`" + mvPartitionInfo.getPartitionCol() + "`"); + } else { + sb.append(mvPartitionInfo.getExpr().toSql()); + } + sb.append(")"); + } + + private static void addMTMVCols(MTMV mtmv, StringBuilder sb) { + sb.append("\n("); + List columns = mtmv.getBaseSchema(); + for (int i = 0; i < columns.size(); i++) { + if (i != 0) { + sb.append(","); + } + Column column = columns.get(i); + sb.append(column.getName()); + if (!StringUtils.isEmpty(column.getComment())) { + sb.append(" comment '"); + sb.append(column.getComment()); + sb.append("'"); + } + } + sb.append(")"); + } + + private static void addMTMVPropertyInfo(MTMV mtmv, StringBuilder sb) { + Map mvProperties = mtmv.getMvProperties(); + for (Entry entry : mvProperties.entrySet()) { + sb.append(",\n\"").append(entry.getKey()).append("\" = \""); + sb.append(entry.getValue()).append("\""); + } + } + + private static void addOlapTablePropertyInfo(OlapTable olapTable, StringBuilder sb, boolean separatePartition, + boolean getDdlForSync, List partitionId) { + // replicationNum + ReplicaAllocation replicaAlloc = olapTable.getDefaultReplicaAllocation(); + sb.append("\"").append(PropertyAnalyzer.PROPERTIES_REPLICATION_ALLOCATION).append("\" = \""); + sb.append(replicaAlloc.toCreateStmt()).append("\""); + + // min load replica num + sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_MIN_LOAD_REPLICA_NUM).append("\" = \""); + sb.append(olapTable.getMinLoadReplicaNum()).append("\""); + + // bloom filter + Set bfColumnNames = olapTable.getCopiedBfColumns(); + if (bfColumnNames != null) { + sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_BF_COLUMNS).append("\" = \""); + sb.append(Joiner.on(", ").join(olapTable.getCopiedBfColumns())).append("\""); + } + + if (separatePartition) { + // version info + sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_VERSION_INFO).append("\" = \""); + Partition partition = null; + if (olapTable.getPartitionInfo().getType() == PartitionType.UNPARTITIONED) { + partition = olapTable.getPartition(olapTable.getName()); + } else { + Preconditions.checkState(partitionId.size() == 1); + partition = olapTable.getPartition(partitionId.get(0)); + } + sb.append(partition.getVisibleVersion()).append("\""); + } + + // mark this table is being synced + sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_IS_BEING_SYNCED).append("\" = \""); + sb.append(String.valueOf(olapTable.isBeingSynced() || getDdlForSync)).append("\""); + // mark this table if it is a auto bucket table + if (getDdlForSync && olapTable.isAutoBucket()) { + sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_AUTO_BUCKET).append("\" = \""); + sb.append("true").append("\""); + } + + // colocateTable + String colocateTable = olapTable.getColocateGroup(); + if (colocateTable != null) { + sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_COLOCATE_WITH).append("\" = \""); + sb.append(colocateTable).append("\""); + } + + // dynamic partition + if (olapTable.dynamicPartitionExists()) { + sb.append(olapTable.getTableProperty().getDynamicPartitionProperty().getProperties(replicaAlloc)); + } + + // only display z-order sort info + if (olapTable.isZOrderSort()) { + sb.append(olapTable.getDataSortInfo().toSql()); + } + + // in memory + if (olapTable.isInMemory()) { + sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_INMEMORY).append("\" = \""); + sb.append(olapTable.isInMemory()).append("\""); + } + + // storage medium + if (olapTable.getStorageMedium() != null) { + sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_STORAGE_MEDIUM).append("\" = \""); + sb.append(olapTable.getStorageMedium().name().toLowerCase()); + sb.append("\""); + } + + // storage type + sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_STORAGE_FORMAT).append("\" = \""); + sb.append(olapTable.getStorageFormat()).append("\""); + + // inverted index storage type + sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_INVERTED_INDEX_STORAGE_FORMAT).append("\" = \""); + sb.append(olapTable.getInvertedIndexStorageFormat()).append("\""); + + // compression type + if (olapTable.getCompressionType() != TCompressionType.LZ4F) { + sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_COMPRESSION).append("\" = \""); + sb.append(olapTable.getCompressionType()).append("\""); + } + + // estimate_partition_size + if (!olapTable.getEstimatePartitionSize().equals("")) { + sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_ESTIMATE_PARTITION_SIZE).append("\" = \""); + sb.append(olapTable.getEstimatePartitionSize()).append("\""); + } + + // unique key table with merge on write, always print this property for unique table + if (olapTable.getKeysType() == KeysType.UNIQUE_KEYS) { + sb.append(",\n\"").append(PropertyAnalyzer.ENABLE_UNIQUE_KEY_MERGE_ON_WRITE).append("\" = \""); + sb.append(olapTable.getEnableUniqueKeyMergeOnWrite()).append("\""); + } + + // show lightSchemaChange only when it is set true + if (olapTable.getEnableLightSchemaChange()) { + sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_ENABLE_LIGHT_SCHEMA_CHANGE).append("\" = \""); + sb.append(olapTable.getEnableLightSchemaChange()).append("\""); + } + + // storage policy + if (olapTable.getStoragePolicy() != null && !olapTable.getStoragePolicy().equals("")) { + sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_STORAGE_POLICY).append("\" = \""); + sb.append(olapTable.getStoragePolicy()).append("\""); + } + + // sequence type + if (olapTable.hasSequenceCol()) { + if (olapTable.getSequenceMapCol() != null) { + sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_FUNCTION_COLUMN + "." + + PropertyAnalyzer.PROPERTIES_SEQUENCE_COL).append("\" = \""); + sb.append(olapTable.getSequenceMapCol()).append("\""); + } else { + sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_FUNCTION_COLUMN + "." + + PropertyAnalyzer.PROPERTIES_SEQUENCE_TYPE).append("\" = \""); + sb.append(olapTable.getSequenceType().toString()).append("\""); + } + } + + // store row column + if (olapTable.storeRowColumn()) { + sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_STORE_ROW_COLUMN).append("\" = \""); + sb.append(olapTable.storeRowColumn()).append("\""); + } + + // skip inverted index on load + if (olapTable.skipWriteIndexOnLoad()) { + sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_SKIP_WRITE_INDEX_ON_LOAD).append("\" = \""); + sb.append(olapTable.skipWriteIndexOnLoad()).append("\""); + } + + // compaction policy + if (olapTable.getCompactionPolicy() != null && !olapTable.getCompactionPolicy().equals("") + && !olapTable.getCompactionPolicy().equals(PropertyAnalyzer.SIZE_BASED_COMPACTION_POLICY)) { + sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_COMPACTION_POLICY).append("\" = \""); + sb.append(olapTable.getCompactionPolicy()).append("\""); + } + + // time series compaction goal size + if (olapTable.getCompactionPolicy() != null && olapTable.getCompactionPolicy() + .equals(PropertyAnalyzer.TIME_SERIES_COMPACTION_POLICY)) { + sb.append(",\n\"").append(PropertyAnalyzer + .PROPERTIES_TIME_SERIES_COMPACTION_GOAL_SIZE_MBYTES).append("\" = \""); + sb.append(olapTable.getTimeSeriesCompactionGoalSizeMbytes()).append("\""); + } + + // time series compaction file count threshold + if (olapTable.getCompactionPolicy() != null && olapTable.getCompactionPolicy() + .equals(PropertyAnalyzer.TIME_SERIES_COMPACTION_POLICY)) { + sb.append(",\n\"").append(PropertyAnalyzer + .PROPERTIES_TIME_SERIES_COMPACTION_FILE_COUNT_THRESHOLD).append("\" = \""); + sb.append(olapTable.getTimeSeriesCompactionFileCountThreshold()).append("\""); + } + + // time series compaction time threshold + if (olapTable.getCompactionPolicy() != null && olapTable.getCompactionPolicy() + .equals(PropertyAnalyzer.TIME_SERIES_COMPACTION_POLICY)) { + sb.append(",\n\"").append(PropertyAnalyzer + .PROPERTIES_TIME_SERIES_COMPACTION_TIME_THRESHOLD_SECONDS).append("\" = \""); + sb.append(olapTable.getTimeSeriesCompactionTimeThresholdSeconds()).append("\""); + } + + // time series compaction empty rowsets threshold + if (olapTable.getCompactionPolicy() != null && olapTable.getCompactionPolicy() + .equals(PropertyAnalyzer.TIME_SERIES_COMPACTION_POLICY)) { + sb.append(",\n\"").append(PropertyAnalyzer + .PROPERTIES_TIME_SERIES_COMPACTION_EMPTY_ROWSETS_THRESHOLD).append("\" = \""); + sb.append(olapTable.getTimeSeriesCompactionEmptyRowsetsThreshold()).append("\""); + } + + // time series compaction level threshold + if (olapTable.getCompactionPolicy() != null && olapTable.getCompactionPolicy() + .equals(PropertyAnalyzer.TIME_SERIES_COMPACTION_POLICY)) { + sb.append(",\n\"").append(PropertyAnalyzer + .PROPERTIES_TIME_SERIES_COMPACTION_LEVEL_THRESHOLD).append("\" = \""); + sb.append(olapTable.getTimeSeriesCompactionLevelThreshold()).append("\""); + } + + // disable auto compaction + sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_DISABLE_AUTO_COMPACTION).append("\" = \""); + sb.append(olapTable.disableAutoCompaction()).append("\""); + + // binlog + if (Config.enable_feature_binlog) { + BinlogConfig binlogConfig = olapTable.getBinlogConfig(); + binlogConfig.appendToShowCreateTable(sb); + } + + // enable single replica compaction + sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_ENABLE_SINGLE_REPLICA_COMPACTION).append("\" = \""); + sb.append(olapTable.enableSingleReplicaCompaction()).append("\""); + + // group commit interval ms + sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_GROUP_COMMIT_INTERVAL_MS).append("\" = \""); + sb.append(olapTable.getGroupCommitIntervalMs()).append("\""); + + // group commit data bytes + sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_GROUP_COMMIT_DATA_BYTES).append("\" = \""); + sb.append(olapTable.getGroupCommitDataBytes()).append("\""); + + // enable duplicate without keys by default + if (olapTable.isDuplicateWithoutKey()) { + sb.append(",\n\"") + .append(PropertyAnalyzer.PROPERTIES_ENABLE_DUPLICATE_WITHOUT_KEYS_BY_DEFAULT) + .append("\" = \""); + sb.append(olapTable.isDuplicateWithoutKey()).append("\""); + } + } + /** * Get table ddl stmt. * @@ -3350,215 +3639,7 @@ public class Env { // properties sb.append("\nPROPERTIES (\n"); - - // replicationNum - ReplicaAllocation replicaAlloc = olapTable.getDefaultReplicaAllocation(); - sb.append("\"").append(PropertyAnalyzer.PROPERTIES_REPLICATION_ALLOCATION).append("\" = \""); - sb.append(replicaAlloc.toCreateStmt()).append("\""); - - // min load replica num - sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_MIN_LOAD_REPLICA_NUM).append("\" = \""); - sb.append(olapTable.getMinLoadReplicaNum()).append("\""); - - // bloom filter - Set bfColumnNames = olapTable.getCopiedBfColumns(); - if (bfColumnNames != null) { - sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_BF_COLUMNS).append("\" = \""); - sb.append(Joiner.on(", ").join(olapTable.getCopiedBfColumns())).append("\""); - } - - if (separatePartition) { - // version info - sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_VERSION_INFO).append("\" = \""); - Partition partition = null; - if (olapTable.getPartitionInfo().getType() == PartitionType.UNPARTITIONED) { - partition = olapTable.getPartition(olapTable.getName()); - } else { - Preconditions.checkState(partitionId.size() == 1); - partition = olapTable.getPartition(partitionId.get(0)); - } - sb.append(partition.getVisibleVersion()).append("\""); - } - - // mark this table is being synced - sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_IS_BEING_SYNCED).append("\" = \""); - sb.append(String.valueOf(olapTable.isBeingSynced() || getDdlForSync)).append("\""); - // mark this table if it is a auto bucket table - if (getDdlForSync && olapTable.isAutoBucket()) { - sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_AUTO_BUCKET).append("\" = \""); - sb.append("true").append("\""); - } - - // colocateTable - String colocateTable = olapTable.getColocateGroup(); - if (colocateTable != null) { - sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_COLOCATE_WITH).append("\" = \""); - sb.append(colocateTable).append("\""); - } - - // dynamic partition - if (olapTable.dynamicPartitionExists()) { - sb.append(olapTable.getTableProperty().getDynamicPartitionProperty().getProperties(replicaAlloc)); - } - - // only display z-order sort info - if (olapTable.isZOrderSort()) { - sb.append(olapTable.getDataSortInfo().toSql()); - } - - // in memory - if (olapTable.isInMemory()) { - sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_INMEMORY).append("\" = \""); - sb.append(olapTable.isInMemory()).append("\""); - } - - // storage medium - if (olapTable.getStorageMedium() != null) { - sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_STORAGE_MEDIUM).append("\" = \""); - sb.append(olapTable.getStorageMedium().name().toLowerCase()); - sb.append("\""); - } - - // storage type - sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_STORAGE_FORMAT).append("\" = \""); - sb.append(olapTable.getStorageFormat()).append("\""); - - // inverted index storage type - sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_INVERTED_INDEX_STORAGE_FORMAT).append("\" = \""); - sb.append(olapTable.getInvertedIndexStorageFormat()).append("\""); - - // compression type - if (olapTable.getCompressionType() != TCompressionType.LZ4F) { - sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_COMPRESSION).append("\" = \""); - sb.append(olapTable.getCompressionType()).append("\""); - } - - // estimate_partition_size - if (!olapTable.getEstimatePartitionSize().equals("")) { - sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_ESTIMATE_PARTITION_SIZE).append("\" = \""); - sb.append(olapTable.getEstimatePartitionSize()).append("\""); - } - - // unique key table with merge on write, always print this property for unique table - if (olapTable.getKeysType() == KeysType.UNIQUE_KEYS) { - sb.append(",\n\"").append(PropertyAnalyzer.ENABLE_UNIQUE_KEY_MERGE_ON_WRITE).append("\" = \""); - sb.append(olapTable.getEnableUniqueKeyMergeOnWrite()).append("\""); - } - - // show lightSchemaChange only when it is set true - if (olapTable.getEnableLightSchemaChange()) { - sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_ENABLE_LIGHT_SCHEMA_CHANGE).append("\" = \""); - sb.append(olapTable.getEnableLightSchemaChange()).append("\""); - } - - // storage policy - if (olapTable.getStoragePolicy() != null && !olapTable.getStoragePolicy().equals("")) { - sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_STORAGE_POLICY).append("\" = \""); - sb.append(olapTable.getStoragePolicy()).append("\""); - } - - // sequence type - if (olapTable.hasSequenceCol()) { - if (olapTable.getSequenceMapCol() != null) { - sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_FUNCTION_COLUMN + "." - + PropertyAnalyzer.PROPERTIES_SEQUENCE_COL).append("\" = \""); - sb.append(olapTable.getSequenceMapCol()).append("\""); - } else { - sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_FUNCTION_COLUMN + "." - + PropertyAnalyzer.PROPERTIES_SEQUENCE_TYPE).append("\" = \""); - sb.append(olapTable.getSequenceType().toString()).append("\""); - } - } - - // store row column - if (olapTable.storeRowColumn()) { - sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_STORE_ROW_COLUMN).append("\" = \""); - sb.append(olapTable.storeRowColumn()).append("\""); - } - - // skip inverted index on load - if (olapTable.skipWriteIndexOnLoad()) { - sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_SKIP_WRITE_INDEX_ON_LOAD).append("\" = \""); - sb.append(olapTable.skipWriteIndexOnLoad()).append("\""); - } - - // compaction policy - if (olapTable.getCompactionPolicy() != null && !olapTable.getCompactionPolicy().equals("") - && !olapTable.getCompactionPolicy().equals(PropertyAnalyzer.SIZE_BASED_COMPACTION_POLICY)) { - sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_COMPACTION_POLICY).append("\" = \""); - sb.append(olapTable.getCompactionPolicy()).append("\""); - } - - // time series compaction goal size - if (olapTable.getCompactionPolicy() != null && olapTable.getCompactionPolicy() - .equals(PropertyAnalyzer.TIME_SERIES_COMPACTION_POLICY)) { - sb.append(",\n\"").append(PropertyAnalyzer - .PROPERTIES_TIME_SERIES_COMPACTION_GOAL_SIZE_MBYTES).append("\" = \""); - sb.append(olapTable.getTimeSeriesCompactionGoalSizeMbytes()).append("\""); - } - - // time series compaction file count threshold - if (olapTable.getCompactionPolicy() != null && olapTable.getCompactionPolicy() - .equals(PropertyAnalyzer.TIME_SERIES_COMPACTION_POLICY)) { - sb.append(",\n\"").append(PropertyAnalyzer - .PROPERTIES_TIME_SERIES_COMPACTION_FILE_COUNT_THRESHOLD).append("\" = \""); - sb.append(olapTable.getTimeSeriesCompactionFileCountThreshold()).append("\""); - } - - // time series compaction time threshold - if (olapTable.getCompactionPolicy() != null && olapTable.getCompactionPolicy() - .equals(PropertyAnalyzer.TIME_SERIES_COMPACTION_POLICY)) { - sb.append(",\n\"").append(PropertyAnalyzer - .PROPERTIES_TIME_SERIES_COMPACTION_TIME_THRESHOLD_SECONDS).append("\" = \""); - sb.append(olapTable.getTimeSeriesCompactionTimeThresholdSeconds()).append("\""); - } - - // time series compaction empty rowsets threshold - if (olapTable.getCompactionPolicy() != null && olapTable.getCompactionPolicy() - .equals(PropertyAnalyzer.TIME_SERIES_COMPACTION_POLICY)) { - sb.append(",\n\"").append(PropertyAnalyzer - .PROPERTIES_TIME_SERIES_COMPACTION_EMPTY_ROWSETS_THRESHOLD).append("\" = \""); - sb.append(olapTable.getTimeSeriesCompactionEmptyRowsetsThreshold()).append("\""); - } - - // time series compaction level threshold - if (olapTable.getCompactionPolicy() != null && olapTable.getCompactionPolicy() - .equals(PropertyAnalyzer.TIME_SERIES_COMPACTION_POLICY)) { - sb.append(",\n\"").append(PropertyAnalyzer - .PROPERTIES_TIME_SERIES_COMPACTION_LEVEL_THRESHOLD).append("\" = \""); - sb.append(olapTable.getTimeSeriesCompactionLevelThreshold()).append("\""); - } - - // disable auto compaction - sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_DISABLE_AUTO_COMPACTION).append("\" = \""); - sb.append(olapTable.disableAutoCompaction()).append("\""); - - // binlog - if (Config.enable_feature_binlog) { - BinlogConfig binlogConfig = olapTable.getBinlogConfig(); - binlogConfig.appendToShowCreateTable(sb); - } - - // enable single replica compaction - sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_ENABLE_SINGLE_REPLICA_COMPACTION).append("\" = \""); - sb.append(olapTable.enableSingleReplicaCompaction()).append("\""); - - // group commit interval ms - sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_GROUP_COMMIT_INTERVAL_MS).append("\" = \""); - sb.append(olapTable.getGroupCommitIntervalMs()).append("\""); - - // group commit data bytes - sb.append(",\n\"").append(PropertyAnalyzer.PROPERTIES_GROUP_COMMIT_DATA_BYTES).append("\" = \""); - sb.append(olapTable.getGroupCommitDataBytes()).append("\""); - - // enable duplicate without keys by default - if (olapTable.isDuplicateWithoutKey()) { - sb.append(",\n\"") - .append(PropertyAnalyzer.PROPERTIES_ENABLE_DUPLICATE_WITHOUT_KEYS_BY_DEFAULT) - .append("\" = \""); - sb.append(olapTable.isDuplicateWithoutKey()).append("\""); - } - + addOlapTablePropertyInfo(olapTable, sb, separatePartition, getDdlForSync, partitionId); sb.append("\n)"); } else if (table.getType() == TableType.MYSQL) { MysqlTable mysqlTable = (MysqlTable) table; 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 543a563024..c56a47c257 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 @@ -169,6 +169,7 @@ 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.ShowConstraintContext; +import org.apache.doris.nereids.DorisParser.ShowCreateMTMVContext; import org.apache.doris.nereids.DorisParser.ShowCreateProcedureContext; import org.apache.doris.nereids.DorisParser.ShowProcedureStatusContext; import org.apache.doris.nereids.DorisParser.SimpleColumnDefContext; @@ -382,6 +383,7 @@ import org.apache.doris.nereids.trees.plans.commands.PauseMTMVCommand; import org.apache.doris.nereids.trees.plans.commands.RefreshMTMVCommand; import org.apache.doris.nereids.trees.plans.commands.ResumeMTMVCommand; import org.apache.doris.nereids.trees.plans.commands.ShowConstraintsCommand; +import org.apache.doris.nereids.trees.plans.commands.ShowCreateMTMVCommand; import org.apache.doris.nereids.trees.plans.commands.ShowCreateProcedureCommand; import org.apache.doris.nereids.trees.plans.commands.ShowProcedureStatusCommand; import org.apache.doris.nereids.trees.plans.commands.UnsupportedCommand; @@ -416,6 +418,7 @@ import org.apache.doris.nereids.trees.plans.commands.info.PauseMTMVInfo; import org.apache.doris.nereids.trees.plans.commands.info.RefreshMTMVInfo; import org.apache.doris.nereids.trees.plans.commands.info.ResumeMTMVInfo; import org.apache.doris.nereids.trees.plans.commands.info.RollupDefinition; +import org.apache.doris.nereids.trees.plans.commands.info.ShowCreateMTMVInfo; 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; @@ -806,6 +809,12 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor { return new ResumeMTMVCommand(new ResumeMTMVInfo(new TableNameInfo(nameParts))); } + @Override + public ShowCreateMTMVCommand visitShowCreateMTMV(ShowCreateMTMVContext ctx) { + List nameParts = visitMultipartIdentifier(ctx.mvName); + return new ShowCreateMTMVCommand(new ShowCreateMTMVInfo(new TableNameInfo(nameParts))); + } + @Override public CancelMTMVTaskCommand visitCancelMTMVTask(CancelMTMVTaskContext ctx) { List nameParts = visitMultipartIdentifier(ctx.mvName); 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 9794eb1996..c665e4751d 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanType.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanType.java @@ -148,6 +148,7 @@ public enum PlanType { DROP_MTMV_COMMAND, PAUSE_MTMV_COMMAND, RESUME_MTMV_COMMAND, + SHOW_CREATE_MTMV_COMMAND, CANCEL_MTMV_TASK_COMMAND, CALL_COMMAND, CREATE_PROCEDURE_COMMAND, diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowCreateMTMVCommand.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowCreateMTMVCommand.java new file mode 100644 index 0000000000..eb244be7af --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/ShowCreateMTMVCommand.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.nereids.trees.plans.PlanType; +import org.apache.doris.nereids.trees.plans.commands.info.ShowCreateMTMVInfo; +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; + +/** + * resume mtmv + */ +public class ShowCreateMTMVCommand extends Command implements ForwardWithSync, NotAllowFallback { + private final ShowCreateMTMVInfo showCreateMTMVInfo; + + public ShowCreateMTMVCommand(ShowCreateMTMVInfo showCreateMTMVInfo) { + super(PlanType.SHOW_CREATE_MTMV_COMMAND); + this.showCreateMTMVInfo = Objects.requireNonNull(showCreateMTMVInfo, "require showCreateMTMVInfo object"); + } + + @Override + public void run(ConnectContext ctx, StmtExecutor executor) throws Exception { + showCreateMTMVInfo.analyze(ctx); + showCreateMTMVInfo.run(executor); + } + + @Override + public R accept(PlanVisitor visitor, C context) { + return visitor.visitShowCreateMTMVCommand(this, context); + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/ShowCreateMTMVInfo.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/ShowCreateMTMVInfo.java new file mode 100644 index 0000000000..588af23657 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/ShowCreateMTMVInfo.java @@ -0,0 +1,106 @@ +// 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.Database; +import org.apache.doris.catalog.Env; +import org.apache.doris.catalog.MTMV; +import org.apache.doris.catalog.TableIf.TableType; +import org.apache.doris.common.DdlException; +import org.apache.doris.common.ErrorCode; +import org.apache.doris.common.MetaNotFoundException; +import org.apache.doris.mysql.privilege.PrivPredicate; +import org.apache.doris.nereids.exceptions.AnalysisException; +import org.apache.doris.qe.ConnectContext; +import org.apache.doris.qe.StmtExecutor; + +import com.google.common.collect.Lists; + +import java.io.IOException; +import java.util.List; +import java.util.Objects; + +/** + * show create mtmv info + */ +public class ShowCreateMTMVInfo { + private final TableNameInfo mvName; + + public ShowCreateMTMVInfo(TableNameInfo mvName) { + this.mvName = Objects.requireNonNull(mvName, "require mvName object"); + } + + /** + * analyze resume info + * + * @param ctx ConnectContext + */ + public void analyze(ConnectContext ctx) { + mvName.analyze(ctx); + if (!Env.getCurrentEnv().getAccessManager().checkTblPriv(ConnectContext.get(), mvName.getCtl(), mvName.getDb(), + mvName.getTbl(), PrivPredicate.SHOW)) { + String message = ErrorCode.ERR_TABLEACCESS_DENIED_ERROR.formatErrorMsg("SHOW", + ConnectContext.get().getQualifiedUser(), ConnectContext.get().getRemoteIP(), + mvName.getDb() + ": " + mvName.getTbl()); + throw new AnalysisException(message); + } + try { + Database db = Env.getCurrentInternalCatalog().getDbOrDdlException(mvName.getDb()); + db.getTableOrMetaException(mvName.getTbl(), TableType.MATERIALIZED_VIEW); + } catch (MetaNotFoundException | DdlException e) { + throw new AnalysisException(e.getMessage()); + } + } + + /** + * run show create materialized view + * + * @param executor executor + * @throws DdlException DdlException + * @throws IOException IOException + */ + public void run(StmtExecutor executor) throws DdlException, IOException { + List> rows = Lists.newArrayList(); + Database db = Env.getCurrentInternalCatalog().getDbOrDdlException(mvName.getDb()); + MTMV mtmv = (MTMV) db.getTableOrDdlException(mvName.getTbl()); + mtmv.readLock(); + try { + String mtmvDdl = Env.getMTMVDdl(mtmv); + rows.add(Lists.newArrayList(mtmv.getName(), mtmvDdl)); + executor.handleShowCreateMTMVStmt(rows); + } finally { + mtmv.readUnlock(); + } + } + + /** + * getMvName + * + * @return TableNameInfo + */ + public TableNameInfo getMvName() { + return mvName; + } + + @Override + public String toString() { + return "ShowCreateMTMVInfo{" + + "mvName=" + mvName + + '}'; + } +} 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 2aafd94ee4..3af299022b 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 @@ -41,6 +41,7 @@ import org.apache.doris.nereids.trees.plans.commands.PauseMTMVCommand; import org.apache.doris.nereids.trees.plans.commands.RefreshMTMVCommand; import org.apache.doris.nereids.trees.plans.commands.ResumeMTMVCommand; import org.apache.doris.nereids.trees.plans.commands.ShowConstraintsCommand; +import org.apache.doris.nereids.trees.plans.commands.ShowCreateMTMVCommand; import org.apache.doris.nereids.trees.plans.commands.ShowCreateProcedureCommand; import org.apache.doris.nereids.trees.plans.commands.ShowProcedureStatusCommand; import org.apache.doris.nereids.trees.plans.commands.UnsupportedCommand; @@ -137,6 +138,10 @@ public interface CommandVisitor { return visitCommand(resumeMTMVCommand, context); } + default R visitShowCreateMTMVCommand(ShowCreateMTMVCommand showCreateMTMVCommand, C context) { + return visitCommand(showCreateMTMVCommand, context); + } + default R visitCancelMTMVTaskCommand(CancelMTMVTaskCommand cancelMTMVTaskCommand, C context) { return visitCommand(cancelMTMVTaskCommand, context); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/ShowExecutor.java b/fe/fe-core/src/main/java/org/apache/doris/qe/ShowExecutor.java index c085ef10e0..9066aa602d 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/qe/ShowExecutor.java +++ b/fe/fe-core/src/main/java/org/apache/doris/qe/ShowExecutor.java @@ -45,6 +45,7 @@ import org.apache.doris.analysis.ShowCreateCatalogStmt; import org.apache.doris.analysis.ShowCreateDbStmt; import org.apache.doris.analysis.ShowCreateFunctionStmt; import org.apache.doris.analysis.ShowCreateLoadStmt; +import org.apache.doris.analysis.ShowCreateMTMVStmt; import org.apache.doris.analysis.ShowCreateMaterializedViewStmt; import org.apache.doris.analysis.ShowCreateRepositoryStmt; import org.apache.doris.analysis.ShowCreateRoutineLoadStmt; @@ -124,6 +125,7 @@ import org.apache.doris.catalog.Env; import org.apache.doris.catalog.Function; import org.apache.doris.catalog.FunctionUtil; import org.apache.doris.catalog.Index; +import org.apache.doris.catalog.MTMV; import org.apache.doris.catalog.MaterializedIndex; import org.apache.doris.catalog.MaterializedIndex.IndexExtState; import org.apache.doris.catalog.MaterializedIndexMeta; @@ -293,6 +295,8 @@ public class ShowExecutor { handleDescribe(); } else if (stmt instanceof ShowCreateTableStmt) { handleShowCreateTable(); + } else if (stmt instanceof ShowCreateMTMVStmt) { + handleShowCreateMTMV(); } else if (stmt instanceof ShowCreateDbStmt) { handleShowCreateDb(); } else if (stmt instanceof ShowProcesslistStmt) { @@ -1061,6 +1065,23 @@ public class ShowExecutor { } } + private void handleShowCreateMTMV() throws AnalysisException { + ShowCreateMTMVStmt showStmt = (ShowCreateMTMVStmt) stmt; + DatabaseIf db = ctx.getEnv().getCatalogMgr().getCatalogOrAnalysisException(showStmt.getCtl()) + .getDbOrAnalysisException(showStmt.getDb()); + MTMV mtmv = (MTMV) db.getTableOrAnalysisException(showStmt.getTable()); + List> rows = Lists.newArrayList(); + + mtmv.readLock(); + try { + String mtmvDdl = Env.getMTMVDdl(mtmv); + rows.add(Lists.newArrayList(mtmv.getName(), mtmvDdl)); + resultSet = new ShowResultSet(showStmt.getMetaData(), rows); + } finally { + mtmv.readUnlock(); + } + } + // Describe statement private void handleDescribe() throws AnalysisException { DescribeStmt describeStmt = (DescribeStmt) stmt; diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java b/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java index 5b8082fd0b..d44229c151 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java +++ b/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java @@ -2595,6 +2595,15 @@ public class StmtExecutor { sendResultSet(resultSet); } + public void handleShowCreateMTMVStmt(List> result) throws IOException { + ShowResultSetMetaData metaData = ShowResultSetMetaData.builder() + .addColumn(new Column("Materialized View", ScalarType.createVarchar(20))) + .addColumn(new Column("Create Materialized View", ScalarType.createVarchar(30))) + .build(); + ResultSet resultSet = new ShowResultSet(metaData, result); + sendResultSet(resultSet); + } + public void handleExplainPlanProcessStmt(List result) throws IOException { ShowResultSetMetaData metaData = ShowResultSetMetaData.builder() .addColumn(new Column("Rule", ScalarType.createVarchar(-1))) diff --git a/regression-test/suites/mtmv_p0/test_alter_distribution_type_mtmv.groovy b/regression-test/suites/mtmv_p0/test_alter_distribution_type_mtmv.groovy index 666541613c..2db7e95c2e 100644 --- a/regression-test/suites/mtmv_p0/test_alter_distribution_type_mtmv.groovy +++ b/regression-test/suites/mtmv_p0/test_alter_distribution_type_mtmv.groovy @@ -51,7 +51,7 @@ suite("test_alter_distribution_type_mtmv","mtmv") { ALTER TABLE ${mvName} set ("distribution_type" = "random"); """ - def showCreateTableResult = sql """show create table ${mvName}""" + def showCreateTableResult = sql """show create materialized view ${mvName}""" logger.info("showCreateTableResult: " + showCreateTableResult.toString()) assertTrue(showCreateTableResult.toString().contains('DISTRIBUTED BY RANDOM')) diff --git a/regression-test/suites/mtmv_p0/test_bloom_filter_mtmv.groovy b/regression-test/suites/mtmv_p0/test_bloom_filter_mtmv.groovy index 1f307fb6f4..67379f6574 100644 --- a/regression-test/suites/mtmv_p0/test_bloom_filter_mtmv.groovy +++ b/regression-test/suites/mtmv_p0/test_bloom_filter_mtmv.groovy @@ -50,7 +50,7 @@ suite("test_bloom_filter_mtmv","mtmv") { SELECT * from ${tableName}; """ - def showCreateTableResult = sql """show create table ${mvName}""" + def showCreateTableResult = sql """show create materialized view ${mvName}""" logger.info("showCreateTableResult: " + showCreateTableResult.toString()) assertTrue(showCreateTableResult.toString().contains('bloom_filter_columns" = "k2"')) @@ -68,7 +68,7 @@ suite("test_bloom_filter_mtmv","mtmv") { ALTER TABLE ${mvName} SET ("bloom_filter_columns" = "k3"); """ assertEquals("FINISHED", getAlterColumnFinalState("${mvName}")) - showCreateTableResult = sql """show create table ${mvName}""" + showCreateTableResult = sql """show create materialized view ${mvName}""" logger.info("showCreateTableResult: " + showCreateTableResult.toString()) assertTrue(showCreateTableResult.toString().contains('bloom_filter_columns" = "k3"')) @@ -77,7 +77,7 @@ suite("test_bloom_filter_mtmv","mtmv") { ALTER TABLE ${mvName} SET ("bloom_filter_columns" = ""); """ assertEquals("FINISHED", getAlterColumnFinalState("${mvName}")) - showCreateTableResult = sql """show create table ${mvName}""" + showCreateTableResult = sql """show create materialized view ${mvName}""" logger.info("showCreateTableResult: " + showCreateTableResult.toString()) assertFalse(showCreateTableResult.toString().contains('bloom_filter_columns" = "k3"')) diff --git a/regression-test/suites/mtmv_p0/test_build_mtmv.groovy b/regression-test/suites/mtmv_p0/test_build_mtmv.groovy index 9a8ba668d1..db69bf9170 100644 --- a/regression-test/suites/mtmv_p0/test_build_mtmv.groovy +++ b/regression-test/suites/mtmv_p0/test_build_mtmv.groovy @@ -83,6 +83,14 @@ suite("test_build_mtmv") { SELECT id, username FROM ${tableName}; """ + // not support show create table + test { + sql """ + show create table ${mvName}; + """ + exception "not support" + } + // desc def descTableAllResult = sql """desc ${mvName} all""" logger.info("descTableAllResult: " + descTableAllResult.toString()) diff --git a/regression-test/suites/mtmv_p0/test_compression_mtmv.groovy b/regression-test/suites/mtmv_p0/test_compression_mtmv.groovy index 45347908a3..72ea457e9d 100644 --- a/regression-test/suites/mtmv_p0/test_compression_mtmv.groovy +++ b/regression-test/suites/mtmv_p0/test_compression_mtmv.groovy @@ -59,7 +59,7 @@ suite("test_compression_mtmv","mtmv") { waitingMTMVTaskFinishedByMvName(mvName) order_qt_refresh_mv "SELECT * FROM ${mvName}" - def showCreateTableResult = sql """show create table ${mvName}""" + def showCreateTableResult = sql """show create materialized view ${mvName}""" logger.info("showCreateTableResult: " + showCreateTableResult.toString()) assertTrue(showCreateTableResult.toString().contains('ZSTD')) diff --git a/regression-test/suites/mtmv_p0/test_show_create_mtmv.groovy b/regression-test/suites/mtmv_p0/test_show_create_mtmv.groovy new file mode 100644 index 0000000000..34cda2f6ff --- /dev/null +++ b/regression-test/suites/mtmv_p0/test_show_create_mtmv.groovy @@ -0,0 +1,104 @@ +// 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. + +import org.junit.Assert; + +suite("test_show_create_mtmv","mtmv") { + String suiteName = "test_show_create_mtmv" + String tableName = "${suiteName}_table" + String mvName = "${suiteName}_mv" + sql """drop table if exists `${tableName}`""" + sql """drop materialized view if exists ${mvName};""" + + sql """ + CREATE TABLE `${tableName}` ( + `k1` LARGEINT NOT NULL COMMENT '\"用户id\"', + `k2` DATE NOT NULL COMMENT '\"数据灌入日期时间\"' + ) ENGINE=OLAP + DUPLICATE KEY(`k1`) + COMMENT 'OLAP' + PARTITION BY range(`k2`) + ( + PARTITION p_20200101 VALUES [("2020-01-01"),("2020-01-02")), + PARTITION p_20200102 VALUES [("2020-01-02"),("2020-01-03")), + PARTITION p_20200201 VALUES [("2020-02-01"),("2020-02-02")) + ) + DISTRIBUTED BY HASH(`k1`) BUCKETS 2 + PROPERTIES ('replication_num' = '1') ; + """ + sql """ + CREATE MATERIALIZED VIEW ${mvName} + BUILD DEFERRED REFRESH AUTO ON MANUAL + partition by (date_trunc(`k2`,'month')) + DISTRIBUTED BY RANDOM BUCKETS 2 + PROPERTIES ( + 'replication_num' = '1', + "grace_period"="333" + ) + AS + SELECT * FROM ${tableName}; + """ + + def showCreateMTMVResult = sql """show CREATE MATERIALIZED VIEW ${mvName}""" + logger.info("showCreateMTMVResult: " + showCreateMTMVResult.toString()) + assertTrue(showCreateMTMVResult.toString().contains("CREATE MATERIALIZED VIEW")) + assertTrue(showCreateMTMVResult.toString().contains("BUILD DEFERRED REFRESH AUTO ON MANUAL")) + assertTrue(showCreateMTMVResult.toString().contains("DUPLICATE KEY(`k1`, `k2`)")) + assertTrue(showCreateMTMVResult.toString().contains("PARTITION BY (date_trunc(`k2`, 'month'))")) + assertTrue(showCreateMTMVResult.toString().contains("DISTRIBUTED BY RANDOM BUCKETS 2")) + assertTrue(showCreateMTMVResult.toString().contains("SELECT * FROM")) + assertTrue(showCreateMTMVResult.toString().contains("grace_period")) + + sql """drop materialized view if exists ${mvName};""" + sql """ + CREATE MATERIALIZED VIEW ${mvName} + BUILD DEFERRED REFRESH AUTO ON SCHEDULE EVERY 10 DAY + partition by (`k2`) + DISTRIBUTED BY hash(k1) BUCKETS 2 + PROPERTIES ( + 'replication_num' = '1' + ) + AS + SELECT * FROM ${tableName}; + """ + showCreateMTMVResult = sql """show CREATE MATERIALIZED VIEW ${mvName}""" + logger.info("showCreateMTMVResult: " + showCreateMTMVResult.toString()) + assertTrue(showCreateMTMVResult.toString().contains("BUILD DEFERRED REFRESH AUTO ON SCHEDULE EVERY 10 DAY")) + assertTrue(showCreateMTMVResult.toString().contains("PARTITION BY (`k2`)")) + assertTrue(showCreateMTMVResult.toString().contains("DISTRIBUTED BY HASH(`k1`) BUCKETS 2")) + + sql """drop materialized view if exists ${mvName};""" + sql """ + CREATE MATERIALIZED VIEW ${mvName} + (aa comment "aa_comment",bb) + BUILD IMMEDIATE REFRESH COMPLETE ON COMMIT + DISTRIBUTED BY RANDOM BUCKETS AUTO + PROPERTIES ( + 'replication_num' = '1' + ) + AS + SELECT * FROM ${tableName}; + """ + showCreateMTMVResult = sql """show CREATE MATERIALIZED VIEW ${mvName}""" + logger.info("showCreateMTMVResult: " + showCreateMTMVResult.toString()) + assertTrue(showCreateMTMVResult.toString().contains("aa comment 'aa_comment',bb")) + assertTrue(showCreateMTMVResult.toString().contains("BUILD IMMEDIATE REFRESH COMPLETE ON COMMIT")) + assertTrue(showCreateMTMVResult.toString().contains("DISTRIBUTED BY RANDOM BUCKETS AUTO")) + + sql """drop table if exists `${tableName}`""" + sql """drop materialized view if exists ${mvName};""" +}