Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,86 @@ public void testSuccessfullyInvalidateCache() throws SQLException {
cleanData(4);
}

@Test
public void testLastByWithTimeShouldReturnNoRowsAfterDeletingAllData() throws SQLException {
try (Connection connection = EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
Statement statement = connection.createStatement()) {
statement.execute("use test");
statement.execute("create table last_by_delete_0(deviceId string tag, s0 int32 field)");
statement.execute(
"insert into last_by_delete_0(time, deviceId, s0) values (1, 'd0', 1)");
statement.execute("flush");

try (ResultSet resultSet =
statement.executeQuery(
"select last_by(s0, time) from last_by_delete_0 where deviceId = 'd0'")) {
assertTrue(resultSet.next());
}

statement.execute("delete from last_by_delete_0 where deviceId = 'd0'");

try (ResultSet resultSet =
statement.executeQuery(
"select last_by(s0, time) from last_by_delete_0 where deviceId = 'd0'")) {
assertResultSetEmpty(resultSet);
}

try (ResultSet resultSet =
statement.executeQuery(
"select last_by(s0, time) from last_by_delete_0 where deviceId = 'd0'")) {
assertResultSetEmpty(resultSet);
}
}
}

@Test
public void testThreeArgLastByShouldReturnNoRowsAfterDeletingAllData() throws SQLException {
try (Connection connection = EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
Statement statement = connection.createStatement()) {
statement.execute("use test");
statement.execute("create table last_by_delete_1(deviceId string tag, s0 int32 field)");
statement.execute(
"insert into last_by_delete_1(time, deviceId, s0) values (1, 'd0', 1)");
statement.execute("flush");

try (ResultSet resultSet =
statement.executeQuery(
"select last_by(time, s0, time) from last_by_delete_1 where deviceId = 'd0'")) {
assertTrue(resultSet.next());
}

statement.execute("delete from last_by_delete_1 where deviceId = 'd0'");

try (ResultSet resultSet =
statement.executeQuery(
"select last_by(time, s0, time) from last_by_delete_1 where deviceId = 'd0'")) {
assertResultSetEmpty(resultSet);
}

try (ResultSet resultSet =
statement.executeQuery(
"select last_by(time, s0, time) from last_by_delete_1 where deviceId = 'd0'")) {
assertResultSetEmpty(resultSet);
}
}
}

private void assertResultSetEmpty(ResultSet resultSet) throws SQLException {
if (!resultSet.next()) {
return;
}

StringBuilder rowBuilder = new StringBuilder();
int columnCount = resultSet.getMetaData().getColumnCount();
for (int i = 1; i <= columnCount; i++) {
if (i > 1) {
rowBuilder.append(", ");
}
rowBuilder.append(resultSet.getString(i));
}
fail("Expected no rows, but got: " + rowBuilder);
}

@Test
public void testFullDeleteWithoutWhereClause() throws SQLException {
prepareData(5, 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ private static AbstractAlignedTimeSeriesMetadata setModifications(
// deal with time column
List<ModEntry> timeModifications =
context.getPathModifications(
resource, alignedPath.getDeviceId(), timeColumnMetadata.getMeasurementId());
resource, alignedPath.getDeviceId(), AlignedFullPath.VECTOR_PLACEHOLDER);
// all rows are deleted, just return null to skip device data in this file
if (ModificationUtils.isAllDeletedByMods(
timeModifications,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.apache.iotdb.db.queryengine.execution.fragment.DataNodeQueryContext;
import org.apache.iotdb.db.queryengine.execution.operator.process.last.LastQueryUtil;
import org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.LastAccumulator;
import org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.LastByAccumulator;
import org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.LastByDescAccumulator;
import org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.LastDescAccumulator;
import org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.TableAggregator;
Expand Down Expand Up @@ -323,7 +324,9 @@ private void buildResultUseLastValuesCache() {
// when there is no data, no need to append result if the query is GROUP BY or output of
// aggregator is partial (final operator will produce NULL result)
if (timeLastValue == EMPTY_PRIMITIVE_TYPE
&& (groupingKeySize != 0 || tableAggregators.get(0).getStep().isOutputPartial())) {
&& (groupingKeySize != 0
|| tableAggregators.get(0).getStep().isOutputPartial()
|| shouldSkipEmptyLastByResult(currentHitResult))) {
outputDeviceIndex++;
currentHitCacheIndex++;
return;
Expand Down Expand Up @@ -706,7 +709,9 @@ private void checkIfUpdated(

@Override
protected void updateResultTsBlock() {
appendAggregationResult();
if (!shouldSkipEmptyLastByResult()) {
appendAggregationResult();
}

if (needUpdateCache && timeIterator.hasCachedTimeRange()) {
if (lastRowCacheResults != null) {
Expand All @@ -723,6 +728,38 @@ protected void updateResultTsBlock() {
resetTableAggregators();
}

private boolean shouldSkipEmptyLastByResult() {
if (groupingKeySize != 0 || tableAggregators.isEmpty()) {
return false;
}
for (TableAggregator aggregator : tableAggregators) {
if (!(aggregator.getAccumulator() instanceof LastByAccumulator)) {
return false;
}
if (((LastByAccumulator) aggregator.getAccumulator()).hasInitResult()) {
return false;
}
}
return true;
}

private boolean shouldSkipEmptyLastByResult(TimeValuePair[] currentHitResult) {
if (groupingKeySize != 0 || tableAggregators.isEmpty()) {
return false;
}
for (TableAggregator aggregator : tableAggregators) {
if (!(aggregator.getAccumulator() instanceof LastByAccumulator)) {
return false;
}
}
for (TimeValuePair timeValuePair : currentHitResult) {
if (timeValuePair.getValue() != EMPTY_PRIMITIVE_TYPE) {
return false;
}
}
return true;
}

@Override
String getNthIdColumnValue(DeviceEntry deviceEntry, int idColumnIndex) {
// +1 for skipping the table name segment
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ private static boolean areAllValueColumnsDeleted(
for (TimeRange range : valueChunkMetadata.getDeleteIntervalList()) {
if (range.contains(valueChunkMetadata.getStartTime(), valueChunkMetadata.getEndTime())) {
valueChunkMetadataList.set(i, null);
modified = true;
currentRemoved = true;
break;
} else {
Expand Down