From 42ea3163cff7efe379201e745317e2f0394dcd01 Mon Sep 17 00:00:00 2001 From: libo Date: Thu, 22 Jan 2026 15:27:02 +0800 Subject: [PATCH 1/2] Fix the problem that fault a Exception named "java.nio.BufferUnderflowException" when AlterTimeSeriesDataTypeProcedure deserialize . --- .../AlterTimeSeriesDataTypeProcedure.java | 5 +- .../AlterTimeSeriesDataTypeProcedureTest.java | 115 ++++++++++++++++++ 2 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/schema/AlterTimeSeriesDataTypeProcedureTest.java diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/AlterTimeSeriesDataTypeProcedure.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/AlterTimeSeriesDataTypeProcedure.java index ad1d04ca6eeb..05daf8c900de 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/AlterTimeSeriesDataTypeProcedure.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/AlterTimeSeriesDataTypeProcedure.java @@ -25,6 +25,7 @@ import org.apache.iotdb.common.rpc.thrift.TSStatus; import org.apache.iotdb.commons.exception.MetadataException; import org.apache.iotdb.commons.path.MeasurementPath; +import org.apache.iotdb.commons.path.PathDeserializeUtil; import org.apache.iotdb.commons.path.PathPatternTree; import org.apache.iotdb.confignode.client.async.CnToDnAsyncRequestType; import org.apache.iotdb.confignode.client.async.CnToDnInternalServiceAsyncRequestManager; @@ -375,9 +376,9 @@ public void serialize(final DataOutputStream stream) throws IOException { public void deserialize(final ByteBuffer byteBuffer) { super.deserialize(byteBuffer); queryId = ReadWriteIOUtils.readString(byteBuffer); - setMeasurementPath(MeasurementPath.deserialize(byteBuffer)); + setMeasurementPath((MeasurementPath) PathDeserializeUtil.deserialize(byteBuffer)); if (getCurrentState() == AlterTimeSeriesDataTypeState.CLEAR_CACHE) { - LOGGER.info("Successfully restored, will set mods to the data regions anyway"); + LOGGER.info("Successfully operate, will clear cache to the data regions anyway"); } if (byteBuffer.hasRemaining()) { operationType = ReadWriteIOUtils.readByte(byteBuffer); diff --git a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/schema/AlterTimeSeriesDataTypeProcedureTest.java b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/schema/AlterTimeSeriesDataTypeProcedureTest.java new file mode 100644 index 000000000000..13ca4701b37a --- /dev/null +++ b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/schema/AlterTimeSeriesDataTypeProcedureTest.java @@ -0,0 +1,115 @@ +/* + * 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.impl.schema; + +import org.apache.iotdb.commons.exception.IllegalPathException; +import org.apache.iotdb.commons.path.MeasurementPath; +import org.apache.iotdb.commons.path.PartialPath; +import org.apache.iotdb.commons.schema.template.Template; +import org.apache.iotdb.commons.schema.tree.AlterTimeSeriesOperationType; +import org.apache.iotdb.confignode.procedure.store.ProcedureType; +import org.apache.iotdb.db.queryengine.common.schematree.ClusterSchemaTree; +import org.apache.iotdb.db.queryengine.plan.relational.metadata.fetcher.cache.TreeDeviceSchemaCacheManager; +import org.apache.iotdb.db.schemaengine.template.ClusterTemplateManager; + +import org.apache.tsfile.enums.TSDataType; +import org.apache.tsfile.file.metadata.enums.CompressionType; +import org.apache.tsfile.file.metadata.enums.TSEncoding; +import org.junit.Assert; +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class AlterTimeSeriesDataTypeProcedureTest { + + @Test + public void serializeDeserializeTest() throws IllegalPathException, IOException { + String queryId = "1"; + + MeasurementPath measurementPath = getMeasurementPath(); + AlterTimeSeriesDataTypeProcedure alterTimeSeriesDataTypeProcedure = + new AlterTimeSeriesDataTypeProcedure( + queryId, + measurementPath, + AlterTimeSeriesOperationType.ALTER_DATA_TYPE.getTypeValue(), + TSDataType.FLOAT, + false); + + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream); + alterTimeSeriesDataTypeProcedure.serialize(dataOutputStream); + + ByteBuffer byteBuffer = ByteBuffer.wrap(byteArrayOutputStream.toByteArray()); + + Assert.assertEquals( + ProcedureType.ALTER_TIMESERIES_DATATYPE_PROCEDURE.getTypeCode(), byteBuffer.getShort()); + + AlterTimeSeriesDataTypeProcedure deserializedProcedure = + new AlterTimeSeriesDataTypeProcedure(false); + deserializedProcedure.deserialize(byteBuffer); + + Assert.assertEquals(queryId, deserializedProcedure.getQueryId()); + Assert.assertEquals("root.sg1.d1.s1", deserializedProcedure.getmeasurementPath().getFullPath()); + } + + private static MeasurementPath getMeasurementPath() throws IllegalPathException { + final ClusterSchemaTree clusterSchemaTree = new ClusterSchemaTree(); + final Template template1 = + new Template( + "t1", + Arrays.asList("s1", "s2"), + Arrays.asList(TSDataType.DOUBLE, TSDataType.INT32), + Arrays.asList(TSEncoding.RLE, TSEncoding.RLE), + Arrays.asList(CompressionType.SNAPPY, CompressionType.SNAPPY)); + template1.setId(1); + final Template template2 = + new Template( + "t2", + Arrays.asList("t1", "t2", "t3"), + Arrays.asList(TSDataType.DOUBLE, TSDataType.INT32, TSDataType.INT64), + Arrays.asList(TSEncoding.RLE, TSEncoding.RLE, TSEncoding.RLBE), + Arrays.asList(CompressionType.SNAPPY, CompressionType.SNAPPY, CompressionType.SNAPPY)); + template2.setId(2); + ClusterTemplateManager.getInstance().putTemplate(template1); + ClusterTemplateManager.getInstance().putTemplate(template2); + clusterSchemaTree.appendTemplateDevice(new PartialPath("root.sg1.d1"), false, 1, template1); + clusterSchemaTree.appendTemplateDevice(new PartialPath("root.sg1.d2"), false, 2, template2); + clusterSchemaTree.setDatabases(Collections.singleton("root.sg1")); + clusterSchemaTree.appendSingleMeasurementPath( + new MeasurementPath("root.sg1.d3.s1", TSDataType.FLOAT)); + + TreeDeviceSchemaCacheManager treeDeviceSchemaCacheManager = + TreeDeviceSchemaCacheManager.getInstance(); + treeDeviceSchemaCacheManager.put(clusterSchemaTree); + final ClusterSchemaTree d1Tree = + treeDeviceSchemaCacheManager.getMatchedTemplateSchema(new PartialPath("root.sg1.d1")); + + final String[] ALL_RESULT_NODES = new String[] {"root", "sg1", "**"}; + final PartialPath ALL_MATCH_PATTERN = new PartialPath(ALL_RESULT_NODES); + List measurementPaths = d1Tree.searchMeasurementPaths(ALL_MATCH_PATTERN).left; + return measurementPaths.get(0); + } +} From 1365d2f07ba43bc501f6da042666b09cea0b6b00 Mon Sep 17 00:00:00 2001 From: libo Date: Thu, 22 Jan 2026 15:48:13 +0800 Subject: [PATCH 2/2] Simplify the way of obtaining a measurementPath object. --- .../AlterTimeSeriesDataTypeProcedureTest.java | 51 +------------------ 1 file changed, 1 insertion(+), 50 deletions(-) diff --git a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/schema/AlterTimeSeriesDataTypeProcedureTest.java b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/schema/AlterTimeSeriesDataTypeProcedureTest.java index 13ca4701b37a..6211b2021afb 100644 --- a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/schema/AlterTimeSeriesDataTypeProcedureTest.java +++ b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/schema/AlterTimeSeriesDataTypeProcedureTest.java @@ -21,17 +21,10 @@ import org.apache.iotdb.commons.exception.IllegalPathException; import org.apache.iotdb.commons.path.MeasurementPath; -import org.apache.iotdb.commons.path.PartialPath; -import org.apache.iotdb.commons.schema.template.Template; import org.apache.iotdb.commons.schema.tree.AlterTimeSeriesOperationType; import org.apache.iotdb.confignode.procedure.store.ProcedureType; -import org.apache.iotdb.db.queryengine.common.schematree.ClusterSchemaTree; -import org.apache.iotdb.db.queryengine.plan.relational.metadata.fetcher.cache.TreeDeviceSchemaCacheManager; -import org.apache.iotdb.db.schemaengine.template.ClusterTemplateManager; import org.apache.tsfile.enums.TSDataType; -import org.apache.tsfile.file.metadata.enums.CompressionType; -import org.apache.tsfile.file.metadata.enums.TSEncoding; import org.junit.Assert; import org.junit.Test; @@ -39,17 +32,13 @@ import java.io.DataOutputStream; import java.io.IOException; import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; public class AlterTimeSeriesDataTypeProcedureTest { @Test public void serializeDeserializeTest() throws IllegalPathException, IOException { String queryId = "1"; - - MeasurementPath measurementPath = getMeasurementPath(); + MeasurementPath measurementPath = new MeasurementPath("root.sg1.d1.s1"); AlterTimeSeriesDataTypeProcedure alterTimeSeriesDataTypeProcedure = new AlterTimeSeriesDataTypeProcedure( queryId, @@ -74,42 +63,4 @@ public void serializeDeserializeTest() throws IllegalPathException, IOException Assert.assertEquals(queryId, deserializedProcedure.getQueryId()); Assert.assertEquals("root.sg1.d1.s1", deserializedProcedure.getmeasurementPath().getFullPath()); } - - private static MeasurementPath getMeasurementPath() throws IllegalPathException { - final ClusterSchemaTree clusterSchemaTree = new ClusterSchemaTree(); - final Template template1 = - new Template( - "t1", - Arrays.asList("s1", "s2"), - Arrays.asList(TSDataType.DOUBLE, TSDataType.INT32), - Arrays.asList(TSEncoding.RLE, TSEncoding.RLE), - Arrays.asList(CompressionType.SNAPPY, CompressionType.SNAPPY)); - template1.setId(1); - final Template template2 = - new Template( - "t2", - Arrays.asList("t1", "t2", "t3"), - Arrays.asList(TSDataType.DOUBLE, TSDataType.INT32, TSDataType.INT64), - Arrays.asList(TSEncoding.RLE, TSEncoding.RLE, TSEncoding.RLBE), - Arrays.asList(CompressionType.SNAPPY, CompressionType.SNAPPY, CompressionType.SNAPPY)); - template2.setId(2); - ClusterTemplateManager.getInstance().putTemplate(template1); - ClusterTemplateManager.getInstance().putTemplate(template2); - clusterSchemaTree.appendTemplateDevice(new PartialPath("root.sg1.d1"), false, 1, template1); - clusterSchemaTree.appendTemplateDevice(new PartialPath("root.sg1.d2"), false, 2, template2); - clusterSchemaTree.setDatabases(Collections.singleton("root.sg1")); - clusterSchemaTree.appendSingleMeasurementPath( - new MeasurementPath("root.sg1.d3.s1", TSDataType.FLOAT)); - - TreeDeviceSchemaCacheManager treeDeviceSchemaCacheManager = - TreeDeviceSchemaCacheManager.getInstance(); - treeDeviceSchemaCacheManager.put(clusterSchemaTree); - final ClusterSchemaTree d1Tree = - treeDeviceSchemaCacheManager.getMatchedTemplateSchema(new PartialPath("root.sg1.d1")); - - final String[] ALL_RESULT_NODES = new String[] {"root", "sg1", "**"}; - final PartialPath ALL_MATCH_PATTERN = new PartialPath(ALL_RESULT_NODES); - List measurementPaths = d1Tree.searchMeasurementPaths(ALL_MATCH_PATTERN).left; - return measurementPaths.get(0); - } }