[feature] show create materialized view (#9391)

This commit is contained in:
Stalary
2022-05-11 09:29:55 +08:00
committed by GitHub
parent 718a51a388
commit 092a12e983
12 changed files with 373 additions and 6 deletions

View File

@ -2895,6 +2895,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 ::=

View File

@ -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();
}
}

View File

@ -136,6 +136,10 @@ public class MaterializedIndexMeta implements Writable, GsonPostProcessable {
return null;
}
public OriginStatement getDefineStmt() {
return defineStmt;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof MaterializedIndexMeta)) {

View File

@ -36,6 +36,7 @@ import org.apache.doris.analysis.ShowColumnStatsStmt;
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;
@ -102,6 +103,7 @@ import org.apache.doris.catalog.Function;
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;
@ -340,6 +342,8 @@ public class ShowExecutor {
handleAdminShowTabletStorageFormat();
} else if (stmt instanceof AdminDiagnoseTabletStmt) {
handleAdminDiagnoseTablet();
} else if (stmt instanceof ShowCreateMaterializedViewStmt) {
handleShowCreateMaterializedView();
} else {
handleEmtpy();
}
@ -392,7 +396,7 @@ public class ShowExecutor {
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);
}
@ -1746,7 +1750,7 @@ public class ShowExecutor {
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();
@ -2178,4 +2182,27 @@ public class ShowExecutor {
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);
}
}

View File

@ -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);
}
}

View File

@ -34,6 +34,7 @@ import org.apache.doris.common.util.SqlParserUtils;
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;
@ -107,6 +108,7 @@ public class UtFrameUtils {
}
}
statementBase.analyze(analyzer);
statementBase.setOrigStmt(new OriginStatement(originStmt, 0));
return statementBase;
}