Skip to content

Commit 7f574ba

Browse files
authored
Fixed the bug that update / delete devices with no effect may end up changing all the devices
1 parent 02a3880 commit 7f574ba

File tree

10 files changed

+119
-74
lines changed

10 files changed

+119
-74
lines changed

integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBDeviceIT.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,9 @@ public void testDevice() throws SQLException {
226226
e.getMessage());
227227
}
228228

229+
// Test filter with no effect
230+
statement.execute("update table0 set model = null where model = 'A' and model = 'B'");
231+
229232
// Test null
230233
statement.execute("update table0 set model = null where model <> substring(device_id, 1, 1)");
231234
TestUtils.assertResultSetEqual(
@@ -249,6 +252,9 @@ public void testDevice() throws SQLException {
249252
TestUtils.assertResultSetSize(
250253
statement.executeQuery("show devices from table0 offset 1 limit 1"), 1);
251254

255+
// Test delete devices with no effect
256+
statement.execute("delete devices from table0 where region_id = '1' and region_id = '2'");
257+
252258
// Test delete devices
253259
statement.execute("delete devices from table0 where region_id = '1' and plant_id = '木兰'");
254260
TestUtils.assertResultSetSize(statement.executeQuery("show devices from table0"), 1);

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4049,6 +4049,11 @@ public SettableFuture<ConfigTaskResult> dropTable(
40494049
public SettableFuture<ConfigTaskResult> deleteDevice(
40504050
final DeleteDevice deleteDevice, final String queryId, final SessionInfo sessionInfo) {
40514051
final SettableFuture<ConfigTaskResult> future = SettableFuture.create();
4052+
if (!deleteDevice.isMayDeleteDevice()) {
4053+
DeleteDeviceTask.buildTSBlock(0, future);
4054+
return future;
4055+
}
4056+
40524057
try (final ConfigNodeClient client =
40534058
CLUSTER_DELETION_CONFIG_NODE_CLIENT_MANAGER.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) {
40544059

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@ protected Scope visitUpdate(final Update node, final Optional<Scope> context) {
473473
final TranslationMap translationMap = analyzeTraverseDevice(node, context, true);
474474
final TsTable table =
475475
DataNodeTableCache.getInstance().getTable(node.getDatabase(), node.getTableName());
476-
node.parseRawExpression(
476+
if (!node.parseRawExpression(
477477
null,
478478
table,
479479
table.getColumnList().stream()
@@ -482,7 +482,10 @@ protected Scope visitUpdate(final Update node, final Optional<Scope> context) {
482482
columnSchema.getColumnCategory().equals(TsTableColumnCategory.ATTRIBUTE))
483483
.map(TsTableColumnSchema::getColumnName)
484484
.collect(Collectors.toList()),
485-
queryContext);
485+
queryContext)) {
486+
analysis.setFinishQueryAfterAnalyze();
487+
return null;
488+
}
486489

487490
// If node.location is absent, this is a pipe-transferred update, namely the assignments are
488491
// already parsed at the sender

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableDeviceCacheAttributeGuard.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
import java.util.concurrent.LinkedBlockingDeque;
4040
import java.util.stream.Collectors;
4141

42-
import static org.apache.iotdb.db.queryengine.plan.relational.metadata.fetcher.TableDeviceSchemaFetcher.convertIdValuesToDeviceID;
42+
import static org.apache.iotdb.db.queryengine.plan.relational.metadata.fetcher.TableDeviceSchemaFetcher.convertTagValuesToDeviceID;
4343

4444
public class TableDeviceCacheAttributeGuard {
4545

@@ -147,7 +147,7 @@ public void handleContainer(final String database, final UpdateContainer contain
147147
(nodes, attributes) ->
148148
cache.updateAttributes(
149149
database,
150-
convertIdValuesToDeviceID(table, nodes.toArray(new String[0])),
150+
convertTagValuesToDeviceID(table, nodes.toArray(new String[0])),
151151
attributes)));
152152
} else {
153153
((UpdateClearContainer) container)

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableDeviceSchemaFetcher.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ public List<DeviceEntry> fetchDeviceSchemaForDataQuery(
205205
}
206206

207207
// Used by show/count device and update device.
208-
// Update device will not access cache
208+
// Update / Delete device will not access cache
209209
public boolean parseFilter4TraverseDevice(
210210
final String database,
211211
final TsTable tableInstance,
@@ -337,7 +337,7 @@ private boolean tryGetDeviceInCache(
337337
idValues[idFilter.getIndex()] = ((PreciseFilter) childFilter).getValue();
338338
}
339339

340-
final IDeviceID deviceID = convertIdValuesToDeviceID(tableInstance.getTableName(), idValues);
340+
final IDeviceID deviceID = convertTagValuesToDeviceID(tableInstance.getTableName(), idValues);
341341
final Map<String, Binary> attributeMap = cache.getDeviceAttribute(database, deviceID);
342342

343343
// 1. AttributeMap == null means cache miss
@@ -370,7 +370,7 @@ private boolean tryGetDeviceInCache(
370370
return true;
371371
}
372372

373-
public static IDeviceID convertIdValuesToDeviceID(
373+
public static IDeviceID convertTagValuesToDeviceID(
374374
final String tableName, final String[] idValues) {
375375
// Convert to IDeviceID
376376
final String[] deviceIdNodes = new String[idValues.length + 1];

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableDeviceSchemaValidator.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
import java.util.Objects;
4747
import java.util.stream.Collectors;
4848

49-
import static org.apache.iotdb.db.queryengine.plan.relational.metadata.fetcher.TableDeviceSchemaFetcher.convertIdValuesToDeviceID;
49+
import static org.apache.iotdb.db.queryengine.plan.relational.metadata.fetcher.TableDeviceSchemaFetcher.convertTagValuesToDeviceID;
5050

5151
public class TableDeviceSchemaValidator {
5252
private final SqlParser relationSqlParser = new SqlParser();
@@ -127,7 +127,7 @@ private ValidateResult validateDeviceSchemaInCache(
127127
TableDeviceSchemaCache.getInstance()
128128
.getDeviceAttribute(
129129
schemaValidation.getDatabase(),
130-
convertIdValuesToDeviceID(
130+
convertTagValuesToDeviceID(
131131
schemaValidation.getTableName(), (String[]) deviceIdList.get(i)));
132132
if (attributeMap == null) {
133133
result.missingDeviceIndexList.add(i);
@@ -165,7 +165,7 @@ private ValidateResult fetchAndValidateDeviceSchema(
165165
for (final int index : previousValidateResult.missingDeviceIndexList) {
166166
final Map<String, Binary> attributeMap =
167167
fetchedDeviceSchema.get(
168-
convertIdValuesToDeviceID(
168+
convertTagValuesToDeviceID(
169169
schemaValidation.getTableName(), (String[]) deviceIdList.get(index)));
170170
if (attributeMap == null) {
171171
result.missingDeviceIndexList.add(index);

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/DeleteDevice.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.apache.iotdb.commons.schema.filter.SchemaFilter;
2525
import org.apache.iotdb.commons.schema.table.TsTable;
2626
import org.apache.iotdb.commons.schema.table.column.TsTableColumnSchema;
27+
import org.apache.iotdb.db.queryengine.common.MPPQueryContext;
2728
import org.apache.iotdb.db.queryengine.common.SessionInfo;
2829
import org.apache.iotdb.db.queryengine.execution.operator.schema.source.DeviceBlackListConstructor;
2930
import org.apache.iotdb.db.queryengine.execution.operator.schema.source.TableDeviceQuerySource;
@@ -32,6 +33,7 @@
3233
import org.apache.iotdb.db.queryengine.plan.analyze.TypeProvider;
3334
import org.apache.iotdb.db.queryengine.plan.planner.LocalExecutionPlanner;
3435
import org.apache.iotdb.db.queryengine.plan.planner.plan.parameter.InputLocation;
36+
import org.apache.iotdb.db.queryengine.plan.relational.metadata.DeviceEntry;
3537
import org.apache.iotdb.db.queryengine.plan.relational.metadata.Metadata;
3638
import org.apache.iotdb.db.queryengine.plan.relational.planner.Symbol;
3739
import org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
@@ -65,13 +67,27 @@ public class DeleteDevice extends AbstractTraverseDevice {
6567

6668
// Used for data deletion
6769
private List<TableDeletionEntry> modEntries;
70+
private boolean mayDeleteDevice;
6871

6972
public DeleteDevice(final NodeLocation location, final Table table, final Expression where) {
7073
super(location, table, where);
7174
}
7275

76+
@Override
77+
public boolean parseRawExpression(
78+
final List<DeviceEntry> entries,
79+
final TsTable tableInstance,
80+
final List<String> attributeColumns,
81+
final MPPQueryContext context) {
82+
return mayDeleteDevice =
83+
super.parseRawExpression(entries, tableInstance, attributeColumns, context);
84+
}
85+
86+
public boolean isMayDeleteDevice() {
87+
return mayDeleteDevice;
88+
}
89+
7390
public void parseModEntries(final TsTable table) {
74-
// TODO: Fallback to precise devices if modEnries parsing failure encountered
7591
modEntries = AnalyzeUtils.parseExpressions2ModEntries(where, table);
7692
}
7793

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/impl/SchemaRegionMemoryImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@
152152
import java.util.stream.Collectors;
153153

154154
import static org.apache.iotdb.db.queryengine.plan.planner.TableOperatorGenerator.makeLayout;
155-
import static org.apache.iotdb.db.queryengine.plan.relational.metadata.fetcher.TableDeviceSchemaFetcher.convertIdValuesToDeviceID;
155+
import static org.apache.iotdb.db.queryengine.plan.relational.metadata.fetcher.TableDeviceSchemaFetcher.convertTagValuesToDeviceID;
156156
import static org.apache.tsfile.common.constant.TsFileConstant.PATH_SEPARATOR;
157157

158158
/**
@@ -1449,7 +1449,7 @@ private void updateAttribute(
14491449
if (!isRecovering) {
14501450
TableDeviceSchemaCache.getInstance()
14511451
.updateAttributes(
1452-
databaseName, convertIdValuesToDeviceID(tableName, deviceId), resultMap);
1452+
databaseName, convertTagValuesToDeviceID(tableName, deviceId), resultMap);
14531453
}
14541454
deviceAttributeCacheUpdater.update(tableName, deviceId, resultMap);
14551455
}

0 commit comments

Comments
 (0)