Skip to content

Commit aca2e13

Browse files
committed
ut
1 parent 402e399 commit aca2e13

16 files changed

Lines changed: 849 additions & 0 deletions

File tree

integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBDatabaseIT.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,51 @@ public void testManageDatabase() {
285285
}
286286
}
287287

288+
@Test
289+
public void testShowCreateDatabase() throws SQLException {
290+
try (final Connection connection =
291+
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
292+
final Statement statement = connection.createStatement()) {
293+
statement.execute(
294+
"create database test_show_create_db with (ttl=300, schema_region_group_num=DEFAULT, data_region_group_num=DEFAULT, time_partition_interval=100000)");
295+
296+
TestUtils.assertResultSetEqual(
297+
statement.executeQuery("show create database test_show_create_db"),
298+
"Database,Create Database,",
299+
Collections.singleton(
300+
"test_show_create_db,CREATE DATABASE \"test_show_create_db\" WITH (ttl=300,time_partition_interval=100000,schema_region_group_num=0,data_region_group_num=0),"));
301+
}
302+
}
303+
304+
@Test
305+
public void testShowCreatePipe() throws SQLException {
306+
try (final Connection connection =
307+
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
308+
final Statement statement = connection.createStatement()) {
309+
statement.execute("create pipe test_show_create_pipe ('sink'='do-nothing-sink')");
310+
311+
TestUtils.assertResultSetEqual(
312+
statement.executeQuery("show create pipe test_show_create_pipe"),
313+
"Pipe,Create Pipe,",
314+
Collections.singleton(
315+
"test_show_create_pipe,CREATE PIPE \"test_show_create_pipe\" WITH SINK ('sink'='do-nothing-sink'),"));
316+
}
317+
}
318+
319+
@Test
320+
public void testShowCreateInformationSchemaDatabase() throws SQLException {
321+
try (final Connection connection =
322+
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
323+
final Statement statement = connection.createStatement()) {
324+
try {
325+
statement.executeQuery("show create database information_schema");
326+
fail("show create database information_schema shouldn't succeed");
327+
} catch (final SQLException e) {
328+
assertEquals("701: The system database does not support show create.", e.getMessage());
329+
}
330+
}
331+
}
332+
288333
@Test
289334
public void testDatabaseWithSpecificCharacters() throws SQLException {
290335
try (final Connection connection =

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/header/DatasetHeaderFactory.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,14 @@ public static DatasetHeader getShowCreateTableColumnHeader() {
263263
return new DatasetHeader(ColumnHeaderConstant.showCreateTableColumnHeaders, true);
264264
}
265265

266+
public static DatasetHeader getShowCreatePipeColumnHeader() {
267+
return new DatasetHeader(ColumnHeaderConstant.showCreatePipeColumnHeaders, true);
268+
}
269+
270+
public static DatasetHeader getShowCreateDatabaseColumnHeader() {
271+
return new DatasetHeader(ColumnHeaderConstant.showCreateDatabaseColumnHeaders, true);
272+
}
273+
266274
public static DatasetHeader getShowTablesHeader() {
267275
return new DatasetHeader(ColumnHeaderConstant.showTablesColumnHeaders, true);
268276
}

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@
110110
import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.relational.RelationalAuthorizerTask;
111111
import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.relational.ShowAINodesTask;
112112
import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.relational.ShowConfigNodesTask;
113+
import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.relational.ShowCreateDatabaseTask;
114+
import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.relational.ShowCreatePipeTask;
113115
import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.relational.ShowCreateTableTask;
114116
import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.relational.ShowCreateViewTask;
115117
import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.relational.ShowDBTask;
@@ -209,6 +211,8 @@
209211
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.ShowClusterId;
210212
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.ShowConfigNodes;
211213
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.ShowConfiguration;
214+
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.ShowCreateDatabase;
215+
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.ShowCreatePipe;
212216
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.ShowCurrentDatabase;
213217
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.ShowCurrentSqlDialect;
214218
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.ShowCurrentTimestamp;
@@ -424,6 +428,15 @@ public IConfigTask visitShowDB(final ShowDB node, final MPPQueryContext context)
424428
canShowDB(accessControl, context.getSession().getUserName(), databaseName, context));
425429
}
426430

431+
@Override
432+
public IConfigTask visitShowCreateDatabase(
433+
final ShowCreateDatabase node, final MPPQueryContext context) {
434+
context.setQueryType(QueryType.READ);
435+
accessControl.checkCanShowOrUseDatabase(
436+
context.getSession().getUserName(), node.getDatabase(), context);
437+
return new ShowCreateDatabaseTask(node.getDatabase());
438+
}
439+
427440
public static boolean canShowDB(
428441
final AccessControl accessControl,
429442
final String userName,
@@ -1341,6 +1354,12 @@ public IConfigTask visitShowPipes(ShowPipes node, MPPQueryContext context) {
13411354
return new ShowPipeTask(node, context.getSession().getUserName());
13421355
}
13431356

1357+
@Override
1358+
public IConfigTask visitShowCreatePipe(ShowCreatePipe node, MPPQueryContext context) {
1359+
context.setQueryType(QueryType.READ);
1360+
return new ShowCreatePipeTask(node.getPipeName(), context.getSession().getUserName());
1361+
}
1362+
13441363
@Override
13451364
public IConfigTask visitCreatePipePlugin(CreatePipePlugin node, MPPQueryContext context) {
13461365
context.setQueryType(QueryType.OTHER);

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
import org.apache.iotdb.commons.schema.column.ColumnHeader;
8282
import org.apache.iotdb.commons.schema.column.ColumnHeaderConstant;
8383
import org.apache.iotdb.commons.schema.table.AlterOrDropTableOperationType;
84+
import org.apache.iotdb.commons.schema.table.InformationSchema;
8485
import org.apache.iotdb.commons.schema.table.TsTable;
8586
import org.apache.iotdb.commons.schema.table.TsTableInternalRPCUtil;
8687
import org.apache.iotdb.commons.schema.table.column.TsTableColumnSchema;
@@ -118,6 +119,7 @@
118119
import org.apache.iotdb.confignode.rpc.thrift.TCreateTriggerReq;
119120
import org.apache.iotdb.confignode.rpc.thrift.TDataNodeRemoveReq;
120121
import org.apache.iotdb.confignode.rpc.thrift.TDataNodeRemoveResp;
122+
import org.apache.iotdb.confignode.rpc.thrift.TDatabaseInfo;
121123
import org.apache.iotdb.confignode.rpc.thrift.TDatabaseSchema;
122124
import org.apache.iotdb.confignode.rpc.thrift.TDeactivateSchemaTemplateReq;
123125
import org.apache.iotdb.confignode.rpc.thrift.TDeleteDatabasesReq;
@@ -162,6 +164,7 @@
162164
import org.apache.iotdb.confignode.rpc.thrift.TShowPipeInfo;
163165
import org.apache.iotdb.confignode.rpc.thrift.TShowPipePluginReq;
164166
import org.apache.iotdb.confignode.rpc.thrift.TShowPipeReq;
167+
import org.apache.iotdb.confignode.rpc.thrift.TShowPipeResp;
165168
import org.apache.iotdb.confignode.rpc.thrift.TShowRegionReq;
166169
import org.apache.iotdb.confignode.rpc.thrift.TShowRegionResp;
167170
import org.apache.iotdb.confignode.rpc.thrift.TShowSubscriptionReq;
@@ -232,6 +235,8 @@
232235
import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.relational.DeleteDeviceTask;
233236
import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.relational.DescribeTableDetailsTask;
234237
import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.relational.DescribeTableTask;
238+
import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.relational.ShowCreateDatabaseTask;
239+
import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.relational.ShowCreatePipeTask;
235240
import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.relational.ShowCreateTableTask;
236241
import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.relational.ShowCreateViewTask;
237242
import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.relational.ShowDBTask;
@@ -2740,6 +2745,65 @@ public SettableFuture<ConfigTaskResult> showPipes(
27402745
return future;
27412746
}
27422747

2748+
@Override
2749+
public SettableFuture<ConfigTaskResult> showCreatePipe(
2750+
final String pipeName, final String userName) {
2751+
final SettableFuture<ConfigTaskResult> future = SettableFuture.create();
2752+
try (final ConfigNodeClient configNodeClient =
2753+
CONFIG_NODE_CLIENT_MANAGER.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) {
2754+
final TShowPipeReq tShowPipeReq =
2755+
new TShowPipeReq().setPipeName(pipeName).setIsTableModel(true);
2756+
if (Objects.nonNull(userName)) {
2757+
tShowPipeReq.setUserName(userName);
2758+
}
2759+
final TShowPipeResp showPipeResp = configNodeClient.showPipe(tShowPipeReq);
2760+
if (showPipeResp.getStatus().getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
2761+
future.setException(new IoTDBException(showPipeResp.getStatus()));
2762+
return future;
2763+
}
2764+
if (!showPipeResp.isSetPipeInfoList() || showPipeResp.getPipeInfoList().isEmpty()) {
2765+
future.setException(
2766+
new IoTDBException(
2767+
String.format("Failed to show create pipe %s, the pipe does not exist.", pipeName),
2768+
TSStatusCode.PIPE_NOT_EXIST_ERROR.getStatusCode()));
2769+
return future;
2770+
}
2771+
2772+
final TGetAllPipeInfoResp getAllPipeInfoResp = configNodeClient.getAllPipeInfo();
2773+
if (getAllPipeInfoResp.getStatus().getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
2774+
future.setException(
2775+
new IoTDBException(
2776+
String.format(
2777+
"Failed to get pipe info from config node, status is %s.",
2778+
getAllPipeInfoResp.getStatus()),
2779+
TSStatusCode.PIPE_ERROR.getStatusCode()));
2780+
return future;
2781+
}
2782+
2783+
final PipeMeta pipeMeta =
2784+
getAllPipeInfoResp.getAllPipeInfo().stream()
2785+
.map(PipeMeta::deserialize4Coordinator)
2786+
.filter(
2787+
meta ->
2788+
meta.getStaticMeta().visibleUnder(true)
2789+
&& meta.getStaticMeta().getPipeName().equals(pipeName))
2790+
.findFirst()
2791+
.orElse(null);
2792+
if (pipeMeta == null) {
2793+
future.setException(
2794+
new IoTDBException(
2795+
String.format("Failed to show create pipe %s, the pipe does not exist.", pipeName),
2796+
TSStatusCode.PIPE_NOT_EXIST_ERROR.getStatusCode()));
2797+
return future;
2798+
}
2799+
2800+
ShowCreatePipeTask.buildTsBlock(pipeMeta, future);
2801+
} catch (final Exception e) {
2802+
future.setException(e);
2803+
}
2804+
return future;
2805+
}
2806+
27432807
@Override
27442808
public SettableFuture<ConfigTaskResult> showSubscriptions(
27452809
final ShowSubscriptionsStatement showSubscriptionsStatement) {
@@ -4140,6 +4204,46 @@ public SettableFuture<ConfigTaskResult> showDatabases(
41404204
return future;
41414205
}
41424206

4207+
@Override
4208+
public SettableFuture<ConfigTaskResult> showCreateDatabase(final String database) {
4209+
final SettableFuture<ConfigTaskResult> future = SettableFuture.create();
4210+
if (InformationSchema.INFORMATION_DATABASE.equals(database)) {
4211+
future.setException(
4212+
new IoTDBException(
4213+
"The system database does not support show create.",
4214+
TSStatusCode.SEMANTIC_ERROR.getStatusCode()));
4215+
return future;
4216+
}
4217+
4218+
final List<String> databasePathPattern = Arrays.asList(ROOT, database);
4219+
try (final ConfigNodeClient client =
4220+
CONFIG_NODE_CLIENT_MANAGER.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) {
4221+
final TGetDatabaseReq req =
4222+
new TGetDatabaseReq(databasePathPattern, ALL_MATCH_SCOPE.serialize())
4223+
.setIsTableModel(true);
4224+
final TShowDatabaseResp resp = client.showDatabase(req);
4225+
if (resp.getStatus().getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
4226+
future.setException(new IoTDBException(resp.getStatus()));
4227+
return future;
4228+
}
4229+
4230+
final TDatabaseInfo databaseInfo =
4231+
resp.isSetDatabaseInfoMap() ? resp.getDatabaseInfoMap().get(database) : null;
4232+
if (databaseInfo == null) {
4233+
future.setException(
4234+
new IoTDBException(
4235+
String.format("Unknown database %s", database),
4236+
TSStatusCode.DATABASE_NOT_EXIST.getStatusCode()));
4237+
return future;
4238+
}
4239+
4240+
ShowCreateDatabaseTask.buildTsBlock(databaseInfo, future);
4241+
} catch (final IOException | ClientManagerException | TException e) {
4242+
future.setException(e);
4243+
}
4244+
return future;
4245+
}
4246+
41434247
@Override
41444248
public SettableFuture<ConfigTaskResult> showCluster(final ShowCluster showCluster) {
41454249
// As the implementation is identical, we'll simply translate to the

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/IConfigTaskExecutor.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,8 @@ SettableFuture<ConfigTaskResult> alterSchemaTemplate(
234234
SettableFuture<ConfigTaskResult> showPipes(
235235
ShowPipesStatement showPipesStatement, String userName);
236236

237+
SettableFuture<ConfigTaskResult> showCreatePipe(String pipeName, String userName);
238+
237239
SettableFuture<ConfigTaskResult> showSubscriptions(
238240
ShowSubscriptionsStatement showSubscriptionsStatement);
239241

@@ -333,6 +335,8 @@ SettableFuture<ConfigTaskResult> showThrottleQuota(
333335
SettableFuture<ConfigTaskResult> showDatabases(
334336
final ShowDB showDB, final Predicate<String> canSeenDB);
335337

338+
SettableFuture<ConfigTaskResult> showCreateDatabase(final String database);
339+
336340
SettableFuture<ConfigTaskResult> showCluster(ShowCluster showCluster);
337341

338342
SettableFuture<ConfigTaskResult> useDatabase(final Use useDB, final IClientSession clientSession);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.apache.iotdb.db.queryengine.plan.execution.config.metadata.relational;
21+
22+
import org.apache.iotdb.commons.conf.IoTDBConstant;
23+
import org.apache.iotdb.commons.schema.column.ColumnHeader;
24+
import org.apache.iotdb.commons.schema.column.ColumnHeaderConstant;
25+
import org.apache.iotdb.confignode.rpc.thrift.TDatabaseInfo;
26+
import org.apache.iotdb.db.queryengine.common.header.DatasetHeader;
27+
import org.apache.iotdb.db.queryengine.common.header.DatasetHeaderFactory;
28+
import org.apache.iotdb.db.queryengine.plan.execution.config.ConfigTaskResult;
29+
import org.apache.iotdb.db.queryengine.plan.execution.config.IConfigTask;
30+
import org.apache.iotdb.db.queryengine.plan.execution.config.executor.IConfigTaskExecutor;
31+
import org.apache.iotdb.rpc.TSStatusCode;
32+
33+
import com.google.common.util.concurrent.ListenableFuture;
34+
import com.google.common.util.concurrent.SettableFuture;
35+
import org.apache.tsfile.common.conf.TSFileConfig;
36+
import org.apache.tsfile.enums.TSDataType;
37+
import org.apache.tsfile.read.common.block.TsBlockBuilder;
38+
import org.apache.tsfile.utils.Binary;
39+
40+
import java.util.List;
41+
import java.util.stream.Collectors;
42+
43+
public class ShowCreateDatabaseTask implements IConfigTask {
44+
45+
private final String database;
46+
47+
public ShowCreateDatabaseTask(final String database) {
48+
this.database = database;
49+
}
50+
51+
@Override
52+
public ListenableFuture<ConfigTaskResult> execute(final IConfigTaskExecutor configTaskExecutor)
53+
throws InterruptedException {
54+
return configTaskExecutor.showCreateDatabase(database);
55+
}
56+
57+
public static void buildTsBlock(
58+
final TDatabaseInfo databaseInfo, final SettableFuture<ConfigTaskResult> future) {
59+
final List<TSDataType> outputDataTypes =
60+
ColumnHeaderConstant.showCreateDatabaseColumnHeaders.stream()
61+
.map(ColumnHeader::getColumnType)
62+
.collect(Collectors.toList());
63+
64+
final TsBlockBuilder builder = new TsBlockBuilder(outputDataTypes);
65+
builder.getTimeColumnBuilder().writeLong(0L);
66+
builder
67+
.getColumnBuilder(0)
68+
.writeBinary(new Binary(databaseInfo.getName(), TSFileConfig.STRING_CHARSET));
69+
builder
70+
.getColumnBuilder(1)
71+
.writeBinary(
72+
new Binary(getShowCreateDatabaseSQL(databaseInfo), TSFileConfig.STRING_CHARSET));
73+
builder.declarePosition();
74+
75+
final DatasetHeader datasetHeader = DatasetHeaderFactory.getShowCreateDatabaseColumnHeader();
76+
future.set(new ConfigTaskResult(TSStatusCode.SUCCESS_STATUS, builder.build(), datasetHeader));
77+
}
78+
79+
public static String getShowCreateDatabaseSQL(final TDatabaseInfo databaseInfo) {
80+
return new StringBuilder("CREATE DATABASE ")
81+
.append(ShowCreateTableTask.getIdentifier(databaseInfo.getName()))
82+
.append(" WITH (ttl=")
83+
.append(
84+
databaseInfo.getTTL() == Long.MAX_VALUE
85+
? ShowCreateTableTask.getString(IoTDBConstant.TTL_INFINITE)
86+
: databaseInfo.getTTL())
87+
.append(",time_partition_interval=")
88+
.append(databaseInfo.getTimePartitionInterval())
89+
.append(",schema_region_group_num=")
90+
.append(databaseInfo.getMinSchemaRegionNum())
91+
.append(",data_region_group_num=")
92+
.append(databaseInfo.getMinDataRegionNum())
93+
.append(")")
94+
.toString();
95+
}
96+
}

0 commit comments

Comments
 (0)