From 624d999e52b8d3583b0997704a2d9826aaae235f Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Mon, 5 Jan 2026 16:17:48 +0800 Subject: [PATCH 01/11] create-check --- .../plan/execution/config/TableConfigTaskVisitor.java | 2 +- .../metadata/fetcher/TableHeaderSchemaValidator.java | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) 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 0f6c4bdb538e1..4b609aa87eb78 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 @@ -580,7 +580,7 @@ private Pair parseTable4CreateTableOrView( final TsTableColumnCategory category = columnDefinition.getColumnCategory(); final String columnName = columnDefinition.getName().getValue(); final TSDataType dataType = getDataType(columnDefinition.getType()); - hasObject |= dataType.equals(TSDataType.OBJECT); + hasObject |= dataType == TSDataType.OBJECT; final String comment = columnDefinition.getComment(); if (checkTimeColumnIdempotent(category, columnName, dataType, comment, table) && !hasTimeColumn) { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableHeaderSchemaValidator.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableHeaderSchemaValidator.java index daea9a9e9da68..9c90f15d3683a 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableHeaderSchemaValidator.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableHeaderSchemaValidator.java @@ -20,6 +20,7 @@ package org.apache.iotdb.db.queryengine.plan.relational.metadata.fetcher; import org.apache.iotdb.commons.exception.IoTDBException; +import org.apache.iotdb.commons.exception.MetadataException; import org.apache.iotdb.commons.schema.table.InsertNodeMeasurementInfo; import org.apache.iotdb.commons.schema.table.TreeViewSchema; import org.apache.iotdb.commons.schema.table.TsTable; @@ -629,6 +630,7 @@ public TsTable toTsTable(InsertNodeMeasurementInfo measurementInfo) { return tsTable; } + boolean hasObject = false; for (int i = 0; i < measurements.length; i++) { if (measurements[i] == null) { continue; @@ -657,9 +659,16 @@ public TsTable toTsTable(InsertNodeMeasurementInfo measurementInfo) { throw new ColumnCreationFailException( "Cannot create column " + columnName + " datatype is not provided"); } - + hasObject |= dataType == TSDataType.OBJECT; tsTable.addColumnSchema(generateColumnSchema(category, columnName, dataType, null, null)); } + if (hasObject) { + try { + tsTable.checkTableNameAndObjectNames4Object(); + } catch (final MetadataException e) { + throw new SemanticException(e.getMessage(), e.getErrorCode()); + } + } return tsTable; } From 3b682f86ce46191c0ebedd81f54fad84f786e692 Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Mon, 5 Jan 2026 16:32:48 +0800 Subject: [PATCH 02/11] init-windows --- .../iotdb/commons/utils/WindowsOSUtils.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/WindowsOSUtils.java diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/WindowsOSUtils.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/WindowsOSUtils.java new file mode 100644 index 0000000000000..60cc5a938b0fa --- /dev/null +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/WindowsOSUtils.java @@ -0,0 +1,24 @@ +/* + * 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.commons.utils; + +public class WindowsOSUtils { + +} From 677ea256f934912eee44df2df8533b98914b83b3 Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Mon, 5 Jan 2026 17:04:15 +0800 Subject: [PATCH 03/11] windows --- .../iotdb/commons/schema/table/TsTable.java | 12 +++--- .../iotdb/commons/utils/WindowsOSUtils.java | 37 ++++++++++++++++++- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TsTable.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TsTable.java index 8f5f5f44f6055..f19d2f58d072d 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TsTable.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TsTable.java @@ -30,6 +30,7 @@ import org.apache.iotdb.commons.schema.table.column.TsTableColumnSchema; import org.apache.iotdb.commons.schema.table.column.TsTableColumnSchemaUtil; import org.apache.iotdb.commons.utils.CommonDateTimeUtils; +import org.apache.iotdb.commons.utils.WindowsOSUtils; import org.apache.iotdb.rpc.TSStatusCode; import com.google.common.collect.ImmutableList; @@ -435,11 +436,12 @@ && isInvalid4ObjectType(schema.getColumnName())) { } } - public static boolean isInvalid4ObjectType(final String column) { - return column.equals(".") - || column.equals("..") - || column.contains("./") - || column.contains(".\\"); + public static boolean isInvalid4ObjectType(final String path) { + return path.equals(".") + || path.equals("..") + || path.contains("./") + || path.contains(".\\") + || !WindowsOSUtils.isLegalPathSegment4Windows(path); } public static String getObjectStringError(final String columnType, final String columnName) { diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/WindowsOSUtils.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/WindowsOSUtils.java index 60cc5a938b0fa..f4fb375c23b82 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/WindowsOSUtils.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/WindowsOSUtils.java @@ -19,6 +19,41 @@ package org.apache.iotdb.commons.utils; +import org.apache.tsfile.external.commons.lang3.SystemUtils; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + public class WindowsOSUtils { - + private static final String ILLEGAL_WINDOWS_CHARS = "\\/:*?\"<>|"; + private static final Set ILLEGAL_WINDOWS_NAMES = + new HashSet<>(Arrays.asList("CON", "PRN", "AUX", "NUL", "COM1-COM9, LPT1-LPT9")); + + static { + for (int i = 0; i < 10; ++i) { + ILLEGAL_WINDOWS_NAMES.add("COM" + i); + ILLEGAL_WINDOWS_NAMES.add("LPT" + i); + } + } + + public static boolean isLegalPathSegment4Windows(final String pathSegment) { + if (!SystemUtils.IS_OS_WINDOWS) { + return true; + } + for (final char illegalChar : ILLEGAL_WINDOWS_CHARS.toCharArray()) { + if (pathSegment.indexOf(illegalChar) != -1) { + return false; + } + } + if (pathSegment.endsWith(".") || pathSegment.endsWith(" ")) { + return false; + } + for (final String illegalName : ILLEGAL_WINDOWS_NAMES) { + if (pathSegment.equalsIgnoreCase(illegalName)) { + return false; + } + } + return true; + } } From ab27d52f8e75596be34ad475100e425c137385d8 Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Mon, 5 Jan 2026 17:10:20 +0800 Subject: [PATCH 04/11] windows --- .../commons/utils/WindowsOSUtilsTest.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 iotdb-core/node-commons/src/test/java/org/apache/iotdb/commons/utils/WindowsOSUtilsTest.java diff --git a/iotdb-core/node-commons/src/test/java/org/apache/iotdb/commons/utils/WindowsOSUtilsTest.java b/iotdb-core/node-commons/src/test/java/org/apache/iotdb/commons/utils/WindowsOSUtilsTest.java new file mode 100644 index 0000000000000..bbe847b6f8ecc --- /dev/null +++ b/iotdb-core/node-commons/src/test/java/org/apache/iotdb/commons/utils/WindowsOSUtilsTest.java @@ -0,0 +1,41 @@ +/* + * 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.commons.utils; + +import org.apache.tsfile.external.commons.lang3.SystemUtils; +import org.junit.Assert; +import org.junit.Test; + +import static org.apache.iotdb.commons.utils.WindowsOSUtils.isLegalPathSegment4Windows; + +public class WindowsOSUtilsTest { + @Test + public void testIllegalDetection() { + if (!SystemUtils.IS_OS_WINDOWS) { + return; + } + Assert.assertTrue(isLegalPathSegment4Windows("abc")); + Assert.assertTrue(isLegalPathSegment4Windows(".A!")); + + Assert.assertFalse(isLegalPathSegment4Windows("C.")); + Assert.assertFalse(isLegalPathSegment4Windows("a:b<|")); + Assert.assertFalse(isLegalPathSegment4Windows("COM1")); + } +} From 96b584d12c9610acf373cdf41e033816429e64d4 Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Mon, 5 Jan 2026 17:32:20 +0800 Subject: [PATCH 05/11] partial --- .../relational/it/schema/IoTDBTableIT.java | 18 ++++++++++++------ .../iotdb/commons/schema/table/TsTable.java | 10 ++++++++-- .../iotdb/commons/utils/WindowsOSUtils.java | 5 +++++ 3 files changed, 25 insertions(+), 8 deletions(-) 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 7ad5172fca41c..39135942dfa56 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 @@ -31,6 +31,7 @@ import org.apache.tsfile.enums.ColumnCategory; import org.apache.tsfile.enums.TSDataType; +import org.apache.tsfile.external.commons.lang3.SystemUtils; import org.apache.tsfile.write.record.Tablet; import org.apache.tsfile.write.schema.IMeasurementSchema; import org.apache.tsfile.write.schema.MeasurementSchema; @@ -784,6 +785,11 @@ public void testConcurrentAutoCreateAndDropColumn() throws Exception { @Test public void testTableObjectCheck() throws Exception { final Set illegal = new HashSet<>(Arrays.asList("./", ".", "..", ".\\", "../hack")); + if (SystemUtils.IS_OS_WINDOWS) { + illegal.add("C."); + illegal.add("a:b<|"); + illegal.add("COM1"); + } for (final String single : illegal) { testObject4SingleIllegalPath(single); } @@ -804,7 +810,7 @@ private void testObject4SingleIllegalPath(final String illegal) throws Exception } catch (final SQLException e) { Assert.assertEquals( String.format( - "701: When there are object fields, the tableName %s shall not be '.', '..' or contain './', '.\\'", + "701: When there are object fields, the tableName %s shall not be '.', '..' or contain './', '.\\'.", illegal), e.getMessage()); } @@ -849,7 +855,7 @@ private void testObject4SingleIllegalPath(final String illegal) throws Exception } catch (final Exception e) { Assert.assertEquals( String.format( - "701: When there are object fields, the tableName %s shall not be '.', '..' or contain './', '.\\'", + "701: When there are object fields, the tableName %s shall not be '.', '..' or contain './', '.\\'.", illegal), e.getMessage()); } @@ -860,7 +866,7 @@ private void testObject4SingleIllegalPath(final String illegal) throws Exception } catch (final SQLException e) { Assert.assertEquals( String.format( - "701: When there are object fields, the objectName %s shall not be '.', '..' or contain './', '.\\'", + "701: When there are object fields, the objectName %s shall not be '.', '..' or contain './', '.\\'.", illegal), e.getMessage()); } @@ -875,7 +881,7 @@ private void testObject4SingleIllegalPath(final String illegal) throws Exception } catch (final Exception e) { Assert.assertEquals( String.format( - "701: When there are object fields, the objectName %s shall not be '.', '..' or contain './', '.\\'", + "701: When there are object fields, the objectName %s shall not be '.', '..' or contain './', '.\\'.", illegal), e.getMessage()); } @@ -891,7 +897,7 @@ private void testObject4SingleIllegalPath(final String illegal) throws Exception } catch (final SQLException e) { Assert.assertEquals( String.format( - "507: When there are object fields, the deviceId [test, %s] shall not be '.', '..' or contain './', '.\\'", + "507: When there are object fields, the deviceId [test, %s] shall not be '.', '..' or contain './', '.\\'.", illegal), e.getMessage()); } @@ -902,7 +908,7 @@ private void testObject4SingleIllegalPath(final String illegal) throws Exception } catch (final SQLException e) { Assert.assertEquals( String.format( - "701: When there are object fields, the objectName %s shall not be '.', '..' or contain './', '.\\'", + "701: When there are object fields, the objectName %s shall not be '.', '..' or contain './', '.\\'.", illegal), e.getMessage()); } diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TsTable.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TsTable.java index f19d2f58d072d..0a28cae2ea02d 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TsTable.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TsTable.java @@ -35,6 +35,7 @@ import com.google.common.collect.ImmutableList; import org.apache.tsfile.enums.TSDataType; +import org.apache.tsfile.external.commons.lang3.SystemUtils; import org.apache.tsfile.utils.Pair; import org.apache.tsfile.utils.ReadWriteIOUtils; @@ -72,7 +73,7 @@ public class TsTable { public static final String TTL_PROPERTY = "ttl"; public static final Set TABLE_ALLOWED_PROPERTIES = Collections.singleton(TTL_PROPERTY); private static final String OBJECT_STRING_ERROR = - "When there are object fields, the %s %s shall not be '.', '..' or contain './', '.\\'"; + "When there are object fields, the %s %s shall not be '.', '..' or contain './', '.\\'."; protected String tableName; private final Map columnSchemaMap = new LinkedHashMap<>(); @@ -445,7 +446,12 @@ public static boolean isInvalid4ObjectType(final String path) { } public static String getObjectStringError(final String columnType, final String columnName) { - return String.format(OBJECT_STRING_ERROR, columnType, columnName); + return String.format( + SystemUtils.IS_OS_WINDOWS + ? OBJECT_STRING_ERROR + " " + WindowsOSUtils.OS_SEGMENT_ERROR + : OBJECT_STRING_ERROR, + columnType, + columnName); } @Override diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/WindowsOSUtils.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/WindowsOSUtils.java index f4fb375c23b82..3e8155ed759b9 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/WindowsOSUtils.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/WindowsOSUtils.java @@ -37,6 +37,11 @@ public class WindowsOSUtils { } } + public static final String OS_SEGMENT_ERROR = + String.format( + "In Windows System, the path shall not contains %s, equals one of %s, or ends with '.' or ' '.", + ILLEGAL_WINDOWS_CHARS, ILLEGAL_WINDOWS_NAMES); + public static boolean isLegalPathSegment4Windows(final String pathSegment) { if (!SystemUtils.IS_OS_WINDOWS) { return true; From 3b138fb0c7eb11982ac86c05ecb270cdb00096bd Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Mon, 5 Jan 2026 17:36:44 +0800 Subject: [PATCH 06/11] IT-change --- .../relational/it/schema/IoTDBTableIT.java | 42 ++++++------------- 1 file changed, 12 insertions(+), 30 deletions(-) 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 39135942dfa56..4842d4e30a014 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 @@ -19,6 +19,7 @@ package org.apache.iotdb.relational.it.schema; +import org.apache.iotdb.commons.utils.WindowsOSUtils; import org.apache.iotdb.db.it.utils.TestUtils; import org.apache.iotdb.isession.ITableSession; import org.apache.iotdb.it.env.EnvFactory; @@ -804,15 +805,16 @@ private void testObject4SingleIllegalPath(final String illegal) throws Exception statement.execute("use db2"); statement.execute(String.format("create table \"%s\" ()", illegal)); + String expectedError = + String.format( + "701: When there are object fields, the tableName %s shall not be '.', '..' or contain './', '.\\'." + + (SystemUtils.IS_OS_WINDOWS ? " " + WindowsOSUtils.OS_SEGMENT_ERROR : ""), + illegal); try { statement.execute(String.format("alter table \"%s\" add column a object", illegal)); fail(); } catch (final SQLException e) { - Assert.assertEquals( - String.format( - "701: When there are object fields, the tableName %s shall not be '.', '..' or contain './', '.\\'.", - illegal), - e.getMessage()); + Assert.assertEquals(expectedError, e.getMessage()); } // Test auto-create @@ -853,22 +855,14 @@ private void testObject4SingleIllegalPath(final String illegal) throws Exception session.executeNonQueryStatement("use db2"); session.insert(tablet); } catch (final Exception e) { - Assert.assertEquals( - String.format( - "701: When there are object fields, the tableName %s shall not be '.', '..' or contain './', '.\\'.", - illegal), - e.getMessage()); + Assert.assertEquals(expectedError, e.getMessage()); } try { statement.execute(String.format("create table test (\"%s\" object)", illegal)); fail(); } catch (final SQLException e) { - Assert.assertEquals( - String.format( - "701: When there are object fields, the objectName %s shall not be '.', '..' or contain './', '.\\'.", - illegal), - e.getMessage()); + Assert.assertEquals(expectedError, e.getMessage()); } statement.execute("create table test (a tag, b attribute, c int32, d object)"); @@ -879,11 +873,7 @@ private void testObject4SingleIllegalPath(final String illegal) throws Exception session.executeNonQueryStatement("use db2"); session.insert(tablet); } catch (final Exception e) { - Assert.assertEquals( - String.format( - "701: When there are object fields, the objectName %s shall not be '.', '..' or contain './', '.\\'.", - illegal), - e.getMessage()); + Assert.assertEquals(expectedError, e.getMessage()); } // It's OK if you don't write object @@ -895,22 +885,14 @@ private void testObject4SingleIllegalPath(final String illegal) throws Exception illegal)); fail(); } catch (final SQLException e) { - Assert.assertEquals( - String.format( - "507: When there are object fields, the deviceId [test, %s] shall not be '.', '..' or contain './', '.\\'.", - illegal), - e.getMessage()); + Assert.assertEquals(expectedError, e.getMessage()); } try { statement.execute(String.format("alter table test add column \"%s\" object", illegal)); fail(); } catch (final SQLException e) { - Assert.assertEquals( - String.format( - "701: When there are object fields, the objectName %s shall not be '.', '..' or contain './', '.\\'.", - illegal), - e.getMessage()); + Assert.assertEquals(expectedError, e.getMessage()); } statement.execute("drop database db2"); From 766ab368ba97de4d6abd2114d62b7c0f77715824 Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Mon, 5 Jan 2026 17:41:09 +0800 Subject: [PATCH 07/11] create-table --- .../relational/it/schema/IoTDBTableIT.java | 41 +++++++++++-------- 1 file changed, 25 insertions(+), 16 deletions(-) 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 4842d4e30a014..470fda789c98e 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 @@ -803,22 +803,9 @@ private void testObject4SingleIllegalPath(final String illegal) throws Exception final ITableSession session = EnvFactory.getEnv().getTableSessionConnection()) { statement.execute("create database if not exists db2"); statement.execute("use db2"); - statement.execute(String.format("create table \"%s\" ()", illegal)); - - String expectedError = - String.format( - "701: When there are object fields, the tableName %s shall not be '.', '..' or contain './', '.\\'." - + (SystemUtils.IS_OS_WINDOWS ? " " + WindowsOSUtils.OS_SEGMENT_ERROR : ""), - illegal); - try { - statement.execute(String.format("alter table \"%s\" add column a object", illegal)); - fail(); - } catch (final SQLException e) { - Assert.assertEquals(expectedError, e.getMessage()); - } - // Test auto-create - String testObject = + // Test auto-create table + final String testObject = System.getProperty("user.dir") + File.separator + "target" @@ -827,7 +814,7 @@ private void testObject4SingleIllegalPath(final String illegal) throws Exception + File.separator + "object-example.pt"; - List schemaList = new ArrayList<>(); + final List schemaList = new ArrayList<>(); schemaList.add(new MeasurementSchema("a", TSDataType.STRING)); schemaList.add(new MeasurementSchema("b", TSDataType.STRING)); schemaList.add(new MeasurementSchema("c", TSDataType.INT32)); @@ -851,6 +838,28 @@ private void testObject4SingleIllegalPath(final String illegal) throws Exception tablet.addValue(schemaList.get(2).getMeasurementName(), 0, 0); tablet.addValue(0, 3, true, 0, Files.readAllBytes(Paths.get(testObject))); + final String expectedError = + String.format( + "701: When there are object fields, the tableName %s shall not be '.', '..' or contain './', '.\\'." + + (SystemUtils.IS_OS_WINDOWS ? " " + WindowsOSUtils.OS_SEGMENT_ERROR : ""), + illegal); + try { + session.executeNonQueryStatement("use db2"); + session.insert(tablet); + } catch (final Exception e) { + Assert.assertEquals(expectedError, e.getMessage()); + } + + statement.execute(String.format("create table \"%s\" ()", illegal)); + + try { + statement.execute(String.format("alter table \"%s\" add column a object", illegal)); + fail(); + } catch (final SQLException e) { + Assert.assertEquals(expectedError, e.getMessage()); + } + + // Test auto-create column try { session.executeNonQueryStatement("use db2"); session.insert(tablet); From bbed44fabe98e3cb63e873a7b3d34ddb78e21fa7 Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Mon, 5 Jan 2026 17:45:29 +0800 Subject: [PATCH 08/11] po --- .../relational/it/schema/IoTDBTableIT.java | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) 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 470fda789c98e..64763177e7a59 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 @@ -838,16 +838,22 @@ private void testObject4SingleIllegalPath(final String illegal) throws Exception tablet.addValue(schemaList.get(2).getMeasurementName(), 0, 0); tablet.addValue(0, 3, true, 0, Files.readAllBytes(Paths.get(testObject))); - final String expectedError = + final String expectedTableError = String.format( "701: When there are object fields, the tableName %s shall not be '.', '..' or contain './', '.\\'." + (SystemUtils.IS_OS_WINDOWS ? " " + WindowsOSUtils.OS_SEGMENT_ERROR : ""), illegal); + final String expectedObjectError = + String.format( + "701: When there are object fields, the objectName %s shall not be '.', '..' or contain './', '.\\'." + + (SystemUtils.IS_OS_WINDOWS ? " " + WindowsOSUtils.OS_SEGMENT_ERROR : ""), + illegal); + try { session.executeNonQueryStatement("use db2"); session.insert(tablet); } catch (final Exception e) { - Assert.assertEquals(expectedError, e.getMessage()); + Assert.assertEquals(expectedTableError, e.getMessage()); } statement.execute(String.format("create table \"%s\" ()", illegal)); @@ -856,7 +862,7 @@ private void testObject4SingleIllegalPath(final String illegal) throws Exception statement.execute(String.format("alter table \"%s\" add column a object", illegal)); fail(); } catch (final SQLException e) { - Assert.assertEquals(expectedError, e.getMessage()); + Assert.assertEquals(expectedTableError, e.getMessage()); } // Test auto-create column @@ -864,14 +870,14 @@ private void testObject4SingleIllegalPath(final String illegal) throws Exception session.executeNonQueryStatement("use db2"); session.insert(tablet); } catch (final Exception e) { - Assert.assertEquals(expectedError, e.getMessage()); + Assert.assertEquals(expectedTableError, e.getMessage()); } try { statement.execute(String.format("create table test (\"%s\" object)", illegal)); fail(); } catch (final SQLException e) { - Assert.assertEquals(expectedError, e.getMessage()); + Assert.assertEquals(expectedObjectError, e.getMessage()); } statement.execute("create table test (a tag, b attribute, c int32, d object)"); @@ -882,7 +888,7 @@ private void testObject4SingleIllegalPath(final String illegal) throws Exception session.executeNonQueryStatement("use db2"); session.insert(tablet); } catch (final Exception e) { - Assert.assertEquals(expectedError, e.getMessage()); + Assert.assertEquals(expectedObjectError, e.getMessage()); } // It's OK if you don't write object @@ -894,14 +900,19 @@ private void testObject4SingleIllegalPath(final String illegal) throws Exception illegal)); fail(); } catch (final SQLException e) { - Assert.assertEquals(expectedError, e.getMessage()); + Assert.assertEquals( + String.format( + "507: When there are object fields, the deviceId [test, %s] shall not be '.', '..' or contain './', '.\\'." + + (SystemUtils.IS_OS_WINDOWS ? " " + WindowsOSUtils.OS_SEGMENT_ERROR : ""), + illegal), + e.getMessage()); } try { statement.execute(String.format("alter table test add column \"%s\" object", illegal)); fail(); } catch (final SQLException e) { - Assert.assertEquals(expectedError, e.getMessage()); + Assert.assertEquals(expectedTableError, e.getMessage()); } statement.execute("drop database db2"); From 1f3851f8a722fb04d80f3387383358d81a5c22ed Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Mon, 5 Jan 2026 18:08:14 +0800 Subject: [PATCH 09/11] fix --- .../relational/metadata/fetcher/TableHeaderSchemaValidator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableHeaderSchemaValidator.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableHeaderSchemaValidator.java index 9c90f15d3683a..41a0d66c1f63b 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableHeaderSchemaValidator.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableHeaderSchemaValidator.java @@ -666,7 +666,7 @@ public TsTable toTsTable(InsertNodeMeasurementInfo measurementInfo) { try { tsTable.checkTableNameAndObjectNames4Object(); } catch (final MetadataException e) { - throw new SemanticException(e.getMessage(), e.getErrorCode()); + throw new SemanticException(e.getMessage(), TSStatusCode.SEMANTIC_ERROR.getStatusCode()); } } return tsTable; From a340e42977488e96d4ceda6dd7748f3dc552da6d Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Mon, 5 Jan 2026 18:26:19 +0800 Subject: [PATCH 10/11] bypass-sit --- .../metadata/fetcher/TableHeaderSchemaValidator.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableHeaderSchemaValidator.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableHeaderSchemaValidator.java index 41a0d66c1f63b..99da3d005f721 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableHeaderSchemaValidator.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableHeaderSchemaValidator.java @@ -20,6 +20,7 @@ package org.apache.iotdb.db.queryengine.plan.relational.metadata.fetcher; import org.apache.iotdb.commons.exception.IoTDBException; +import org.apache.iotdb.commons.exception.IoTDBRuntimeException; import org.apache.iotdb.commons.exception.MetadataException; import org.apache.iotdb.commons.schema.table.InsertNodeMeasurementInfo; import org.apache.iotdb.commons.schema.table.TreeViewSchema; @@ -666,7 +667,8 @@ public TsTable toTsTable(InsertNodeMeasurementInfo measurementInfo) { try { tsTable.checkTableNameAndObjectNames4Object(); } catch (final MetadataException e) { - throw new SemanticException(e.getMessage(), TSStatusCode.SEMANTIC_ERROR.getStatusCode()); + throw new IoTDBRuntimeException( + e.getMessage(), TSStatusCode.SEMANTIC_ERROR.getStatusCode()); } } return tsTable; From 60124bdd6000cf378c8f8d00b0f1425492d53d20 Mon Sep 17 00:00:00 2001 From: Caideyipi <87789683+Caideyipi@users.noreply.github.com> Date: Mon, 5 Jan 2026 18:35:06 +0800 Subject: [PATCH 11/11] finally --- .../org/apache/iotdb/relational/it/schema/IoTDBTableIT.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 64763177e7a59..7915d64a68089 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 @@ -842,12 +842,12 @@ private void testObject4SingleIllegalPath(final String illegal) throws Exception String.format( "701: When there are object fields, the tableName %s shall not be '.', '..' or contain './', '.\\'." + (SystemUtils.IS_OS_WINDOWS ? " " + WindowsOSUtils.OS_SEGMENT_ERROR : ""), - illegal); + illegal.toLowerCase()); final String expectedObjectError = String.format( "701: When there are object fields, the objectName %s shall not be '.', '..' or contain './', '.\\'." + (SystemUtils.IS_OS_WINDOWS ? " " + WindowsOSUtils.OS_SEGMENT_ERROR : ""), - illegal); + illegal.toLowerCase()); try { session.executeNonQueryStatement("use db2"); @@ -912,7 +912,7 @@ private void testObject4SingleIllegalPath(final String illegal) throws Exception statement.execute(String.format("alter table test add column \"%s\" object", illegal)); fail(); } catch (final SQLException e) { - Assert.assertEquals(expectedTableError, e.getMessage()); + Assert.assertEquals(expectedObjectError, e.getMessage()); } statement.execute("drop database db2");