diff --git a/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBInsertTableIT.java b/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBInsertTableIT.java index c223761cd2a2b..a3138ee6ea226 100644 --- a/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBInsertTableIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBInsertTableIT.java @@ -1275,6 +1275,23 @@ public void testInsertWithChangedSchema() throws SQLException, IOException { } } + @Test + public void testInsertWithTree() { + try (Connection connection = EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT); + Statement statement = connection.createStatement()) { + statement.execute("use \"test\""); + statement.execute("create table sg22 (tag1 string tag, s1 int64 field)"); + statement.execute( + String.format( + "insert into root.test.sg22(tag1,time,s1) values('d1',%s,2)", + System.currentTimeMillis())); + fail(); + } catch (Exception e) { + Assert.assertEquals( + "701: The tree model database shall not be specified in table model.", e.getMessage()); + } + } + private List checkHeader( ResultSetMetaData resultSetMetaData, String expectedHeaderStrings, int[] expectedTypes) throws SQLException { diff --git a/integration-test/src/test/java/org/apache/iotdb/relational/it/rest/it/IoTDBRestServiceIT.java b/integration-test/src/test/java/org/apache/iotdb/relational/it/rest/it/IoTDBRestServiceIT.java index 8ffe434db738b..05567b886fc7e 100644 --- a/integration-test/src/test/java/org/apache/iotdb/relational/it/rest/it/IoTDBRestServiceIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/relational/it/rest/it/IoTDBRestServiceIT.java @@ -143,6 +143,7 @@ public void test() { testInsertMultiPartition(); testInsertTablet(); testInsertTabletNoDatabase(); + testInsertTabletWithTreeDB(); testInsertTablet1(); testInsertTablet2(); testQuery(); @@ -296,6 +297,18 @@ public void testInsertTabletNoDatabase() { assertEquals(305, Integer.parseInt(result.get("code").toString())); } + public void testInsertTabletWithTreeDB() { + List sqls = + Collections.singletonList( + "create table sg211 (tag1 string tag,t1 STRING ATTRIBUTE, s1 FLOAT field)"); + for (String sql : sqls) { + RestUtils.nonQuery(httpClient, port, sqlHandler("test", sql)); + } + String json = + "{\"database\":\"root.test\",\"column_categories\":[\"TAG\",\"ATTRIBUTE\",\"FIELD\"],\"timestamps\":[1635232143960,1635232153960,1635232163960,1635232173960,1635232183960],\"column_names\":[\"tag1\",\"t1\",\"s1\"],\"data_types\":[\"STRING\",\"STRING\",\"FLOAT\"],\"values\":[[\"a11\",\"true\",11],[\"a11\",\"false\",22],[\"a13\",\"false1\",23],[\"a14\",\"false2\",24],[\"a15\",\"false3\",25]],\"table\":\"sg211\"}"; + wrongInsertTablet(json); + } + public void testInsertTablet1() { List sqls = Collections.singletonList( @@ -340,6 +353,11 @@ public void rightInsertTablet(String json) { assertEquals(11f, jsonArray1.get(2).getAsFloat(), 0f); } + public void wrongInsertTablet(String json) { + JsonObject result = RestUtils.insertTablet(httpClient, port, json); + assertEquals(701, Integer.parseInt(result.get("code").toString())); + } + public void prepareTableData() { for (int i = 0; i < sqls.length; i++) { JsonObject jsonObject = new JsonObject(); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/parser/TsFileInsertionEventParser.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/parser/TsFileInsertionEventParser.java index 678e7a4a62a5d..a723adce0dfda 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/parser/TsFileInsertionEventParser.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/parser/TsFileInsertionEventParser.java @@ -26,6 +26,7 @@ import org.apache.iotdb.commons.pipe.datastructure.pattern.TreePattern; import org.apache.iotdb.db.conf.IoTDBDescriptor; import org.apache.iotdb.db.pipe.event.common.PipeInsertionEvent; +import org.apache.iotdb.db.pipe.event.common.tsfile.parser.table.TsFileInsertionEventTableParser; import org.apache.iotdb.db.pipe.metric.overview.PipeTsFileToTabletsMetrics; import org.apache.iotdb.db.pipe.resource.PipeDataNodeResourceManager; import org.apache.iotdb.db.pipe.resource.memory.PipeMemoryBlock; @@ -41,6 +42,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.File; import java.io.IOException; public abstract class TsFileInsertionEventParser implements AutoCloseable { @@ -76,6 +78,7 @@ public abstract class TsFileInsertionEventParser implements AutoCloseable { protected Iterable tabletInsertionIterable; protected TsFileInsertionEventParser( + final File tsFile, final String pipeName, final long creationTime, final TreePattern treePattern, @@ -85,7 +88,8 @@ protected TsFileInsertionEventParser( final PipeTaskMeta pipeTaskMeta, final IAuditEntity entity, final boolean skipIfNoPrivileges, - final PipeInsertionEvent sourceEvent) { + final PipeInsertionEvent sourceEvent, + final boolean isWithMod) { this.pipeName = pipeName; this.creationTime = creationTime; this.entity = entity; @@ -107,6 +111,17 @@ protected TsFileInsertionEventParser( PipeDataNodeResourceManager.memory() .forceAllocateForTabletWithRetry( IoTDBDescriptor.getInstance().getConfig().getPipeDataStructureTabletSizeInBytes()); + + LOGGER.info( + "TsFile {} has initialized {}, pipeName: {}, creation time: {}, pattern: {}, startTime: {}, endTime: {}, withMod: {}", + tsFile, + getClass().getSimpleName(), + pipeName, + creationTime, + this instanceof TsFileInsertionEventTableParser ? tablePattern : treePattern, + startTime, + endTime, + isWithMod); } /** diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/parser/query/TsFileInsertionEventQueryParser.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/parser/query/TsFileInsertionEventQueryParser.java index cc497635aab37..7e7226a61656f 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/parser/query/TsFileInsertionEventQueryParser.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/parser/query/TsFileInsertionEventQueryParser.java @@ -131,6 +131,7 @@ public TsFileInsertionEventQueryParser( final boolean isWithMod) throws IOException, IllegalPathException { super( + tsFile, pipeName, creationTime, pattern, @@ -140,7 +141,8 @@ public TsFileInsertionEventQueryParser( pipeTaskMeta, entity, skipIfNoPrivileges, - sourceEvent); + sourceEvent, + isWithMod); try { currentModifications = diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/parser/scan/TsFileInsertionEventScanParser.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/parser/scan/TsFileInsertionEventScanParser.java index da9d7d00477b9..aeb7aaadf2867 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/parser/scan/TsFileInsertionEventScanParser.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/parser/scan/TsFileInsertionEventScanParser.java @@ -118,6 +118,7 @@ public TsFileInsertionEventScanParser( final boolean isWithMod) throws IOException, IllegalPathException { super( + tsFile, pipeName, creationTime, pattern, @@ -127,7 +128,8 @@ public TsFileInsertionEventScanParser( pipeTaskMeta, entity, skipIfNoPrivileges, - sourceEvent); + sourceEvent, + isWithMod); this.startTime = startTime; this.endTime = endTime; diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/parser/table/TsFileInsertionEventTableParser.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/parser/table/TsFileInsertionEventTableParser.java index af2fd214e4a30..87cf374aeb266 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/parser/table/TsFileInsertionEventTableParser.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/parser/table/TsFileInsertionEventTableParser.java @@ -71,6 +71,7 @@ public TsFileInsertionEventTableParser( final boolean isWithMod) throws IOException { super( + tsFile, pipeName, creationTime, null, @@ -80,7 +81,8 @@ public TsFileInsertionEventTableParser( pipeTaskMeta, entity, true, - sourceEvent); + sourceEvent, + isWithMod); this.isWithMod = isWithMod; try { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/session/IClientSession.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/session/IClientSession.java index 44db640237562..9054636904ed6 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/session/IClientSession.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/session/IClientSession.java @@ -21,7 +21,10 @@ import org.apache.iotdb.commons.conf.IoTDBConstant.ClientVersion; import org.apache.iotdb.commons.utils.CommonDateTimeUtils; +import org.apache.iotdb.commons.utils.PathUtils; +import org.apache.iotdb.db.exception.sql.SemanticException; import org.apache.iotdb.db.queryengine.common.ConnectionInfo; +import org.apache.iotdb.rpc.subscription.annotation.TableModel; import org.apache.iotdb.service.rpc.thrift.TSConnectionInfo; import org.apache.iotdb.service.rpc.thrift.TSConnectionType; @@ -33,6 +36,7 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.time.ZoneId; +import java.util.Objects; import java.util.Set; import java.util.TimeZone; @@ -188,8 +192,15 @@ public String getDatabaseName() { return databaseName; } + @TableModel public void setDatabaseName(@Nullable String databaseName) { this.databaseName = databaseName; + if (Objects.nonNull(databaseName) && !PathUtils.isTableModelDatabase(databaseName)) { + throw new SemanticException( + "The database name " + + databaseName + + " is a tree model database, which is not allowed to set in the client session."); + } } /** 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 8770f6416c528..9bd99771f53ba 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 @@ -32,6 +32,7 @@ import org.apache.iotdb.commons.schema.table.column.TsTableColumnSchema; import org.apache.iotdb.commons.udf.builtin.relational.TableBuiltinScalarFunction; import org.apache.iotdb.commons.utils.CommonDateTimeUtils; +import org.apache.iotdb.commons.utils.PathUtils; import org.apache.iotdb.db.exception.query.QueryProcessException; import org.apache.iotdb.db.exception.sql.SemanticException; import org.apache.iotdb.db.protocol.session.IClientSession; @@ -4136,7 +4137,11 @@ private static String unquote(String value) { } private QualifiedName getQualifiedName(RelationalSqlParser.QualifiedNameContext context) { - return QualifiedName.of(visit(context.identifier(), Identifier.class)); + final QualifiedName result = QualifiedName.of(visit(context.identifier(), Identifier.class)); + if (!result.getPrefix().map(s -> PathUtils.isTableModelDatabase(s.toString())).orElse(true)) { + throw new SemanticException("The tree model database shall not be specified in table model."); + } + return result; } private static boolean isDistinct(RelationalSqlParser.SetQuantifierContext setQuantifier) { diff --git a/pom.xml b/pom.xml index 4d837399bf7a2..1763a519f9efe 100644 --- a/pom.xml +++ b/pom.xml @@ -61,7 +61,7 @@ 4.2.0 - 1.81 + 1.84 2.9.3 3.3.0