This is an automated email from the ASF dual-hosted git repository. adonisling pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push: new b7eea72d1d [feature-wip](MTMV) Support showing and dropping materialized view for multiple tables (#12762) b7eea72d1d is described below commit b7eea72d1dc59da58907c3e902541342a5eea83e Author: Adonis Ling <adonis0...@gmail.com> AuthorDate: Fri Sep 23 10:36:40 2022 +0800 [feature-wip](MTMV) Support showing and dropping materialized view for multiple tables (#12762) Use cases: mysql> CREATE TABLE t1 (pk INT, v1 INT SUM) AGGREGATE KEY (pk) DISTRIBUTED BY hash (pk) PROPERTIES ('replication_num' = '1'); Query OK, 0 rows affected (0.05 sec) mysql> CREATE TABLE t2 (pk INT, v2 INT SUM) AGGREGATE KEY (pk) DISTRIBUTED BY hash (pk) PROPERTIES ('replication_num' = '1'); Query OK, 0 rows affected (0.01 sec) mysql> CREATE MATERIALIZED VIEW mv BUILD IMMEDIATE REFRESH COMPLETE KEY (mv_pk) DISTRIBUTED BY HASH (mv_pk) PROPERTIES ('replication_num' = '1') AS SELECT t1.pk as mv_pk FROM t1, t2 WHERE t1.pk = t2.pk; Query OK, 0 rows affected (0.02 sec) mysql> SHOW TABLES; +---------------+ | Tables_in_dev | +---------------+ | mv | | t1 | | t2 | +---------------+ 3 rows in set (0.00 sec) mysql> SHOW CREATE TABLE mv; +-------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Materialized View | Create Materialized View | +-------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | mv | CREATE MATERIALIZED VIEW `mv` BUILD IMMEDIATE REFRESH COMPLETE ON DEMAND KEY(`mv_pk`) DISTRIBUTED BY HASH(`mv_pk`) BUCKETS 10 PROPERTIES ( "replication_allocation" = "tag.location.default: 1", "in_memory" = "false", "storage_format" = "V2", "disable_auto_compaction" = "false" ) AS SELECT `t1`.`pk` AS `mv_pk` FROM `default_cluster:dev`.`t1` , `default_cluster:dev`.`t2` WHERE `t1`.`pk` = `t2`.`pk`; | +-------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.01 sec) mysql> DROP MATERIALIZED VIEW mv; Query OK, 0 rows affected (0.01 sec) --- .../main/java/org/apache/doris/alter/Alter.java | 21 ++++-- .../CreateMultiTableMaterializedViewStmt.java | 13 ++-- .../doris/analysis/DropMaterializedViewStmt.java | 41 +++++++---- .../org/apache/doris/analysis/DropTableStmt.java | 9 +++ .../org/apache/doris/analysis/MVRefreshInfo.java | 2 +- .../apache/doris/analysis/ShowCreateTableStmt.java | 11 +++ .../main/java/org/apache/doris/catalog/Env.java | 80 +++++++++++++--------- .../org/apache/doris/catalog/MaterializedView.java | 8 +++ .../org/apache/doris/catalog/OlapTableFactory.java | 11 ++- .../apache/doris/datasource/InternalCatalog.java | 3 +- .../java/org/apache/doris/qe/ShowExecutor.java | 4 +- .../MultiTableMaterializedViewTest.java} | 76 ++++++++++++++++---- 12 files changed, 208 insertions(+), 71 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/alter/Alter.java b/fe/fe-core/src/main/java/org/apache/doris/alter/Alter.java index c602c6dd7f..51c66eb77e 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/alter/Alter.java +++ b/fe/fe-core/src/main/java/org/apache/doris/alter/Alter.java @@ -28,6 +28,7 @@ import org.apache.doris.analysis.CreateMaterializedViewStmt; import org.apache.doris.analysis.CreateMultiTableMaterializedViewStmt; import org.apache.doris.analysis.DropMaterializedViewStmt; import org.apache.doris.analysis.DropPartitionClause; +import org.apache.doris.analysis.DropTableStmt; import org.apache.doris.analysis.ModifyColumnCommentClause; import org.apache.doris.analysis.ModifyDistributionClause; import org.apache.doris.analysis.ModifyEngineClause; @@ -131,17 +132,27 @@ public class Alter { } public void processDropMaterializedView(DropMaterializedViewStmt stmt) throws DdlException, MetaNotFoundException { - if (stmt.getTableName() == null) { + if (!stmt.isForMTMV() && stmt.getTableName() == null) { throw new DdlException("Drop materialized view without table name is unsupported : " + stmt.toSql()); } + TableName tableName = !stmt.isForMTMV() ? stmt.getTableName() : stmt.getMTMVName(); + // check db - String dbName = stmt.getTableName().getDb(); + String dbName = tableName.getDb(); Database db = Env.getCurrentInternalCatalog().getDbOrDdlException(dbName); - String tableName = stmt.getTableName().getTbl(); - OlapTable olapTable = (OlapTable) db.getTableOrMetaException(tableName, TableType.OLAP); + String name = tableName.getTbl(); + OlapTable olapTable = (OlapTable) db.getTableOrMetaException(name, + !stmt.isForMTMV() ? TableType.OLAP : TableType.MATERIALIZED_VIEW); + // drop materialized view - ((MaterializedViewHandler) materializedViewHandler).processDropMaterializedView(stmt, db, olapTable); + if (!stmt.isForMTMV()) { + ((MaterializedViewHandler) materializedViewHandler).processDropMaterializedView(stmt, db, olapTable); + } else { + DropTableStmt dropTableStmt = new DropTableStmt(stmt.isIfExists(), stmt.getMTMVName(), false); + dropTableStmt.setMaterializedView(true); + Env.getCurrentInternalCatalog().dropTable(dropTableStmt); + } } public void processRefreshMaterializedView(RefreshMaterializedViewStmt stmt) throws DdlException { diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateMultiTableMaterializedViewStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateMultiTableMaterializedViewStmt.java index 2f25591985..70a3c3289e 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateMultiTableMaterializedViewStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateMultiTableMaterializedViewStmt.java @@ -18,6 +18,7 @@ package org.apache.doris.analysis; import org.apache.doris.analysis.ColumnDef.DefaultValue; +import org.apache.doris.analysis.MVRefreshInfo.BuildMode; import org.apache.doris.catalog.Column; import org.apache.doris.catalog.Database; import org.apache.doris.catalog.Env; @@ -38,17 +39,17 @@ import java.util.stream.Collectors; public class CreateMultiTableMaterializedViewStmt extends CreateTableStmt { private final String mvName; - private final MVRefreshInfo.BuildMode buildMethod; + private final MVRefreshInfo.BuildMode buildMode; private final MVRefreshInfo refreshInfo; private final QueryStmt queryStmt; private Database database; private final Map<String, OlapTable> olapTables = Maps.newHashMap(); - public CreateMultiTableMaterializedViewStmt(String mvName, MVRefreshInfo.BuildMode buildMethod, + public CreateMultiTableMaterializedViewStmt(String mvName, MVRefreshInfo.BuildMode buildMode, MVRefreshInfo refreshInfo, KeysDesc keyDesc, PartitionDesc partitionDesc, DistributionDesc distributionDesc, Map<String, String> properties, QueryStmt queryStmt) { this.mvName = mvName; - this.buildMethod = buildMethod; + this.buildMode = buildMode; this.refreshInfo = refreshInfo; this.queryStmt = queryStmt; @@ -142,7 +143,7 @@ public class CreateMultiTableMaterializedViewStmt extends CreateTableStmt { @Override public String toSql() { StringBuilder sb = new StringBuilder(); - sb.append("CREATE MATERIALIZED VIEW ").append(mvName).append(" BUILD ON ").append(buildMethod.toString()); + sb.append("CREATE MATERIALIZED VIEW ").append(mvName).append(" BUILD ").append(buildMode.toString()); if (refreshInfo != null) { sb.append(" ").append(refreshInfo.toString()); } @@ -180,4 +181,8 @@ public class CreateMultiTableMaterializedViewStmt extends CreateTableStmt { public QueryStmt getQueryStmt() { return queryStmt; } + + public BuildMode getBuildMode() { + return buildMode; + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/DropMaterializedViewStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/DropMaterializedViewStmt.java index 9d81c6d68c..4352b47cd1 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/DropMaterializedViewStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/DropMaterializedViewStmt.java @@ -71,26 +71,39 @@ public class DropMaterializedViewStmt extends DdlStmt { return tableName; } + public TableName getMTMVName() { + return mtmvName; + } + public boolean isIfExists() { return ifExists; } + public boolean isForMTMV() { + return mtmvName != null; + } + @Override public void analyze(Analyzer analyzer) throws UserException { - if (mtmvName != null && tableName == null) { - throw new AnalysisException("Multi table materialized view is not supported now."); - } - if (Strings.isNullOrEmpty(mvName)) { - throw new AnalysisException("The materialized name could not be empty or null."); - } - tableName.analyze(analyzer); - // disallow external catalog - Util.prohibitExternalCatalog(tableName.getCtl(), this.getClass().getSimpleName()); - - // check access - if (!Env.getCurrentEnv().getAuth().checkTblPriv(ConnectContext.get(), tableName.getDb(), - tableName.getTbl(), PrivPredicate.DROP)) { - ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, "DROP"); + if (!isForMTMV()) { + if (Strings.isNullOrEmpty(mvName)) { + throw new AnalysisException("The materialized name could not be empty or null."); + } + tableName.analyze(analyzer); + // disallow external catalog + Util.prohibitExternalCatalog(tableName.getCtl(), this.getClass().getSimpleName()); + + // check access + if (!Env.getCurrentEnv().getAuth().checkTblPriv(ConnectContext.get(), tableName.getDb(), + tableName.getTbl(), PrivPredicate.DROP)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, "DROP"); + } + } else { + mtmvName.analyze(analyzer); + if (!Env.getCurrentEnv().getAuth().checkTblPriv(ConnectContext.get(), mtmvName.getDb(), + mtmvName.getTbl(), PrivPredicate.DROP)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, "DROP"); + } } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/DropTableStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/DropTableStmt.java index db003fa016..1658d9f96e 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/DropTableStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/DropTableStmt.java @@ -33,6 +33,7 @@ public class DropTableStmt extends DdlStmt { private final TableName tableName; private final boolean isView; private boolean forceDrop; + private boolean isMaterializedView; public DropTableStmt(boolean ifExists, TableName tableName, boolean forceDrop) { this.ifExists = ifExists; @@ -68,6 +69,14 @@ public class DropTableStmt extends DdlStmt { return this.forceDrop; } + public void setMaterializedView(boolean value) { + isMaterializedView = value; + } + + public boolean isMaterializedView() { + return isMaterializedView; + } + @Override public void analyze(Analyzer analyzer) throws UserException { if (Strings.isNullOrEmpty(tableName.getDb())) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/MVRefreshInfo.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/MVRefreshInfo.java index aeabe1e410..07fe9ca4ca 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/MVRefreshInfo.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/MVRefreshInfo.java @@ -85,7 +85,7 @@ public class MVRefreshInfo { DEMAND, COMMIT, INTERVAL } - enum BuildMode { + public enum BuildMode { IMMEDIATE, DEFERRED } } 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 60c562d007..2bed873353 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 @@ -43,6 +43,12 @@ public class ShowCreateTableStmt extends ShowStmt { .addColumn(new Column("collation_connection", ScalarType.createVarchar(30))) .build(); + private static final ShowResultSetMetaData MATERIALIZED_VIEW_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; private boolean isView; @@ -55,6 +61,7 @@ public class ShowCreateTableStmt extends ShowStmt { this.isView = isView; } + public String getCtl() { return tbl.getCtl(); } @@ -75,6 +82,10 @@ public class ShowCreateTableStmt extends ShowStmt { return VIEW_META_DATA; } + public static ShowResultSetMetaData getMaterializedViewMetaData() { + return MATERIALIZED_VIEW_META_DATA; + } + @Override public void analyze(Analyzer analyzer) throws AnalysisException { if (tbl == null) { 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 20a85c829b..bf29f9fb99 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 @@ -2723,48 +2723,61 @@ public class Env { || table.getType() == TableType.HIVE || table.getType() == TableType.JDBC) { sb.append("EXTERNAL "); } - sb.append("TABLE "); + sb.append(table.getType() != TableType.MATERIALIZED_VIEW ? "TABLE " : "MATERIALIZED VIEW "); + if (!Strings.isNullOrEmpty(dbName)) { sb.append("`").append(dbName).append("`."); } - sb.append("`").append(table.getName()).append("` (\n"); - int idx = 0; - List<Column> columns; - // when 'create table B like A', always return schema of A without hidden columns - if (getDdlForLike) { - columns = table.getBaseSchema(false); - } else { - columns = table.getBaseSchema(); - } - for (Column column : columns) { - if (idx++ != 0) { - sb.append(",\n"); - } - // There MUST BE 2 space in front of each column description line - // sqlalchemy requires this to parse SHOW CREATE TABLE stmt. - if (table.getType() == TableType.OLAP) { - sb.append(" ").append(column.toSql(((OlapTable) table).getKeysType() == KeysType.UNIQUE_KEYS)); + sb.append("`").append(table.getName()).append("`"); + + if (table.getType() != TableType.MATERIALIZED_VIEW) { + sb.append(" (\n"); + int idx = 0; + List<Column> columns; + // when 'create table B like A', always return schema of A without hidden columns + if (getDdlForLike) { + columns = table.getBaseSchema(false); } else { - sb.append(" ").append(column.toSql()); + columns = table.getBaseSchema(); } - } - if (table.getType() == TableType.OLAP) { - OlapTable olapTable = (OlapTable) table; - if (CollectionUtils.isNotEmpty(olapTable.getIndexes())) { - for (Index index : olapTable.getIndexes()) { + for (Column column : columns) { + if (idx++ != 0) { sb.append(",\n"); - sb.append(" ").append(index.toSql()); + } + // There MUST BE 2 space in front of each column description line + // sqlalchemy requires this to parse SHOW CREATE TABLE stmt. + if (table.getType() == TableType.OLAP) { + sb.append(" ").append(column.toSql(((OlapTable) table).getKeysType() == KeysType.UNIQUE_KEYS)); + } else { + sb.append(" ").append(column.toSql()); + } + } + if (table.getType() == TableType.OLAP) { + OlapTable olapTable = (OlapTable) table; + if (CollectionUtils.isNotEmpty(olapTable.getIndexes())) { + for (Index index : olapTable.getIndexes()) { + sb.append(",\n"); + sb.append(" ").append(index.toSql()); + } } } + sb.append("\n) ENGINE="); + sb.append(table.getType().name()); + } else { + MaterializedView materializedView = ((MaterializedView) table); + sb.append("\n").append("BUILD ").append(materializedView.getBuildMode()) + .append(materializedView.getRefreshInfo().toString()); } - sb.append("\n) ENGINE="); - sb.append(table.getType().name()); - if (table.getType() == TableType.OLAP) { + if (table.getType() == TableType.OLAP || table.getType() == TableType.MATERIALIZED_VIEW) { OlapTable olapTable = (OlapTable) table; // keys - sb.append("\n").append(olapTable.getKeysType().toSql()).append("("); + String keySql = olapTable.getKeysType().toSql(); + sb.append("\n").append(table.getType() == TableType.OLAP + ? keySql + : keySql.substring("DUPLICATE ".length())) + .append("("); List<String> keysColumnNames = Lists.newArrayList(); for (Column column : olapTable.getBaseSchema()) { if (column.isKey()) { @@ -2783,8 +2796,9 @@ public class Env { return; } - - addTableComment(olapTable, sb); + if (table.getType() != TableType.MATERIALIZED_VIEW) { + addTableComment(olapTable, sb); + } // partition PartitionInfo partitionInfo = olapTable.getPartitionInfo(); @@ -3071,6 +3085,10 @@ public class Env { sb.append("\n)"); } + if (table.getType() == TableType.MATERIALIZED_VIEW) { + sb.append("\nAS ").append(((MaterializedView) table).getQuery()); + } + createTableStmt.add(sb + ";"); // 2. add partition diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/MaterializedView.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/MaterializedView.java index fa9481380a..0309308c90 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/MaterializedView.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/MaterializedView.java @@ -18,6 +18,7 @@ package org.apache.doris.catalog; import org.apache.doris.analysis.MVRefreshInfo; +import org.apache.doris.analysis.MVRefreshInfo.BuildMode; import org.apache.doris.catalog.OlapTableFactory.MaterializedViewParams; import org.apache.doris.common.io.Text; import org.apache.doris.persist.gson.GsonUtils; @@ -29,6 +30,8 @@ import java.io.DataOutput; import java.io.IOException; public class MaterializedView extends OlapTable { + @SerializedName("buildMode") + private BuildMode buildMode; @SerializedName("refreshInfo") private MVRefreshInfo refreshInfo; @SerializedName("query") @@ -49,10 +52,15 @@ public class MaterializedView extends OlapTable { params.distributionInfo ); type = TableType.MATERIALIZED_VIEW; + buildMode = params.buildMode; refreshInfo = params.mvRefreshInfo; query = params.queryStmt.toSql(); } + public BuildMode getBuildMode() { + return buildMode; + } + public MVRefreshInfo getRefreshInfo() { return refreshInfo; } diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTableFactory.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTableFactory.java index dfb044f54e..3e0a1eba5c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTableFactory.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTableFactory.java @@ -21,6 +21,7 @@ import org.apache.doris.analysis.CreateMultiTableMaterializedViewStmt; import org.apache.doris.analysis.CreateTableStmt; import org.apache.doris.analysis.DdlStmt; import org.apache.doris.analysis.MVRefreshInfo; +import org.apache.doris.analysis.MVRefreshInfo.BuildMode; import org.apache.doris.analysis.QueryStmt; import org.apache.doris.catalog.TableIf.TableType; @@ -44,6 +45,7 @@ public class OlapTableFactory { } public static class MaterializedViewParams extends BuildParams { + public MVRefreshInfo.BuildMode buildMode; public MVRefreshInfo mvRefreshInfo; public QueryStmt queryStmt; } @@ -135,6 +137,12 @@ public class OlapTableFactory { return this; } + private OlapTableFactory withBuildMode(BuildMode buildMode) { + MaterializedViewParams materializedViewParams = (MaterializedViewParams) params; + materializedViewParams.buildMode = buildMode; + return this; + } + public OlapTableFactory withRefreshInfo(MVRefreshInfo mvRefreshInfo) { Preconditions.checkState(params instanceof MaterializedViewParams, "Invalid argument for " + params.getClass().getSimpleName()); @@ -150,7 +158,8 @@ public class OlapTableFactory { return withIndexes(new TableIndexes(createOlapTableStmt.getIndexes())); } else { CreateMultiTableMaterializedViewStmt createMVStmt = (CreateMultiTableMaterializedViewStmt) stmt; - return withRefreshInfo(createMVStmt.getRefreshInfo()) + return withBuildMode(createMVStmt.getBuildMode()) + .withRefreshInfo(createMVStmt.getRefreshInfo()) .withQueryStmt(createMVStmt.getQueryStmt()); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java b/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java index 63515d092c..6a109124c3 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java +++ b/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java @@ -86,6 +86,7 @@ import org.apache.doris.catalog.MaterializedIndex; import org.apache.doris.catalog.MaterializedIndex.IndexExtState; import org.apache.doris.catalog.MaterializedIndex.IndexState; import org.apache.doris.catalog.MaterializedIndexMeta; +import org.apache.doris.catalog.MaterializedView; import org.apache.doris.catalog.MetaIdGenerator.IdGeneratorBuffer; import org.apache.doris.catalog.MysqlTable; import org.apache.doris.catalog.OdbcTable; @@ -825,7 +826,7 @@ public class InternalCatalog implements CatalogIf<Database> { ErrorReport.reportDdlException(ErrorCode.ERR_WRONG_OBJECT, dbName, tableName, "VIEW"); } } else { - if (table instanceof View) { + if (table instanceof View || (!stmt.isMaterializedView() && table instanceof MaterializedView)) { ErrorReport.reportDdlException(ErrorCode.ERR_WRONG_OBJECT, dbName, tableName, "TABLE"); } } 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 a1a4659b83..669a87edf8 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 @@ -878,7 +878,9 @@ public class ShowExecutor { showStmt.getTable(), "VIEW"); } rows.add(Lists.newArrayList(table.getName(), createTableStmt.get(0))); - resultSet = new ShowResultSet(showStmt.getMetaData(), rows); + resultSet = table.getType() != TableType.MATERIALIZED_VIEW + ? new ShowResultSet(showStmt.getMetaData(), rows) + : new ShowResultSet(ShowCreateTableStmt.getMaterializedViewMetaData(), rows); } } catch (MetaNotFoundException e) { throw new AnalysisException(e.getMessage()); diff --git a/fe/fe-core/src/test/java/org/apache/doris/analysis/CreateMultiTableMaterializedViewStmtTest.java b/fe/fe-core/src/test/java/org/apache/doris/catalog/MultiTableMaterializedViewTest.java similarity index 65% rename from fe/fe-core/src/test/java/org/apache/doris/analysis/CreateMultiTableMaterializedViewStmtTest.java rename to fe/fe-core/src/test/java/org/apache/doris/catalog/MultiTableMaterializedViewTest.java index 1e73514ea0..be2858e300 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/analysis/CreateMultiTableMaterializedViewStmtTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/catalog/MultiTableMaterializedViewTest.java @@ -15,19 +15,24 @@ // specific language governing permissions and limitations // under the License. -package org.apache.doris.analysis; - -import org.apache.doris.catalog.Env; -import org.apache.doris.catalog.MaterializedView; -import org.apache.doris.catalog.OlapTableFactory; -import org.apache.doris.catalog.SinglePartitionInfo; +package org.apache.doris.catalog; + +import org.apache.doris.analysis.CreateMultiTableMaterializedViewStmt; +import org.apache.doris.analysis.DropMaterializedViewStmt; +import org.apache.doris.analysis.DropTableStmt; +import org.apache.doris.analysis.MVRefreshInfo; +import org.apache.doris.analysis.MVRefreshIntervalTriggerInfo; +import org.apache.doris.analysis.ShowStmt; import org.apache.doris.catalog.TableIf.TableType; +import org.apache.doris.common.DdlException; import org.apache.doris.common.ExceptionChecker; import org.apache.doris.common.UserException; import org.apache.doris.common.io.DataInputBuffer; import org.apache.doris.common.io.DataOutputBuffer; import org.apache.doris.common.util.SqlParserUtils; import org.apache.doris.common.util.Util; +import org.apache.doris.qe.ShowExecutor; +import org.apache.doris.qe.ShowResultSet; import org.apache.doris.qe.StmtExecutor; import org.apache.doris.thrift.TStorageType; import org.apache.doris.utframe.TestWithFeService; @@ -39,7 +44,7 @@ import org.junit.jupiter.api.Test; import java.io.IOException; -public class CreateMultiTableMaterializedViewStmtTest extends TestWithFeService { +public class MultiTableMaterializedViewTest extends TestWithFeService { @BeforeEach protected void setUp() throws Exception { @@ -53,15 +58,18 @@ public class CreateMultiTableMaterializedViewStmtTest extends TestWithFeService } @Test - public void testSimple() throws Exception { + public void testCreate() throws Exception { createTable("create table test.t1 (pk int, v1 int sum) aggregate key (pk) " + "distributed by hash (pk) buckets 1 properties ('replication_num' = '1');"); createTable("create table test.t2 (pk int, v2 int sum) aggregate key (pk) " + "distributed by hash (pk) buckets 1 properties ('replication_num' = '1');"); - StmtExecutor executor = new StmtExecutor(connectContext, "create materialized view mv " - + "build immediate refresh complete key (mv_pk) distributed by hash (mv_pk) " - + "as select test.t1.pk as mv_pk from test.t1, test.t2 where test.t1.pk = test.t2.pk"); - ExceptionChecker.expectThrowsNoException(executor::execute); + + ExceptionChecker.expectThrowsNoException(() -> + connectContext.getEnv().createMultiTableMaterializedView( + (CreateMultiTableMaterializedViewStmt) parseAndAnalyzeStmt("create materialized view mv " + + "build immediate refresh complete key (mv_pk) distributed by hash (mv_pk) " + + "properties ('replication_num' = '1') " + + "as select test.t1.pk as mv_pk from test.t1, test.t2 where test.t1.pk = test.t2.pk"))); } @Test @@ -139,7 +147,49 @@ public class CreateMultiTableMaterializedViewStmtTest extends TestWithFeService Util.generateSchemaHash(), Env.calcShortKeyColumnCount(stmt.getColumns(), stmt.getProperties()), TStorageType.COLUMN, - stmt.keysDesc.getKeysType()); + stmt.getKeysDesc().getKeysType()); return mv; } + + @Test + void testShowCreateTables() throws Exception { + createTable("create table test.t1 (pk int, v1 int sum) aggregate key (pk) " + + "distributed by hash (pk) buckets 1 properties ('replication_num' = '1');"); + createTable("create table test.t2 (pk int, v2 int sum) aggregate key (pk) " + + "distributed by hash (pk) buckets 1 properties ('replication_num' = '1');"); + StmtExecutor executor = new StmtExecutor(connectContext, "create materialized view mv " + + "build immediate refresh complete key (mv_pk) distributed by hash (mv_pk) " + + "properties ('replication_num' = '1') " + + "as select test.t1.pk as mv_pk from test.t1, test.t2 where test.t1.pk = test.t2.pk"); + ExceptionChecker.expectThrowsNoException(executor::execute); + + ShowExecutor showExecutor = new ShowExecutor(connectContext, + (ShowStmt) parseAndAnalyzeStmt("show create table mv")); + ShowResultSet resultSet = showExecutor.execute(); + String result = resultSet.getResultRows().get(0).get(1); + Assertions.assertTrue(result.contains("CREATE MATERIALIZED VIEW `mv`\n" + + "BUILD IMMEDIATE REFRESH COMPLETE ON DEMAND\n" + + "KEY(`mv_pk`)\n" + + "DISTRIBUTED BY HASH(`mv_pk`) BUCKETS 10")); + } + + @Test + void testDropMaterializedView() throws Exception { + createTable("create table test.t1 (pk int, v1 int sum) aggregate key (pk) " + + "distributed by hash (pk) buckets 1 properties ('replication_num' = '1');"); + createTable("create table test.t2 (pk int, v2 int sum) aggregate key (pk) " + + "distributed by hash (pk) buckets 1 properties ('replication_num' = '1');"); + StmtExecutor executor = new StmtExecutor(connectContext, "create materialized view mv " + + "build immediate refresh complete key (mv_pk) distributed by hash (mv_pk) " + + "properties ('replication_num' = '1') " + + "as select test.t1.pk as mv_pk from test.t1, test.t2 where test.t1.pk = test.t2.pk"); + ExceptionChecker.expectThrowsNoException(executor::execute); + + ExceptionChecker.expectThrowsWithMsg(DdlException.class, "is not TABLE", + () -> Env.getCurrentInternalCatalog() + .dropTable((DropTableStmt) parseAndAnalyzeStmt("drop table mv"))); + + ExceptionChecker.expectThrowsNoException(() -> connectContext.getEnv().dropMaterializedView( + (DropMaterializedViewStmt) parseAndAnalyzeStmt("drop materialized view mv"))); + } } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org