Skip to content

Commit

Permalink
[feature] show create materialized view (#9391) (#11352)
Browse files Browse the repository at this point in the history
Co-authored-by: Stalary <452024236@qq.com>
  • Loading branch information
yiguolei and stalary authored Jul 30, 2022
1 parent 978f65a commit 91b1d34
Show file tree
Hide file tree
Showing 8 changed files with 251 additions and 40 deletions.
38 changes: 19 additions & 19 deletions docs/.vuepress/sidebar/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -790,27 +790,27 @@ module.exports = [
"subscribe-mail-list",
"feedback",
{
title: "How to Contribute",
directoryPath: "how-to-contribute/",
initialOpenGroupIndex: -1,
children: [
"how-to-contribute",
"committer-guide",
"commit-format-specification",
"pull-request",
],
title: "How to Contribute",
directoryPath: "how-to-contribute/",
initialOpenGroupIndex: -1,
children: [
"how-to-contribute",
"committer-guide",
"commit-format-specification",
"pull-request",
],
},
{
title: "Release Process & Verification",
directoryPath: "release-and-verify/",
initialOpenGroupIndex: -1,
children: [
"release-prepare",
"release-doris-core",
"release-doris-connectors",
"release-complete",
"release-verify",
],
title: "Release Process & Verification",
directoryPath: "release-and-verify/",
initialOpenGroupIndex: -1,
children: [
"release-prepare",
"release-doris-core",
"release-doris-connectors",
"release-complete",
"release-verify",
],
},
"security",
],
Expand Down
38 changes: 19 additions & 19 deletions docs/.vuepress/sidebar/zh-CN.js
Original file line number Diff line number Diff line change
Expand Up @@ -794,27 +794,27 @@ module.exports = [
"subscribe-mail-list",
"feedback",
{
title: "贡献指南",
directoryPath: "how-to-contribute/",
initialOpenGroupIndex: -1,
children: [
"how-to-contribute",
"committer-guide",
"commit-format-specification",
"pull-request",
],
title: "贡献指南",
directoryPath: "how-to-contribute/",
initialOpenGroupIndex: -1,
children: [
"how-to-contribute",
"committer-guide",
"commit-format-specification",
"pull-request",
],
},
{
title: "版本发布与校验",
directoryPath: "release-and-verify/",
initialOpenGroupIndex: -1,
children: [
"release-prepare",
"release-doris-core",
"release-doris-connectors",
"release-complete",
"release-verify",
],
title: "版本发布与校验",
directoryPath: "release-and-verify/",
initialOpenGroupIndex: -1,
children: [
"release-prepare",
"release-doris-core",
"release-doris-connectors",
"release-complete",
"release-verify",
],
},
"security",
],
Expand Down
4 changes: 4 additions & 0 deletions fe/fe-core/src/main/cup/sql_parser.cup
Original file line number Diff line number Diff line change
Expand Up @@ -2885,6 +2885,10 @@ show_param ::=
{:
RESULT = new ShowLastInsertStmt();
:}
| KW_CREATE KW_MATERIALIZED KW_VIEW ident:mvName KW_ON table_name:tableName
{:
RESULT = new ShowCreateMaterializedViewStmt(mvName, tableName);
:}
;

opt_tmp ::=
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// 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.Catalog;
import org.apache.doris.catalog.Column;
import org.apache.doris.catalog.ScalarType;
import org.apache.doris.common.ErrorCode;
import org.apache.doris.common.ErrorReport;
import org.apache.doris.common.UserException;
import org.apache.doris.mysql.privilege.PrivPredicate;
import org.apache.doris.qe.ConnectContext;
import org.apache.doris.qe.ShowResultSetMetaData;

import lombok.AllArgsConstructor;
import lombok.Getter;

/**
* SHOW CREATE MATERIALIZED VIEW mv_name ON table_name.
**/
@AllArgsConstructor
@Getter
public class ShowCreateMaterializedViewStmt extends ShowStmt {

private static final ShowResultSetMetaData META_DATA =
ShowResultSetMetaData.builder()
.addColumn(new Column("TableName", ScalarType.createVarchar(255)))
.addColumn(new Column("ViewName", ScalarType.createVarchar(255)))
.addColumn(new Column("CreateStmt", ScalarType.createVarchar(65535)))
.build();

private String mvName;

private TableName tableName;

@Override
public void analyze(Analyzer analyzer) throws UserException {
super.analyze(analyzer);
tableName.analyze(analyzer);
if (!Catalog.getCurrentCatalog().getAuth()
.checkTblPriv(ConnectContext.get(), tableName.getDb(), tableName.getTbl(), PrivPredicate.SHOW)) {
ErrorReport.reportAnalysisException(ErrorCode.ERR_TABLEACCESS_DENIED_ERROR, "SHOW CREATE MATERIALIZED",
ConnectContext.get().getQualifiedUser(),
ConnectContext.get().getRemoteIP(),
tableName.toSql());
}
}

@Override
public ShowResultSetMetaData getMetaData() {
return META_DATA;
}

@Override
public String toSql() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("SHOW CREATE MATERIALIZED VIEW ");
stringBuilder.append("`").append(mvName).append("` ");
stringBuilder.append("ON ").append(tableName.toSql());
return stringBuilder.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ public Column getColumnByName(String columnName) {
return null;
}

public OriginStatement getDefineStmt() {
return defineStmt;
}

@Override
public boolean equals(Object obj) {
if (!(obj instanceof MaterializedIndexMeta)) {
Expand Down
31 changes: 29 additions & 2 deletions fe/fe-core/src/main/java/org/apache/doris/qe/ShowExecutor.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.apache.doris.analysis.ShowColumnStmt;
import org.apache.doris.analysis.ShowCreateDbStmt;
import org.apache.doris.analysis.ShowCreateFunctionStmt;
import org.apache.doris.analysis.ShowCreateMaterializedViewStmt;
import org.apache.doris.analysis.ShowCreateRoutineLoadStmt;
import org.apache.doris.analysis.ShowCreateTableStmt;
import org.apache.doris.analysis.ShowDataSkewStmt;
Expand Down Expand Up @@ -102,6 +103,7 @@
import org.apache.doris.catalog.Index;
import org.apache.doris.catalog.MaterializedIndex;
import org.apache.doris.catalog.MaterializedIndex.IndexExtState;
import org.apache.doris.catalog.MaterializedIndexMeta;
import org.apache.doris.catalog.MetadataViewer;
import org.apache.doris.catalog.OlapTable;
import org.apache.doris.catalog.Partition;
Expand Down Expand Up @@ -340,6 +342,8 @@ public ShowResultSet execute() throws AnalysisException {
handleAdminShowTabletStorageFormat();
} else if (stmt instanceof AdminDiagnoseTabletStmt) {
handleAdminDiagnoseTablet();
} else if (stmt instanceof ShowCreateMaterializedViewStmt) {
handleShowCreateMaterializedView();
} else {
handleEmtpy();
}
Expand Down Expand Up @@ -393,7 +397,7 @@ private void handleShowEngines() {
rowSet.add(Lists.newArrayList("HIVE", "YES", "HIVE database which data is in it", "NO", "NO", "NO"));
rowSet.add(Lists.newArrayList("ICEBERG", "YES", "ICEBERG data lake which data is in it", "NO", "NO", "NO"));
rowSet.add(Lists.newArrayList("ODBC", "YES", "ODBC driver which data we can connect", "NO", "NO", "NO"));

// Only success
resultSet = new ShowResultSet(showStmt.getMetaData(), rowSet);
}
Expand Down Expand Up @@ -1747,7 +1751,7 @@ private void handleShowRoles() {
List<List<String>> infos = Catalog.getCurrentCatalog().getAuth().getRoleInfo();
resultSet = new ShowResultSet(showStmt.getMetaData(), infos);
}

private void handleShowTrash() {
ShowTrashStmt showStmt = (ShowTrashStmt) stmt;
List<List<String>> infos = Lists.newArrayList();
Expand Down Expand Up @@ -2179,4 +2183,27 @@ private void handleAdminDiagnoseTablet() {
resultSet = new ShowResultSet(showMetaData, resultRowSet);
}

private void handleShowCreateMaterializedView() throws AnalysisException {
List<List<String>> resultRowSet = new ArrayList<>();
ShowCreateMaterializedViewStmt showStmt = (ShowCreateMaterializedViewStmt) stmt;
Database db = Catalog.getCurrentCatalog().getDbOrAnalysisException(showStmt.getTableName().getDb());
Table table = db.getTableOrAnalysisException(showStmt.getTableName().getTbl());
if (table instanceof OlapTable) {
OlapTable baseTable = ((OlapTable) table);
Long indexIdByName = baseTable.getIndexIdByName(showStmt.getMvName());
if (indexIdByName != null) {
MaterializedIndexMeta meta = baseTable.getIndexMetaByIndexId(indexIdByName);
if (meta != null && meta.getDefineStmt() != null) {
String originStmt = meta.getDefineStmt().originStmt;
List<String> data = new ArrayList<>();
data.add(showStmt.getTableName().getTbl());
data.add(showStmt.getMvName());
data.add(originStmt);
resultRowSet.add(data);
}
}
}
resultSet = new ShowResultSet(showStmt.getMetaData(), resultRowSet);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// 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.common.AnalysisException;
import org.apache.doris.common.ExceptionChecker;
import org.apache.doris.qe.ConnectContext;
import org.apache.doris.qe.ShowExecutor;
import org.apache.doris.utframe.DorisAssert;
import org.apache.doris.utframe.UtFrameUtils;

import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

import java.io.File;
import java.util.UUID;

/**
* test for ShowCreateMaterializedViewStmt.
**/
public class ShowCreateMaterializedViewStmtTest {

private static String runningDir = "fe/mocked/ShowCreateMaterializedViewStmtTest/" + UUID.randomUUID() + "/";

private static ConnectContext connectContext;

private static DorisAssert dorisAssert;

/**
* init.
**/
@BeforeClass
public static void beforeClass() throws Exception {
UtFrameUtils.createDorisCluster(runningDir);

// create connect context
connectContext = UtFrameUtils.createDefaultCtx();
dorisAssert = new DorisAssert(connectContext);
dorisAssert.withDatabase("test")
.withTable("create table test.table1 (k1 int, k2 int) distributed by hash(k1) "
+ "buckets 1 properties(\"replication_num\" = \"1\");")
.withMaterializedView("CREATE MATERIALIZED VIEW test_mv as select k1 from test.table1;");
}

@AfterClass
public static void tearDown() {
File file = new File(runningDir);
file.delete();
}

@Test
public void testNormal() throws Exception {
String showMvSql = "SHOW CREATE MATERIALIZED VIEW test_mv on test.table1;";
ShowCreateMaterializedViewStmt showStmt =
(ShowCreateMaterializedViewStmt) UtFrameUtils.parseAndAnalyzeStmt(showMvSql, connectContext);
ShowExecutor executor = new ShowExecutor(connectContext, showStmt);
Assert.assertEquals(executor.execute().getResultRows().get(0).get(2),
"CREATE MATERIALIZED VIEW test_mv as select k1 from test.table1;");
}

@Test
public void testNoView() throws Exception {
String showMvSql = "SHOW CREATE MATERIALIZED VIEW test_mv_empty on test.table1;";
ShowCreateMaterializedViewStmt showStmt =
(ShowCreateMaterializedViewStmt) UtFrameUtils.parseAndAnalyzeStmt(showMvSql, connectContext);
ShowExecutor executor = new ShowExecutor(connectContext, showStmt);
Assert.assertTrue(executor.execute().getResultRows().isEmpty());
}

@Test
public void testNoTable() throws Exception {
String showMvSql = "SHOW CREATE MATERIALIZED VIEW test_mv on test.table1_error;";
ShowCreateMaterializedViewStmt showStmt =
(ShowCreateMaterializedViewStmt) UtFrameUtils.parseAndAnalyzeStmt(showMvSql, connectContext);
ShowExecutor executor = new ShowExecutor(connectContext, showStmt);
ExceptionChecker.expectThrowsWithMsg(AnalysisException.class,
"Unknown table 'table1_error' in default_cluster:test", executor::execute);

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.apache.doris.mysql.privilege.PaloAuth;
import org.apache.doris.planner.Planner;
import org.apache.doris.qe.ConnectContext;
import org.apache.doris.qe.OriginStatement;
import org.apache.doris.qe.QueryState;
import org.apache.doris.qe.StmtExecutor;
import org.apache.doris.system.Backend;
Expand Down Expand Up @@ -98,6 +99,7 @@ public static StatementBase parseAndAnalyzeStmt(String originStmt, ConnectContex
}
}
statementBase.analyze(analyzer);
statementBase.setOrigStmt(new OriginStatement(originStmt, 0));
return statementBase;
}

Expand Down

0 comments on commit 91b1d34

Please sign in to comment.