diff --git a/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBTableIT.java b/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBTableIT.java index 3ef1e8ecd113..2294f156509c 100644 --- a/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBTableIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBTableIT.java @@ -299,10 +299,15 @@ public void testManageTable() { assertEquals(tableNames.length, cnt); } + // Will not affect the manual "6600000" + statement.execute("alter database test2 set properties ttl=6600000"); + statement.execute("alter database test2 set properties ttl=DEFAULT"); + statement.execute("alter table table3 set properties ttl=1000000"); statement.execute("alter table table3 set properties ttl=DEFAULT"); - // The table3's ttl shall be also 3000000 + ttls = new String[] {"INF", "6600000"}; + // The table3's ttl shall be "INF" try (final ResultSet resultSet = statement.executeQuery("SHOW tables")) { int cnt = 0; ResultSetMetaData metaData = resultSet.getMetaData(); diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/schema/ClusterSchemaManager.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/schema/ClusterSchemaManager.java index afa3135df65e..76e0f1f4fe5c 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/schema/ClusterSchemaManager.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/schema/ClusterSchemaManager.java @@ -207,7 +207,7 @@ public TSStatus setDatabase( public TSStatus alterDatabase( final DatabaseSchemaPlan databaseSchemaPlan, final boolean isGeneratedByPipe) { TSStatus result; - TDatabaseSchema databaseSchema = databaseSchemaPlan.getSchema(); + final TDatabaseSchema databaseSchema = databaseSchemaPlan.getSchema(); if (!isDatabaseExist(databaseSchema.getName())) { // Reject if Database doesn't exist @@ -219,7 +219,7 @@ public TSStatus alterDatabase( if (databaseSchema.isSetMinSchemaRegionGroupNum()) { // Validate alter SchemaRegionGroupNum - int minSchemaRegionGroupNum = + final int minSchemaRegionGroupNum = getMinRegionGroupNum(databaseSchema.getName(), TConsensusGroupType.SchemaRegion); if (databaseSchema.getMinSchemaRegionGroupNum() <= minSchemaRegionGroupNum) { result = new TSStatus(TSStatusCode.DATABASE_CONFIG_ERROR.getStatusCode()); diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ClusterSchemaInfo.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ClusterSchemaInfo.java index 2f6c93977ffb..6256458beb34 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ClusterSchemaInfo.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ClusterSchemaInfo.java @@ -246,10 +246,19 @@ public TSStatus alterDatabase(final DatabaseSchemaPlan plan) { currentSchema.getMaxDataRegionGroupNum()); } + if (alterSchema.isSetTTL()) { + currentSchema.setTTL(alterSchema.getTTL()); + LOGGER.info( + "[SetTTL] The ttl of Database: {} is adjusted to: {}", + currentSchema.getName(), + currentSchema.getTTL()); + } + mTree .getDatabaseNodeByDatabasePath(partialPathName) .getAsMNode() .setDatabaseSchema(currentSchema); + result.setCode(TSStatusCode.SUCCESS_STATUS.getStatusCode()); } catch (final MetadataException e) { LOGGER.error(ERROR_NAME, e); diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTree.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTree.java index c64b6c10906b..5041be35a5e0 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTree.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTree.java @@ -827,7 +827,8 @@ public void setTableProperties( if (Objects.nonNull(v)) { table.addProp(k, v); } else if (k.equals(TsTable.TTL_PROPERTY) - && databaseNode.getDatabaseSchema().isSetTTL()) { + && databaseNode.getDatabaseSchema().isSetTTL() + && databaseNode.getDatabaseSchema().getTTL() != Long.MAX_VALUE) { table.addProp(k, String.valueOf(databaseNode.getDatabaseSchema().getTTL())); } else { table.removeProp(k); diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/DeleteDatabaseProcedure.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/DeleteDatabaseProcedure.java index 21892d6e6296..6c8a679b9f3b 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/DeleteDatabaseProcedure.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/DeleteDatabaseProcedure.java @@ -65,11 +65,12 @@ public class DeleteDatabaseProcedure private TDatabaseSchema deleteDatabaseSchema; - public DeleteDatabaseProcedure(boolean isGeneratedByPipe) { + public DeleteDatabaseProcedure(final boolean isGeneratedByPipe) { super(isGeneratedByPipe); } - public DeleteDatabaseProcedure(TDatabaseSchema deleteDatabaseSchema, boolean isGeneratedByPipe) { + public DeleteDatabaseProcedure( + final TDatabaseSchema deleteDatabaseSchema, final boolean isGeneratedByPipe) { super(isGeneratedByPipe); this.deleteDatabaseSchema = deleteDatabaseSchema; } @@ -78,12 +79,13 @@ public TDatabaseSchema getDeleteDatabaseSchema() { return deleteDatabaseSchema; } - public void setDeleteDatabaseSchema(TDatabaseSchema deleteDatabaseSchema) { + public void setDeleteDatabaseSchema(final TDatabaseSchema deleteDatabaseSchema) { this.deleteDatabaseSchema = deleteDatabaseSchema; } @Override - protected Flow executeFromState(ConfigNodeProcedureEnv env, DeleteStorageGroupState state) + protected Flow executeFromState( + final ConfigNodeProcedureEnv env, final DeleteStorageGroupState state) throws ProcedureSuspendedException, ProcedureYieldException, InterruptedException { if (deleteDatabaseSchema == null) { return Flow.NO_MORE_STATE; @@ -113,11 +115,11 @@ protected Flow executeFromState(ConfigNodeProcedureEnv env, DeleteStorageGroupSt deleteDatabaseSchema.getName()); // Submit RegionDeleteTasks - OfferRegionMaintainTasksPlan dataRegionDeleteTaskOfferPlan = + final OfferRegionMaintainTasksPlan dataRegionDeleteTaskOfferPlan = new OfferRegionMaintainTasksPlan(); - List regionReplicaSets = + final List regionReplicaSets = env.getAllReplicaSets(deleteDatabaseSchema.getName()); - List schemaRegionReplicaSets = new ArrayList<>(); + final List schemaRegionReplicaSets = new ArrayList<>(); regionReplicaSets.forEach( regionReplicaSet -> { // Clear heartbeat cache along the way @@ -147,12 +149,12 @@ protected Flow executeFromState(ConfigNodeProcedureEnv env, DeleteStorageGroupSt } // try sync delete schemaengine region - DataNodeAsyncRequestContext asyncClientHandler = + final DataNodeAsyncRequestContext asyncClientHandler = new DataNodeAsyncRequestContext<>(CnToDnAsyncRequestType.DELETE_REGION); - Map schemaRegionDeleteTaskMap = new HashMap<>(); + final Map schemaRegionDeleteTaskMap = new HashMap<>(); int requestIndex = 0; - for (TRegionReplicaSet schemaRegionReplicaSet : schemaRegionReplicaSets) { - for (TDataNodeLocation dataNodeLocation : + for (final TRegionReplicaSet schemaRegionReplicaSet : schemaRegionReplicaSets) { + for (final TDataNodeLocation dataNodeLocation : schemaRegionReplicaSet.getDataNodeLocations()) { asyncClientHandler.putRequest(requestIndex, schemaRegionReplicaSet.getRegionId()); asyncClientHandler.putNodeLocation(requestIndex, dataNodeLocation); @@ -165,7 +167,7 @@ protected Flow executeFromState(ConfigNodeProcedureEnv env, DeleteStorageGroupSt if (!schemaRegionDeleteTaskMap.isEmpty()) { CnToDnInternalServiceAsyncRequestManager.getInstance() .sendAsyncRequestWithRetry(asyncClientHandler); - for (Map.Entry entry : + for (final Map.Entry entry : asyncClientHandler.getResponseMap().entrySet()) { if (entry.getValue().getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) { LOG.info( @@ -183,7 +185,7 @@ protected Flow executeFromState(ConfigNodeProcedureEnv env, DeleteStorageGroupSt if (!schemaRegionDeleteTaskMap.isEmpty()) { // submit async schemaengine region delete task for failed sync execution - OfferRegionMaintainTasksPlan schemaRegionDeleteTaskOfferPlan = + final OfferRegionMaintainTasksPlan schemaRegionDeleteTaskOfferPlan = new OfferRegionMaintainTasksPlan(); schemaRegionDeleteTaskMap .values() @@ -215,7 +217,7 @@ protected Flow executeFromState(ConfigNodeProcedureEnv env, DeleteStorageGroupSt new ProcedureException("[DeleteDatabaseProcedure] Delete DatabaseSchema failed")); } } - } catch (ConsensusException | TException | IOException e) { + } catch (final ConsensusException | TException | IOException e) { if (isRollbackSupported(state)) { setFailure( new ProcedureException( @@ -238,7 +240,8 @@ protected Flow executeFromState(ConfigNodeProcedureEnv env, DeleteStorageGroupSt } @Override - protected void rollbackState(ConfigNodeProcedureEnv env, DeleteStorageGroupState state) + protected void rollbackState( + final ConfigNodeProcedureEnv env, final DeleteStorageGroupState state) throws IOException, InterruptedException { switch (state) { case PRE_DELETE_DATABASE: @@ -254,7 +257,7 @@ protected void rollbackState(ConfigNodeProcedureEnv env, DeleteStorageGroupState } @Override - protected boolean isRollbackSupported(DeleteStorageGroupState state) { + protected boolean isRollbackSupported(final DeleteStorageGroupState state) { switch (state) { case PRE_DELETE_DATABASE: case INVALIDATE_CACHE: @@ -265,12 +268,12 @@ protected boolean isRollbackSupported(DeleteStorageGroupState state) { } @Override - protected DeleteStorageGroupState getState(int stateId) { + protected DeleteStorageGroupState getState(final int stateId) { return DeleteStorageGroupState.values()[stateId]; } @Override - protected int getStateId(DeleteStorageGroupState deleteStorageGroupState) { + protected int getStateId(final DeleteStorageGroupState deleteStorageGroupState) { return deleteStorageGroupState.ordinal(); } @@ -284,7 +287,7 @@ public String getDatabase() { } @Override - public void serialize(DataOutputStream stream) throws IOException { + public void serialize(final DataOutputStream stream) throws IOException { stream.writeShort( isGeneratedByPipe ? ProcedureType.PIPE_ENRICHED_DELETE_DATABASE_PROCEDURE.getTypeCode() @@ -294,17 +297,17 @@ public void serialize(DataOutputStream stream) throws IOException { } @Override - public void deserialize(ByteBuffer byteBuffer) { + public void deserialize(final ByteBuffer byteBuffer) { super.deserialize(byteBuffer); try { deleteDatabaseSchema = ThriftConfigNodeSerDeUtils.deserializeTDatabaseSchema(byteBuffer); - } catch (ThriftSerDeException e) { - LOG.error("Error in deserialize DeleteStorageGroupProcedure", e); + } catch (final ThriftSerDeException e) { + LOG.error("Error in deserialize DeleteDatabaseProcedure", e); } } @Override - public boolean equals(Object that) { + public boolean equals(final Object that) { if (that instanceof DeleteDatabaseProcedure) { DeleteDatabaseProcedure thatProc = (DeleteDatabaseProcedure) that; return thatProc.getProcId() == this.getProcId() diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/SchemaUtils.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/SchemaUtils.java index ebf51084aa37..3b9b5766b43d 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/SchemaUtils.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/SchemaUtils.java @@ -225,7 +225,7 @@ protected void onAllReplicasetFailure( public static Map preReleaseTable( final String database, final TsTable table, final ConfigManager configManager) { final TUpdateTableReq req = new TUpdateTableReq(); - req.setType(TsTableInternalRPCType.PRE_CREATE_OR_ADD_COLUMN.getOperationType()); + req.setType(TsTableInternalRPCType.PRE_UPDATE_TABLE.getOperationType()); req.setTableInfo(TsTableInternalRPCUtil.serializeSingleTsTableWithDatabase(database, table)); final Map dataNodeLocationMap = @@ -242,7 +242,7 @@ public static Map preReleaseTable( public static Map commitReleaseTable( final String database, final String tableName, final ConfigManager configManager) { final TUpdateTableReq req = new TUpdateTableReq(); - req.setType(TsTableInternalRPCType.COMMIT_CREATE_OR_ADD_COLUMN.getOperationType()); + req.setType(TsTableInternalRPCType.COMMIT_UPDATE_TABLE.getOperationType()); final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); try { ReadWriteIOUtils.write(database, outputStream); @@ -266,7 +266,7 @@ public static Map commitReleaseTable( public static Map rollbackPreRelease( final String database, final String tableName, final ConfigManager configManager) { final TUpdateTableReq req = new TUpdateTableReq(); - req.setType(TsTableInternalRPCType.ROLLBACK_CREATE_OR_ADD_COLUMN.getOperationType()); + req.setType(TsTableInternalRPCType.ROLLBACK_UPDATE_TABLE.getOperationType()); final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); try { ReadWriteIOUtils.write(database, outputStream); diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/table/CreateTableProcedure.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/table/CreateTableProcedure.java index dedd9349d3ae..26a71130e39a 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/table/CreateTableProcedure.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/table/CreateTableProcedure.java @@ -145,7 +145,9 @@ private void checkTableExistence(final ConfigNodeProcedureEnv env) { } else { final TDatabaseSchema schema = env.getConfigManager().getClusterSchemaManager().getDatabaseSchemaByName(database); - if (schema.isSetTTL() && !table.getPropValue(TsTable.TTL_PROPERTY).isPresent()) { + if (!table.getPropValue(TsTable.TTL_PROPERTY).isPresent() + && schema.isSetTTL() + && schema.getTTL() != Long.MAX_VALUE) { table.addProp(TsTable.TTL_PROPERTY, String.valueOf(schema.getTTL())); } setNextState(CreateTableState.PRE_CREATE); diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/state/schema/AlterDatabaseState.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/state/schema/AlterDatabaseState.java new file mode 100644 index 000000000000..ca5a50c22654 --- /dev/null +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/state/schema/AlterDatabaseState.java @@ -0,0 +1,27 @@ +/* + * 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.iotdb.confignode.procedure.state.schema; + +public enum AlterDatabaseState { + CHECK_ALTERED_TABLES, + PRE_RELEASE, + ALTER_DATABASE, + COMMIT_RELEASE +} diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/store/ProcedureFactory.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/store/ProcedureFactory.java index 7cb7f1ebeaeb..42ef4a1b8069 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/store/ProcedureFactory.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/store/ProcedureFactory.java @@ -320,7 +320,7 @@ public Procedure create(ByteBuffer buffer) throws IOException { return procedure; } - public static ProcedureType getProcedureType(Procedure procedure) { + public static ProcedureType getProcedureType(final Procedure procedure) { if (procedure instanceof DeleteDatabaseProcedure) { return ProcedureType.DELETE_DATABASE_PROCEDURE; } else if (procedure instanceof AddConfigNodeProcedure) { diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java index a524150d0d76..ce360da47cfc 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java @@ -481,7 +481,7 @@ public TSStatus alterDatabase(final TDatabaseSchema databaseSchema) { TSStatus errorResp = null; // TODO: Support alter the following fields - if (databaseSchema.isSetTTL()) { + if (databaseSchema.isSetTTL() && !databaseSchema.isIsTableModel()) { errorResp = new TSStatus(TSStatusCode.DATABASE_CONFIG_ERROR.getStatusCode()) .setMessage("Failed to alter database. Doesn't support ALTER TTL yet."); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/thrift/impl/DataNodeInternalRPCServiceImpl.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/thrift/impl/DataNodeInternalRPCServiceImpl.java index 1b801d38b108..b1d2806cdc2a 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/thrift/impl/DataNodeInternalRPCServiceImpl.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/thrift/impl/DataNodeInternalRPCServiceImpl.java @@ -1533,8 +1533,10 @@ public TFetchFragmentInstanceStatisticsResp fetchFragmentInstanceStatistics( @Override public TSStatus updateTable(final TUpdateTableReq req) { + final String database; + final int size; switch (TsTableInternalRPCType.getType(req.type)) { - case PRE_CREATE_OR_ADD_COLUMN: + case PRE_UPDATE_TABLE: DataNodeSchemaLockManager.getInstance().takeWriteLock(SchemaLockType.TIMESERIES_VS_TABLE); try { Pair pair = @@ -1545,13 +1547,13 @@ public TSStatus updateTable(final TUpdateTableReq req) { .releaseWriteLock(SchemaLockType.TIMESERIES_VS_TABLE); } break; - case ROLLBACK_CREATE_OR_ADD_COLUMN: + case ROLLBACK_UPDATE_TABLE: DataNodeTableCache.getInstance() .rollbackUpdateTable( ReadWriteIOUtils.readString(req.tableInfo), ReadWriteIOUtils.readString(req.tableInfo)); break; - case COMMIT_CREATE_OR_ADD_COLUMN: + case COMMIT_UPDATE_TABLE: DataNodeTableCache.getInstance() .commitUpdateTable( ReadWriteIOUtils.readString(req.tableInfo), diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/Coordinator.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/Coordinator.java index c3896cd60fd6..ded116bcd670 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/Coordinator.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/Coordinator.java @@ -56,6 +56,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.security.AccessControl; import org.apache.iotdb.db.queryengine.plan.relational.security.AllowAllAccessControl; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AddColumn; +import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AlterDB; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.ClearCache; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.CreateDB; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.CreateTable; @@ -369,6 +370,7 @@ private IQueryExecution createQueryExecutionForTableModel( if (statement instanceof DropDB || statement instanceof ShowDB || statement instanceof CreateDB + || statement instanceof AlterDB || statement instanceof Use || statement instanceof CreateTable || statement instanceof DescribeTable diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java index 1fd3b186eea1..915dd49ffd60 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java @@ -37,6 +37,7 @@ import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.ShowPipePluginsTask; import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.ShowRegionTask; import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.ShowVariablesTask; +import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.relational.AlterDBTask; import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.relational.AlterTableAddColumnTask; import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.relational.AlterTableDropColumnTask; import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.relational.AlterTableRenameColumnTask; @@ -81,6 +82,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.metadata.fetcher.TableHeaderSchemaValidator; import org.apache.iotdb.db.queryengine.plan.relational.security.AccessControl; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AddColumn; +import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AlterDB; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AlterPipe; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AstVisitor; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.ClearCache; @@ -91,6 +93,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.CreateTable; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.CreateTopic; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DataType; +import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DatabaseStatement; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DeleteDevice; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DescribeTable; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DropColumn; @@ -134,6 +137,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Use; import org.apache.iotdb.db.queryengine.plan.relational.sql.rewrite.StatementRewrite; import org.apache.iotdb.db.queryengine.plan.relational.type.TypeNotFoundException; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.DatabaseSchemaStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.ShowClusterStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.ShowRegionStatement; import org.apache.iotdb.db.queryengine.plan.statement.sys.FlushStatement; @@ -194,6 +198,16 @@ protected IConfigTask visitNode(final Node node, final MPPQueryContext context) @Override protected IConfigTask visitCreateDB(final CreateDB node, final MPPQueryContext context) { + return visitDatabaseStatement(node, context); + } + + @Override + protected IConfigTask visitAlterDB(final AlterDB node, final MPPQueryContext context) { + return visitDatabaseStatement(node, context); + } + + private IConfigTask visitDatabaseStatement( + final DatabaseStatement node, final MPPQueryContext context) { context.setQueryType(QueryType.WRITE); final TDatabaseSchema schema = new TDatabaseSchema(); @@ -210,11 +224,15 @@ protected IConfigTask visitCreateDB(final CreateDB node, final MPPQueryContext c final String key = property.getName().getValue().toLowerCase(Locale.ENGLISH); if (property.isSetToDefault()) { switch (key) { - case TTL_KEY: case TIME_PARTITION_INTERVAL_KEY: case SCHEMA_REGION_GROUP_NUM_KEY: case DATA_REGION_GROUP_NUM_KEY: break; + case TTL_KEY: + if (node.getType() == DatabaseSchemaStatement.DatabaseSchemaStatementType.ALTER) { + schema.setTTL(Long.MAX_VALUE); + } + break; default: throw new SemanticException("Unsupported database property key: " + key); } @@ -231,6 +249,9 @@ protected IConfigTask visitCreateDB(final CreateDB node, final MPPQueryContext c throw new SemanticException( "ttl value must be 'INF' or a long literal, but now is: " + value); } + if (node.getType() == DatabaseSchemaStatement.DatabaseSchemaStatementType.ALTER) { + schema.setTTL(Long.MAX_VALUE); + } break; } schema.setTTL(parseLongFromLiteral(value, TTL_KEY)); @@ -249,7 +270,9 @@ protected IConfigTask visitCreateDB(final CreateDB node, final MPPQueryContext c throw new SemanticException("Unsupported database property key: " + key); } } - return new CreateDBTask(schema, node.isSetIfNotExists()); + return node.getType() == DatabaseSchemaStatement.DatabaseSchemaStatementType.CREATE + ? new CreateDBTask(schema, node.exists()) + : new AlterDBTask(schema, node.exists()); } @Override diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java index 4073c1b1b84b..092a9fec9ee1 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java @@ -3127,7 +3127,7 @@ public SettableFuture dropDatabase(final DropDB dropDB) { @Override public SettableFuture createDatabase( - final TDatabaseSchema databaseSchema, final boolean ifNotExists) { + final TDatabaseSchema databaseSchema, final boolean ifExists) { final SettableFuture future = SettableFuture.create(); // Construct request using statement @@ -3139,7 +3139,7 @@ public SettableFuture createDatabase( if (TSStatusCode.SUCCESS_STATUS.getStatusCode() == tsStatus.getCode()) { future.set(new ConfigTaskResult(TSStatusCode.SUCCESS_STATUS)); } else if (TSStatusCode.DATABASE_ALREADY_EXISTS.getStatusCode() == tsStatus.getCode()) { - if (ifNotExists) { + if (ifExists) { future.set(new ConfigTaskResult(TSStatusCode.SUCCESS_STATUS)); } else { future.setException( @@ -3157,6 +3157,37 @@ public SettableFuture createDatabase( return future; } + @Override + public SettableFuture alterDatabase( + final TDatabaseSchema databaseSchema, final boolean ifNotExists) { + final SettableFuture future = SettableFuture.create(); + + // Construct request using statement + try (final ConfigNodeClient configNodeClient = + CONFIG_NODE_CLIENT_MANAGER.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) { + // Send request to some API server + final TSStatus tsStatus = configNodeClient.alterDatabase(databaseSchema); + + if (TSStatusCode.SUCCESS_STATUS.getStatusCode() == tsStatus.getCode()) { + future.set(new ConfigTaskResult(TSStatusCode.SUCCESS_STATUS)); + } else if (TSStatusCode.DATABASE_NOT_EXIST.getStatusCode() == tsStatus.getCode()) { + if (ifNotExists) { + future.set(new ConfigTaskResult(TSStatusCode.SUCCESS_STATUS)); + } else { + future.setException( + new IoTDBException( + String.format("Database %s doesn't exist", databaseSchema.getName().substring(5)), + TSStatusCode.DATABASE_NOT_EXIST.getStatusCode())); + } + } else { + future.setException(new IoTDBException(tsStatus.message, tsStatus.code)); + } + } catch (final ClientManagerException | TException e) { + future.setException(e); + } + return future; + } + @Override public SettableFuture createTable( final TsTable table, final String database, final boolean ifNotExists) { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/IConfigTaskExecutor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/IConfigTaskExecutor.java index 4180abd3b092..ad81c6469ee1 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/IConfigTaskExecutor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/IConfigTaskExecutor.java @@ -295,6 +295,9 @@ SettableFuture showDatabases( SettableFuture createDatabase( final TDatabaseSchema databaseSchema, final boolean ifNotExists); + SettableFuture alterDatabase( + final TDatabaseSchema databaseSchema, final boolean ifNotExists); + SettableFuture createTable( final TsTable table, final String database, final boolean ifNotExists); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/AbstractDatabaseTask.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/AbstractDatabaseTask.java new file mode 100644 index 000000000000..df280c8759de --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/AbstractDatabaseTask.java @@ -0,0 +1,48 @@ +/* + * 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.iotdb.db.queryengine.plan.execution.config.metadata.relational; + +import org.apache.iotdb.confignode.rpc.thrift.TDatabaseSchema; +import org.apache.iotdb.db.queryengine.plan.execution.config.IConfigTask; + +public abstract class AbstractDatabaseTask implements IConfigTask { + + /////////////////////////////// Allowed properties /////////////////////////////// + public static final String TTL_KEY = "ttl"; + public static final String TIME_PARTITION_INTERVAL_KEY = "time_partition_interval"; + public static final String SCHEMA_REGION_GROUP_NUM_KEY = "schema_region_group_num"; + public static final String DATA_REGION_GROUP_NUM_KEY = "data_region_group_num"; + + // Deprecated + public static final String SCHEMA_REPLICATION_FACTOR_KEY = "schema_replication_factor"; + public static final String DATA_REPLICATION_FACTOR_KEY = "data_replication_factor"; + + /////////////////////////////// Fields /////////////////////////////// + + protected final TDatabaseSchema schema; + // In CreateDB: If not exists + // In AlterDB: If exists + protected final boolean exists; + + protected AbstractDatabaseTask(final TDatabaseSchema schema, final boolean exists) { + this.schema = schema; + this.exists = exists; + } +} diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/AlterDBTask.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/AlterDBTask.java new file mode 100644 index 000000000000..377d982482fd --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/AlterDBTask.java @@ -0,0 +1,38 @@ +/* + * 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.iotdb.db.queryengine.plan.execution.config.metadata.relational; + +import org.apache.iotdb.confignode.rpc.thrift.TDatabaseSchema; +import org.apache.iotdb.db.queryengine.plan.execution.config.ConfigTaskResult; +import org.apache.iotdb.db.queryengine.plan.execution.config.executor.IConfigTaskExecutor; + +import com.google.common.util.concurrent.ListenableFuture; + +public class AlterDBTask extends AbstractDatabaseTask { + public AlterDBTask(final TDatabaseSchema schema, final boolean exists) { + super(schema, exists); + } + + @Override + public ListenableFuture execute(final IConfigTaskExecutor configTaskExecutor) + throws InterruptedException { + return configTaskExecutor.alterDatabase(schema, exists); + } +} diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/CreateDBTask.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/CreateDBTask.java index a4ec37d42fa6..5728c4ce52c7 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/CreateDBTask.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/CreateDBTask.java @@ -21,36 +21,19 @@ import org.apache.iotdb.confignode.rpc.thrift.TDatabaseSchema; import org.apache.iotdb.db.queryengine.plan.execution.config.ConfigTaskResult; -import org.apache.iotdb.db.queryengine.plan.execution.config.IConfigTask; import org.apache.iotdb.db.queryengine.plan.execution.config.executor.IConfigTaskExecutor; import com.google.common.util.concurrent.ListenableFuture; -public class CreateDBTask implements IConfigTask { +public class CreateDBTask extends AbstractDatabaseTask { - /////////////////////////////// Allowed properties /////////////////////////////// - public static final String TTL_KEY = "ttl"; - public static final String TIME_PARTITION_INTERVAL_KEY = "time_partition_interval"; - public static final String SCHEMA_REGION_GROUP_NUM_KEY = "schema_region_group_num"; - public static final String DATA_REGION_GROUP_NUM_KEY = "data_region_group_num"; - - // Deprecated - public static final String SCHEMA_REPLICATION_FACTOR_KEY = "schema_replication_factor"; - public static final String DATA_REPLICATION_FACTOR_KEY = "data_replication_factor"; - - /////////////////////////////// Fields /////////////////////////////// - - private final TDatabaseSchema schema; - private final boolean ifNotExists; - - public CreateDBTask(final TDatabaseSchema schema, final boolean ifNotExists) { - this.schema = schema; - this.ifNotExists = ifNotExists; + public CreateDBTask(final TDatabaseSchema schema, final boolean exists) { + super(schema, exists); } @Override public ListenableFuture execute(final IConfigTaskExecutor configTaskExecutor) throws InterruptedException { - return configTaskExecutor.createDatabase(schema, ifNotExists); + return configTaskExecutor.createDatabase(schema, exists); } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java index c29f337f7253..c8838de59423 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java @@ -48,6 +48,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AliasedRelation; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AllColumns; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AllRows; +import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AlterDB; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AlterPipe; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AstVisitor; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.ComparisonExpression; @@ -334,6 +335,11 @@ protected Scope visitCreateDB(CreateDB node, Optional context) { throw new SemanticException("Create Database statement is not supported yet."); } + @Override + protected Scope visitAlterDB(AlterDB node, Optional context) { + throw new SemanticException("Alter Database statement is not supported yet."); + } + @Override protected Scope visitDropDB(DropDB node, Optional context) { throw new SemanticException("Drop Database statement is not supported yet."); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AlterDB.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AlterDB.java new file mode 100644 index 000000000000..4a5e6a8d1229 --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AlterDB.java @@ -0,0 +1,56 @@ +/* + * 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.iotdb.db.queryengine.plan.relational.sql.ast; + +import org.apache.iotdb.db.queryengine.plan.statement.metadata.DatabaseSchemaStatement; + +import java.util.List; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static java.util.Objects.requireNonNull; + +public class AlterDB extends DatabaseStatement { + public AlterDB( + final NodeLocation location, + final boolean exists, + final String dbName, + final List properties) { + super(requireNonNull(location, "location is null"), exists, dbName, properties); + } + + @Override + public DatabaseSchemaStatement.DatabaseSchemaStatementType getType() { + return DatabaseSchemaStatement.DatabaseSchemaStatementType.ALTER; + } + + @Override + public R accept(final AstVisitor visitor, final C context) { + return visitor.visitAlterDB(this, context); + } + + @Override + public String toString() { + return toStringHelper(this) + .add("dbName", dbName) + .add("ifExists", exists) + .add("properties", properties) + .toString(); + } +} diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AstVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AstVisitor.java index 8cacc1375a14..43bc9223b114 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AstVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AstVisitor.java @@ -313,6 +313,10 @@ protected R visitCreateDB(final CreateDB node, final C context) { return visitStatement(node, context); } + protected R visitAlterDB(final AlterDB node, final C context) { + return visitStatement(node, context); + } + protected R visitDropDB(final DropDB node, final C context) { return visitStatement(node, context); } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/CreateDB.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/CreateDB.java index c230b90e9622..9f493b16d481 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/CreateDB.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/CreateDB.java @@ -19,63 +19,26 @@ package org.apache.iotdb.db.queryengine.plan.relational.sql.ast; -import com.google.common.collect.ImmutableList; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.DatabaseSchemaStatement; import java.util.List; -import java.util.Locale; -import java.util.Objects; import static com.google.common.base.MoreObjects.toStringHelper; import static java.util.Objects.requireNonNull; -public class CreateDB extends Statement { - - private final boolean ifNotExists; - private final String dbName; - private final List properties; - - public CreateDB(final boolean ifNotExists, final String dbName) { - super(null); - this.ifNotExists = ifNotExists; - this.dbName = requireNonNull(dbName, "dbName is null").toLowerCase(Locale.ENGLISH); - this.properties = null; - } - - public CreateDB(final NodeLocation location, final boolean ifNotExists, final String dbName) { - super(requireNonNull(location, "location is null")); - this.ifNotExists = ifNotExists; - this.dbName = requireNonNull(dbName, "dbName is null").toLowerCase(Locale.ENGLISH); - this.properties = null; - } - - public CreateDB(final boolean ifNotExists, final String dbName, final List properties) { - super(null); - this.ifNotExists = ifNotExists; - this.dbName = requireNonNull(dbName, "dbName is null").toLowerCase(Locale.ENGLISH); - this.properties = ImmutableList.copyOf(requireNonNull(properties, "properties is null")); - } +public class CreateDB extends DatabaseStatement { public CreateDB( final NodeLocation location, - final boolean ifNotExists, + final boolean exists, final String dbName, final List properties) { - super(requireNonNull(location, "location is null")); - this.ifNotExists = ifNotExists; - this.dbName = requireNonNull(dbName, "dbName is null").toLowerCase(Locale.ENGLISH); - this.properties = ImmutableList.copyOf(requireNonNull(properties, "properties is null")); - } - - public String getDbName() { - return dbName; - } - - public boolean isSetIfNotExists() { - return ifNotExists; + super(requireNonNull(location, "location is null"), exists, dbName, properties); } - public List getProperties() { - return properties; + @Override + public DatabaseSchemaStatement.DatabaseSchemaStatementType getType() { + return DatabaseSchemaStatement.DatabaseSchemaStatementType.CREATE; } @Override @@ -83,35 +46,11 @@ public R accept(final AstVisitor visitor, final C context) { return visitor.visitCreateDB(this, context); } - @Override - public List getChildren() { - return ImmutableList.copyOf(properties); - } - - @Override - public int hashCode() { - return Objects.hash(dbName, ifNotExists, properties); - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - final CreateDB o = (CreateDB) obj; - return Objects.equals(dbName, o.dbName) - && Objects.equals(ifNotExists, o.ifNotExists) - && Objects.equals(properties, o.properties); - } - @Override public String toString() { return toStringHelper(this) .add("dbName", dbName) - .add("ifNotExists", ifNotExists) + .add("ifNotExists", exists) .add("properties", properties) .toString(); } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/DatabaseStatement.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/DatabaseStatement.java new file mode 100644 index 000000000000..54ae7542c6f0 --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/DatabaseStatement.java @@ -0,0 +1,88 @@ +/* + * 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.iotdb.db.queryengine.plan.relational.sql.ast; + +import org.apache.iotdb.db.queryengine.plan.statement.metadata.DatabaseSchemaStatement; + +import com.google.common.collect.ImmutableList; + +import java.util.List; +import java.util.Locale; +import java.util.Objects; + +import static java.util.Objects.requireNonNull; + +public abstract class DatabaseStatement extends Statement { + + // In CreateDB: If not exists + // In AlterDB: If exists + protected final boolean exists; + protected final String dbName; + protected final List properties; + + protected DatabaseStatement( + final NodeLocation location, + final boolean exists, + final String dbName, + final List properties) { + super(requireNonNull(location, "location is null")); + this.exists = exists; + this.dbName = requireNonNull(dbName, "dbName is null").toLowerCase(Locale.ENGLISH); + this.properties = ImmutableList.copyOf(requireNonNull(properties, "properties is null")); + } + + public String getDbName() { + return dbName; + } + + public boolean exists() { + return exists; + } + + public List getProperties() { + return properties; + } + + public abstract DatabaseSchemaStatement.DatabaseSchemaStatementType getType(); + + @Override + public List getChildren() { + return ImmutableList.copyOf(properties); + } + + @Override + public int hashCode() { + return Objects.hash(dbName, exists, properties); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if ((obj == null) || (getClass() != obj.getClass())) { + return false; + } + final CreateDB o = (CreateDB) obj; + return Objects.equals(dbName, o.dbName) + && Objects.equals(exists, o.exists) + && Objects.equals(properties, o.properties); + } +} diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/DefaultTraversalVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/DefaultTraversalVisitor.java index 6a5168937f7e..cf5590d2ce4a 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/DefaultTraversalVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/DefaultTraversalVisitor.java @@ -393,6 +393,15 @@ protected Void visitCreateDB(CreateDB node, C context) { return null; } + @Override + protected Void visitAlterDB(AlterDB node, C context) { + for (Property property : node.getProperties()) { + process(property, context); + } + + return null; + } + @Override protected Void visitCreateTable(final CreateTable node, final C context) { for (final Property property : node.getProperties()) { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java index ef6036f827be..a3bbd8349a5d 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java @@ -36,6 +36,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AliasedRelation; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AllColumns; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AllRows; +import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AlterDB; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AlterPipe; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.ArithmeticBinaryExpression; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.ArithmeticUnaryExpression; @@ -290,7 +291,7 @@ public Node visitShowDatabasesStatement( } @Override - public Node visitCreateDbStatement(RelationalSqlParser.CreateDbStatementContext ctx) { + public Node visitCreateDbStatement(final RelationalSqlParser.CreateDbStatementContext ctx) { List properties = ImmutableList.of(); if (ctx.properties() != null) { properties = visit(ctx.properties().propertyAssignments().property(), Property.class); @@ -304,7 +305,21 @@ public Node visitCreateDbStatement(RelationalSqlParser.CreateDbStatementContext } @Override - public Node visitDropDbStatement(RelationalSqlParser.DropDbStatementContext ctx) { + public Node visitAlterDbStatement(final RelationalSqlParser.AlterDbStatementContext ctx) { + List properties = ImmutableList.of(); + if (ctx.propertyAssignments() != null) { + properties = visit(ctx.propertyAssignments().property(), Property.class); + } + + return new AlterDB( + getLocation(ctx), + ctx.EXISTS() != null, + ((Identifier) visit(ctx.database)).getValue(), + properties); + } + + @Override + public Node visitDropDbStatement(final RelationalSqlParser.DropDbStatementContext ctx) { return new DropDB( getLocation(ctx), lowerIdentifier((Identifier) visit(ctx.database)), ctx.EXISTS() != null); } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/util/SqlFormatter.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/util/SqlFormatter.java index 7c0fefc8c6af..98c5a048809a 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/util/SqlFormatter.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/util/SqlFormatter.java @@ -22,6 +22,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AddColumn; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AliasedRelation; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AllColumns; +import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AlterDB; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AlterPipe; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AstVisitor; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.ColumnDefinition; @@ -584,7 +585,7 @@ protected Void visitShowCurrentTimestamp(ShowCurrentTimestamp node, Integer cont } @Override - protected Void visitDelete(Delete node, Integer indent) { + protected Void visitDelete(final Delete node, final Integer indent) { builder.append("DELETE FROM ").append(formatName(node.getTable().getName())); node.getWhere().ifPresent(where -> builder.append(" WHERE ").append(formatExpression(where))); @@ -593,9 +594,9 @@ protected Void visitDelete(Delete node, Integer indent) { } @Override - protected Void visitCreateDB(CreateDB node, Integer indent) { + protected Void visitCreateDB(final CreateDB node, final Integer indent) { builder.append("CREATE DATABASE "); - if (node.isSetIfNotExists()) { + if (node.exists()) { builder.append("IF NOT EXISTS "); } builder.append(node.getDbName()).append(" "); @@ -606,7 +607,20 @@ protected Void visitCreateDB(CreateDB node, Integer indent) { } @Override - protected Void visitDropDB(DropDB node, Integer indent) { + protected Void visitAlterDB(final AlterDB node, final Integer indent) { + builder.append("ALTER DATABASE "); + if (node.exists()) { + builder.append("IF EXISTS "); + } + builder.append(node.getDbName()).append(" "); + + builder.append(formatPropertiesMultiLine(node.getProperties())); + + return null; + } + + @Override + protected Void visitDropDB(final DropDB node, final Integer indent) { builder.append("DROP DATABASE "); if (node.isExists()) { builder.append("IF EXISTS "); diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TsTableInternalRPCType.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TsTableInternalRPCType.java index e76160e7f992..37ffdf1cfef9 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TsTableInternalRPCType.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TsTableInternalRPCType.java @@ -26,13 +26,13 @@ import java.nio.ByteBuffer; public enum TsTableInternalRPCType { - PRE_CREATE_OR_ADD_COLUMN((byte) 0), - ROLLBACK_CREATE_OR_ADD_COLUMN((byte) 1), - COMMIT_CREATE_OR_ADD_COLUMN((byte) 2); + PRE_UPDATE_TABLE((byte) 0), + ROLLBACK_UPDATE_TABLE((byte) 1), + COMMIT_UPDATE_TABLE((byte) 2); private final byte operationType; - private TsTableInternalRPCType(final byte operationType) { + TsTableInternalRPCType(final byte operationType) { this.operationType = operationType; } @@ -45,18 +45,18 @@ public void serialize(final OutputStream stream) throws IOException { } public static TsTableInternalRPCType deserialize(final ByteBuffer buffer) { - byte type = ReadWriteIOUtils.readByte(buffer); + final byte type = ReadWriteIOUtils.readByte(buffer); return getType(type); } public static TsTableInternalRPCType getType(final byte type) { switch (type) { case 0: - return PRE_CREATE_OR_ADD_COLUMN; + return PRE_UPDATE_TABLE; case 1: - return ROLLBACK_CREATE_OR_ADD_COLUMN; + return ROLLBACK_UPDATE_TABLE; case 2: - return COMMIT_CREATE_OR_ADD_COLUMN; + return COMMIT_UPDATE_TABLE; default: throw new IllegalArgumentException("Unknown table update operation type" + type); } diff --git a/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4 b/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4 index a0011275212c..06a21e9cd4d6 100644 --- a/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4 +++ b/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4 @@ -46,6 +46,7 @@ statement | useDatabaseStatement | showDatabasesStatement | createDbStatement + | alterDbStatement | dropDbStatement // Table Statement @@ -143,6 +144,10 @@ createDbStatement : CREATE DATABASE (IF NOT EXISTS)? database=identifier (WITH properties)? ; +alterDbStatement + : ALTER DATABASE (IF EXISTS)? database=identifier SET PROPERTIES propertyAssignments + ; + dropDbStatement : DROP DATABASE (IF EXISTS)? database=identifier ;