This is an automated email from the ASF dual-hosted git repository. jackietien pushed a commit to branch IOTDB-3364-013 in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 24366dd70ea904c7575858a2ef96fb73b2d1ed91 Author: JackieTien97 <[email protected]> AuthorDate: Wed Jun 1 17:30:40 2022 +0800 [To rel/0.13] [IOTDB-3364] Fix Query stucked with null valued aligned timeseries bug --- .../db/integration/aligned/IoTDBEmptyDataIT.java | 85 ++++++++++++++++++++++ .../querycontext/AlignedReadOnlyMemChunk.java | 15 ++-- .../file/metadata/statistics/Statistics.java | 21 +++--- .../file/metadata/statistics/TimeStatistics.java | 14 ++++ 4 files changed, 121 insertions(+), 14 deletions(-) diff --git a/integration/src/test/java/org/apache/iotdb/db/integration/aligned/IoTDBEmptyDataIT.java b/integration/src/test/java/org/apache/iotdb/db/integration/aligned/IoTDBEmptyDataIT.java new file mode 100644 index 0000000000..12daea27aa --- /dev/null +++ b/integration/src/test/java/org/apache/iotdb/db/integration/aligned/IoTDBEmptyDataIT.java @@ -0,0 +1,85 @@ +/* + * 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.integration.aligned; + +import org.apache.iotdb.db.utils.EnvironmentUtils; +import org.apache.iotdb.itbase.category.LocalStandaloneTest; +import org.apache.iotdb.jdbc.Config; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +@Category({LocalStandaloneTest.class}) +public class IoTDBEmptyDataIT { + + @BeforeClass + public static void setUp() throws Exception { + EnvironmentUtils.envSetUp(); + Class.forName(Config.JDBC_DRIVER_NAME); + try (Connection connection = + DriverManager.getConnection( + Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root"); + Statement statement = connection.createStatement()) { + + statement.execute("create aligned timeseries root.sg.d1(s1 int32);"); + statement.execute("insert into root.sg.d1(time, s1) aligned values(1400, null); "); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @AfterClass + public static void tearDown() throws Exception { + EnvironmentUtils.cleanEnv(); + } + + @Test + public void selectAllAlignedWithoutValueFilterTest() throws ClassNotFoundException { + + Class.forName(Config.JDBC_DRIVER_NAME); + try (Connection connection = + DriverManager.getConnection( + Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root"); + Statement statement = connection.createStatement()) { + + try (ResultSet resultSet = statement.executeQuery("select * from root.sg.d1")) { + int cnt = 0; + while (resultSet.next()) { + cnt++; + } + assertEquals(0, cnt); + } + + } catch (SQLException e) { + e.printStackTrace(); + fail(e.getMessage()); + } + } +} diff --git a/server/src/main/java/org/apache/iotdb/db/engine/querycontext/AlignedReadOnlyMemChunk.java b/server/src/main/java/org/apache/iotdb/db/engine/querycontext/AlignedReadOnlyMemChunk.java index 781311a56a..5e44026dbb 100644 --- a/server/src/main/java/org/apache/iotdb/db/engine/querycontext/AlignedReadOnlyMemChunk.java +++ b/server/src/main/java/org/apache/iotdb/db/engine/querycontext/AlignedReadOnlyMemChunk.java @@ -117,12 +117,8 @@ public class AlignedReadOnlyMemChunk extends ReadOnlyMemChunk { lastValidPointIndexForTimeDupCheck = new Pair<>(Long.MIN_VALUE, null); } Statistics valueStatistics = Statistics.getStatsByType(dataTypeList.get(column)); - IChunkMetadata valueChunkMetadata = - new ChunkMetadata( - measurementList.get(column), dataTypeList.get(column), 0, valueStatistics); - valueChunkMetadataList.add(valueChunkMetadata); if (alignedChunkData.getValues().get(column) == null) { - valueStatistics.setEmpty(true); + valueChunkMetadataList.add(null); continue; } for (int row = 0; row < alignedChunkData.rowCount(); row++) { @@ -184,6 +180,15 @@ public class AlignedReadOnlyMemChunk extends ReadOnlyMemChunk { throw new QueryProcessException("Unsupported data type:" + dataType); } } + if (valueStatistics.getCount() > 0) { + IChunkMetadata valueChunkMetadata = + new ChunkMetadata( + measurementList.get(column), dataTypeList.get(column), 0, valueStatistics); + valueChunkMetadataList.add(valueChunkMetadata); + valueStatistics.setEmpty(false); + } else { + valueChunkMetadataList.add(null); + } valueStatistics.setEmpty(false); } IChunkMetadata vectorChunkMetadata = diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/Statistics.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/Statistics.java index a9fcec1b2a..ba42bccea9 100644 --- a/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/Statistics.java +++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/Statistics.java @@ -155,16 +155,19 @@ public abstract class Statistics<T extends Serializable> { @SuppressWarnings("unchecked") public void mergeStatistics(Statistics<? extends Serializable> stats) { if (this.getClass() == stats.getClass()) { - if (stats.startTime < this.startTime) { - this.startTime = stats.startTime; + if (!stats.isEmpty) { + if (stats.startTime < this.startTime) { + this.startTime = stats.startTime; + } + if (stats.endTime > this.endTime) { + this.endTime = stats.endTime; + } + + // must be sure no overlap between two statistics + this.count += stats.count; + mergeStatisticsValue((Statistics<T>) stats); + isEmpty = false; } - if (stats.endTime > this.endTime) { - this.endTime = stats.endTime; - } - // must be sure no overlap between two statistics - this.count += stats.count; - mergeStatisticsValue((Statistics<T>) stats); - isEmpty = false; } else { Class<?> thisClass = this.getClass(); Class<?> statsClass = stats.getClass(); diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/TimeStatistics.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/TimeStatistics.java index adc967ecc7..33fcad15cb 100644 --- a/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/TimeStatistics.java +++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/file/metadata/statistics/TimeStatistics.java @@ -45,6 +45,20 @@ public class TimeStatistics extends Statistics<Long> { return 0; } + @Override + public void update(long time) { + super.update(time); + setEmpty(false); + } + + @Override + public void update(long[] time, int batchSize) { + super.update(time, batchSize); + if (batchSize > 0) { + setEmpty(false); + } + } + @Override public Long getMinValue() { throw new StatisticsClassException(String.format(STATS_UNSUPPORTED_MSG, TIME, "min value"));
