blob: 33f20ff7baee4f612590b5de0ef11700575e7337 [file] [log] [blame]
// 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.qe;
import org.apache.doris.analysis.AccessTestUtil;
import org.apache.doris.analysis.Analyzer;
import org.apache.doris.analysis.DescribeStmt;
import org.apache.doris.analysis.HelpStmt;
import org.apache.doris.analysis.SetType;
import org.apache.doris.analysis.ShowAuthorStmt;
import org.apache.doris.analysis.ShowColumnStmt;
import org.apache.doris.analysis.ShowCreateDbStmt;
import org.apache.doris.analysis.ShowCreateTableStmt;
import org.apache.doris.analysis.ShowDbStmt;
import org.apache.doris.analysis.ShowEnginesStmt;
import org.apache.doris.analysis.ShowProcedureStmt;
import org.apache.doris.analysis.ShowTableStmt;
import org.apache.doris.analysis.ShowVariablesStmt;
import org.apache.doris.analysis.TableName;
import org.apache.doris.catalog.Catalog;
import org.apache.doris.catalog.Column;
import org.apache.doris.catalog.Database;
import org.apache.doris.catalog.KeysType;
import org.apache.doris.catalog.MaterializedIndex;
import org.apache.doris.catalog.OlapTable;
import org.apache.doris.catalog.Partition;
import org.apache.doris.catalog.PrimitiveType;
import org.apache.doris.catalog.RandomDistributionInfo;
import org.apache.doris.catalog.SinglePartitionInfo;
import org.apache.doris.catalog.Table;
import org.apache.doris.catalog.Table.TableType;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.PatternMatcher;
import org.apache.doris.common.UserException;
import org.apache.doris.common.jmockit.Deencapsulation;
import org.apache.doris.mysql.MysqlCommand;
import org.apache.doris.mysql.privilege.PaloAuth;
import org.apache.doris.system.SystemInfoService;
import org.apache.doris.thrift.TStorageType;
import com.google.common.collect.Lists;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import java.io.IOException;
import java.net.URL;
import java.util.List;
import mockit.Expectations;
import mockit.Mock;
import mockit.MockUp;
public class ShowExecutorTest {
private ConnectContext ctx;
private Catalog catalog;
@Rule
public ExpectedException expectedEx = ExpectedException.none();
@Before
public void setUp() throws Exception {
ctx = new ConnectContext(null);
ctx.setCommand(MysqlCommand.COM_SLEEP);
Column column1 = new Column("col1", PrimitiveType.BIGINT);
Column column2 = new Column("col2", PrimitiveType.DOUBLE);
column1.setIsKey(true);
column2.setIsKey(true);
// mock index 1
MaterializedIndex index1 = new MaterializedIndex();
// mock index 2
MaterializedIndex index2 = new MaterializedIndex();
// mock partition
Partition partition = Deencapsulation.newInstance(Partition.class);
new Expectations(partition) {
{
partition.getBaseIndex();
minTimes = 0;
result = index1;
}
};
// mock table
OlapTable table = new OlapTable();
new Expectations(table) {
{
table.getName();
minTimes = 0;
result = "testTbl";
table.getType();
minTimes = 0;
result = TableType.OLAP;
table.getBaseSchema();
minTimes = 0;
result = Lists.newArrayList(column1, column2);
table.getKeysType();
minTimes = 0;
result = KeysType.AGG_KEYS;
table.getPartitionInfo();
minTimes = 0;
result = new SinglePartitionInfo();
table.getDefaultDistributionInfo();
minTimes = 0;
result = new RandomDistributionInfo(10);
table.getIndexIdByName(anyString);
minTimes = 0;
result = 0L;
table.getStorageTypeByIndexId(0L);
minTimes = 0;
result = TStorageType.COLUMN;
table.getPartition(anyLong);
minTimes = 0;
result = partition;
table.getCopiedBfColumns();
minTimes = 0;
result = null;
}
};
// mock database
Database db = new Database();
new Expectations(db) {
{
db.readLock();
minTimes = 0;
db.readUnlock();
minTimes = 0;
db.getTable(anyString);
minTimes = 0;
result = table;
}
};
// mock auth
PaloAuth auth = AccessTestUtil.fetchAdminAccess();
// mock catalog.
catalog = Deencapsulation.newInstance(Catalog.class);
new Expectations(catalog) {
{
catalog.getDb("testCluster:testDb");
minTimes = 0;
result = db;
catalog.getDb("testCluster:emptyDb");
minTimes = 0;
result = null;
catalog.getClusterDbNames("testCluster");
minTimes = 0;
result = Lists.newArrayList("testCluster:testDb");
catalog.getClusterDbNames("");
minTimes = 0;
result = Lists.newArrayList("");
catalog.getAuth();
minTimes = 0;
result = auth;
Catalog.getCurrentCatalog();
minTimes = 0;
result = catalog;
Catalog.getCurrentCatalog();
minTimes = 0;
result = catalog;
Catalog.getDdlStmt((Table) any, (List) any, (List) any, (List) any, anyBoolean, anyBoolean);
minTimes = 0;
Catalog.getDdlStmt((Table) any, (List) any, null, null, anyBoolean, anyBoolean);
minTimes = 0;
}
};
// mock scheduler
ConnectScheduler scheduler = new ConnectScheduler(10);
new Expectations(scheduler) {
{
scheduler.listConnection("testCluster:testUser");
minTimes = 0;
result = Lists.newArrayList(ctx.toThreadInfo());
}
};
ctx.setConnectScheduler(scheduler);
ctx.setCatalog(AccessTestUtil.fetchAdminCatalog());
ctx.setQualifiedUser("testCluster:testUser");
ctx.setCluster("testCluster");
new Expectations(ctx) {
{
ConnectContext.get();
minTimes = 0;
result = ctx;
}
};
}
@Test
public void testShowDb() throws AnalysisException {
ShowDbStmt stmt = new ShowDbStmt(null);
ShowExecutor executor = new ShowExecutor(ctx, stmt);
ShowResultSet resultSet = executor.execute();
Assert.assertTrue(resultSet.next());
Assert.assertEquals("testDb", resultSet.getString(0));
}
@Test
public void testShowDbPattern() throws AnalysisException {
ShowDbStmt stmt = new ShowDbStmt("testCluster:empty%");
ShowExecutor executor = new ShowExecutor(ctx, stmt);
ShowResultSet resultSet = executor.execute();
Assert.assertFalse(resultSet.next());
}
@Test
public void testShowDbPriv() throws AnalysisException {
ShowDbStmt stmt = new ShowDbStmt(null);
ShowExecutor executor = new ShowExecutor(ctx, stmt);
ctx.setCatalog(AccessTestUtil.fetchBlockCatalog());
ShowResultSet resultSet = executor.execute();
}
@Test
public void testShowTable() throws AnalysisException {
ShowTableStmt stmt = new ShowTableStmt("testCluster:testDb", false, null);
ShowExecutor executor = new ShowExecutor(ctx, stmt);
ShowResultSet resultSet = executor.execute();
Assert.assertTrue(resultSet.next());
Assert.assertEquals("testTbl", resultSet.getString(0));
Assert.assertFalse(resultSet.next());
}
@Test
public void testShowTableFromUnknownDatabase() throws AnalysisException {
ShowTableStmt stmt = new ShowTableStmt("testCluster:emptyDb", false, null);
ShowExecutor executor = new ShowExecutor(ctx, stmt);
expectedEx.expect(AnalysisException.class);
expectedEx.expectMessage("Unknown database 'testCluster:emptyDb'");
executor.execute();
}
@Test
public void testShowTablePattern() throws AnalysisException {
ShowTableStmt stmt = new ShowTableStmt("testCluster:testDb", false, "empty%");
ShowExecutor executor = new ShowExecutor(ctx, stmt);
ShowResultSet resultSet = executor.execute();
Assert.assertFalse(resultSet.next());
}
@Ignore
@Test
public void testDescribe() {
SystemInfoService clusterInfo = AccessTestUtil.fetchSystemInfoService();
Analyzer analyzer = AccessTestUtil.fetchAdminAnalyzer(false);
Catalog catalog = AccessTestUtil.fetchAdminCatalog();
new MockUp<Catalog>() {
@Mock
Catalog getCurrentCatalog() {
return catalog;
}
@Mock
SystemInfoService getCurrentSystemInfo() {
return clusterInfo;
}
};
DescribeStmt stmt = new DescribeStmt(new TableName("testCluster:testDb", "testTbl"), false);
try {
stmt.analyze(analyzer);
} catch (Exception e) {
e.printStackTrace();
Assert.fail();
}
ShowExecutor executor = new ShowExecutor(ctx, stmt);
ShowResultSet resultSet;
try {
resultSet = executor.execute();
Assert.assertFalse(resultSet.next());
} catch (AnalysisException e) {
e.printStackTrace();
Assert.fail();
}
}
@Test
public void testShowVariable() throws AnalysisException {
// Mock variable
VariableMgr variableMgr = new VariableMgr();
List<List<String>> rows = Lists.newArrayList();
rows.add(Lists.newArrayList("var1", "abc"));
rows.add(Lists.newArrayList("var2", "abc"));
new Expectations(variableMgr) {
{
VariableMgr.dump((SetType) any, (SessionVariable) any, (PatternMatcher) any);
minTimes = 0;
result = rows;
VariableMgr.dump((SetType) any, (SessionVariable) any, null);
minTimes = 0;
result = rows;
}
};
ShowVariablesStmt stmt = new ShowVariablesStmt(SetType.SESSION, "var%");
ShowExecutor executor = new ShowExecutor(ctx, stmt);
ShowResultSet resultSet = executor.execute();
Assert.assertTrue(resultSet.next());
Assert.assertEquals("var1", resultSet.getString(0));
Assert.assertTrue(resultSet.next());
Assert.assertEquals("var2", resultSet.getString(0));
Assert.assertFalse(resultSet.next());
stmt = new ShowVariablesStmt(SetType.SESSION, null);
executor = new ShowExecutor(ctx, stmt);
resultSet = executor.execute();
Assert.assertTrue(resultSet.next());
Assert.assertEquals("var1", resultSet.getString(0));
Assert.assertTrue(resultSet.next());
Assert.assertEquals("var2", resultSet.getString(0));
Assert.assertFalse(resultSet.next());
}
@Test
public void testShowTableVerbose() throws AnalysisException {
ShowTableStmt stmt = new ShowTableStmt("testCluster:testDb", true, null);
ShowExecutor executor = new ShowExecutor(ctx, stmt);
ShowResultSet resultSet = executor.execute();
Assert.assertTrue(resultSet.next());
Assert.assertEquals("testTbl", resultSet.getString(0));
Assert.assertEquals("BASE TABLE", resultSet.getString(1));
Assert.assertFalse(resultSet.next());
}
@Test
public void testShowCreateDb() throws AnalysisException {
ctx.setCatalog(catalog);
ctx.setQualifiedUser("testCluster:testUser");
ShowCreateDbStmt stmt = new ShowCreateDbStmt("testCluster:testDb");
ShowExecutor executor = new ShowExecutor(ctx, stmt);
ShowResultSet resultSet = executor.execute();
Assert.assertTrue(resultSet.next());
Assert.assertEquals("testDb", resultSet.getString(0));
Assert.assertEquals("CREATE DATABASE `testDb`", resultSet.getString(1));
Assert.assertFalse(resultSet.next());
}
@Test(expected = AnalysisException.class)
public void testShowCreateNoDb() throws AnalysisException {
ctx.setCatalog(catalog);
ctx.setQualifiedUser("testCluster:testUser");
ShowCreateDbStmt stmt = new ShowCreateDbStmt("testCluster:emptyDb");
ShowExecutor executor = new ShowExecutor(ctx, stmt);
ShowResultSet resultSet = executor.execute();
Assert.fail("No exception throws.");
}
@Test(expected = AnalysisException.class)
public void testShowCreateTableEmptyDb() throws AnalysisException {
ShowCreateTableStmt stmt = new ShowCreateTableStmt(new TableName("testCluster:emptyDb", "testTable"));
ShowExecutor executor = new ShowExecutor(ctx, stmt);
ShowResultSet resultSet = executor.execute();
Assert.fail("No Exception throws.");
}
@Test(expected = AnalysisException.class)
public void testShowCreateTableEmptyTbl() throws AnalysisException {
ShowCreateTableStmt stmt = new ShowCreateTableStmt(new TableName("testCluster:testDb", "emptyTable"));
ShowExecutor executor = new ShowExecutor(ctx, stmt);
ShowResultSet resultSet = executor.execute();
Assert.assertFalse(resultSet.next());
}
@Test
public void testShowColumn() throws AnalysisException {
ctx.setCatalog(catalog);
ctx.setQualifiedUser("testCluster:testUser");
ShowColumnStmt stmt = new ShowColumnStmt(new TableName("testCluster:testDb", "testTbl"), null, null, false);
stmt.analyze(AccessTestUtil.fetchAdminAnalyzer(false));
ShowExecutor executor = new ShowExecutor(ctx, stmt);
ShowResultSet resultSet = executor.execute();
Assert.assertTrue(resultSet.next());
Assert.assertEquals("col1", resultSet.getString(0));
Assert.assertEquals("NO", resultSet.getString(2));
Assert.assertTrue(resultSet.next());
Assert.assertEquals("col2", resultSet.getString(0));
Assert.assertFalse(resultSet.next());
// verbose
stmt = new ShowColumnStmt(new TableName("testCluster:testDb", "testTbl"), null, null, true);
stmt.analyze(AccessTestUtil.fetchAdminAnalyzer(false));
executor = new ShowExecutor(ctx, stmt);
resultSet = executor.execute();
Assert.assertTrue(resultSet.next());
Assert.assertEquals("col1", resultSet.getString(0));
Assert.assertEquals("NO", resultSet.getString(3));
Assert.assertTrue(resultSet.next());
Assert.assertEquals("col2", resultSet.getString(0));
Assert.assertEquals("NO", resultSet.getString(3));
Assert.assertFalse(resultSet.next());
// pattern
stmt = new ShowColumnStmt(new TableName("testCluster:testDb", "testTable"), null, "%1", true);
stmt.analyze(AccessTestUtil.fetchAdminAnalyzer(false));
executor = new ShowExecutor(ctx, stmt);
resultSet = executor.execute();
Assert.assertTrue(resultSet.next());
Assert.assertEquals("col1", resultSet.getString(0));
Assert.assertEquals("NO", resultSet.getString(3));
Assert.assertFalse(resultSet.next());
}
@Test
public void testShowColumnFromUnknownTable() throws AnalysisException {
ShowColumnStmt stmt = new ShowColumnStmt(new TableName("testCluster:emptyDb", "testTable"), null, null, false);
stmt.analyze(AccessTestUtil.fetchAdminAnalyzer(false));
ShowExecutor executor = new ShowExecutor(ctx, stmt);
expectedEx.expect(AnalysisException.class);
expectedEx.expectMessage("Unknown table 'testCluster:emptyDb.testTable'");
executor.execute();
// empty table
stmt = new ShowColumnStmt(new TableName("testCluster:testDb", "emptyTable"), null, null, true);
stmt.analyze(AccessTestUtil.fetchAdminAnalyzer(false));
executor = new ShowExecutor(ctx, stmt);
expectedEx.expect(AnalysisException.class);
expectedEx.expectMessage("Unknown table 'testCluster:testDb.emptyTable'");
executor.execute();
}
@Test
public void testShowAuthors() throws AnalysisException {
ShowAuthorStmt stmt = new ShowAuthorStmt();
ShowExecutor executor = new ShowExecutor(ctx, stmt);
ShowResultSet resultSet = executor.execute();
Assert.assertEquals(3, resultSet.getMetaData().getColumnCount());
Assert.assertEquals("Name", resultSet.getMetaData().getColumn(0).getName());
Assert.assertEquals("Location", resultSet.getMetaData().getColumn(1).getName());
Assert.assertEquals("Comment", resultSet.getMetaData().getColumn(2).getName());
}
@Test
public void testShowEngine() throws AnalysisException {
ShowEnginesStmt stmt = new ShowEnginesStmt();
ShowExecutor executor = new ShowExecutor(ctx, stmt);
ShowResultSet resultSet = executor.execute();
Assert.assertTrue(resultSet.next());
Assert.assertEquals("Olap engine", resultSet.getString(0));
}
@Test
public void testShowEmpty() throws AnalysisException {
ShowProcedureStmt stmt = new ShowProcedureStmt();
ShowExecutor executor = new ShowExecutor(ctx, stmt);
ShowResultSet resultSet = executor.execute();
Assert.assertFalse(resultSet.next());
}
@Test
public void testHelp() throws AnalysisException, IOException, UserException {
HelpModule module = new HelpModule();
URL help = getClass().getClassLoader().getResource("test-help-resource-show-help.zip");
module.setUpByZip(help.getPath());
new Expectations(module) {
{
HelpModule.getInstance();
minTimes = 0;
result = module;
}
};
// topic
HelpStmt stmt = new HelpStmt("ADD");
ShowExecutor executor = new ShowExecutor(ctx, stmt);
ShowResultSet resultSet = executor.execute();
Assert.assertTrue(resultSet.next());
Assert.assertEquals("ADD", resultSet.getString(0));
Assert.assertEquals("add function\n", resultSet.getString(1));
Assert.assertFalse(resultSet.next());
// topic
stmt = new HelpStmt("logical");
executor = new ShowExecutor(ctx, stmt);
resultSet = executor.execute();
Assert.assertTrue(resultSet.next());
Assert.assertEquals("OR", resultSet.getString(0));
Assert.assertFalse(resultSet.next());
// keywords
stmt = new HelpStmt("MATH");
executor = new ShowExecutor(ctx, stmt);
resultSet = executor.execute();
Assert.assertTrue(resultSet.next());
Assert.assertEquals("ADD", resultSet.getString(0));
Assert.assertTrue(resultSet.next());
Assert.assertEquals("MINUS", resultSet.getString(0));
Assert.assertFalse(resultSet.next());
// category
stmt = new HelpStmt("functions");
executor = new ShowExecutor(ctx, stmt);
resultSet = executor.execute();
Assert.assertTrue(resultSet.next());
Assert.assertEquals("HELP", resultSet.getString(0));
Assert.assertTrue(resultSet.next());
Assert.assertEquals("binary function", resultSet.getString(0));
Assert.assertTrue(resultSet.next());
Assert.assertEquals("bit function", resultSet.getString(0));
Assert.assertFalse(resultSet.next());
// empty
stmt = new HelpStmt("empty");
executor = new ShowExecutor(ctx, stmt);
resultSet = executor.execute();
Assert.assertFalse(resultSet.next());
}
}