diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertMultiTabletsStatement.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertMultiTabletsStatement.java index 0ccd115fb2e9..d36615ea3921 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertMultiTabletsStatement.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertMultiTabletsStatement.java @@ -22,7 +22,6 @@ import org.apache.iotdb.commons.conf.CommonDescriptor; import org.apache.iotdb.commons.exception.SemanticException; import org.apache.iotdb.commons.path.PartialPath; -import org.apache.iotdb.db.queryengine.common.MPPQueryContext; import org.apache.iotdb.db.queryengine.plan.analyze.schema.ISchemaValidation; import org.apache.iotdb.db.queryengine.plan.statement.StatementType; import org.apache.iotdb.db.queryengine.plan.statement.StatementVisitor; @@ -110,12 +109,45 @@ public List getSchemaValidationList() { } @Override - public void updateAfterSchemaValidation(MPPQueryContext context) { - for (InsertTabletStatement insertTabletStatement : insertTabletStatementList) { - if (!this.hasFailedMeasurements() && insertTabletStatement.hasFailedMeasurements()) { - this.failedMeasurementIndex2Info = insertTabletStatement.failedMeasurementIndex2Info; - } - } + public boolean hasFailedMeasurements() { + return insertTabletStatementList != null + && insertTabletStatementList.stream().anyMatch(InsertBaseStatement::hasFailedMeasurements); + } + + @Override + public int getFailedMeasurementNumber() { + return insertTabletStatementList == null + ? 0 + : insertTabletStatementList.stream() + .mapToInt(InsertBaseStatement::getFailedMeasurementNumber) + .sum(); + } + + @Override + public List getFailedMeasurements() { + return insertTabletStatementList == null + ? Collections.emptyList() + : insertTabletStatementList.stream() + .flatMap(statement -> statement.getFailedMeasurements().stream()) + .collect(Collectors.toList()); + } + + @Override + public List getFailedExceptions() { + return insertTabletStatementList == null + ? Collections.emptyList() + : insertTabletStatementList.stream() + .flatMap(statement -> statement.getFailedExceptions().stream()) + .collect(Collectors.toList()); + } + + @Override + public List getFailedMessages() { + return insertTabletStatementList == null + ? Collections.emptyList() + : insertTabletStatementList.stream() + .flatMap(statement -> statement.getFailedMessages().stream()) + .collect(Collectors.toList()); } @Override diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertRowsOfOneDeviceStatement.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertRowsOfOneDeviceStatement.java index bfae0797a4aa..4b6d8de840d3 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertRowsOfOneDeviceStatement.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertRowsOfOneDeviceStatement.java @@ -36,6 +36,7 @@ import org.apache.tsfile.utils.RamUsageEstimator; import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Objects; @@ -140,12 +141,51 @@ public List getSchemaValidationList() { public void updateAfterSchemaValidation(MPPQueryContext context) throws QueryProcessException { for (InsertRowStatement insertRowStatement : insertRowStatementList) { insertRowStatement.updateAfterSchemaValidation(context); - if (!this.hasFailedMeasurements() && insertRowStatement.hasFailedMeasurements()) { - this.failedMeasurementIndex2Info = insertRowStatement.failedMeasurementIndex2Info; - } } } + @Override + public boolean hasFailedMeasurements() { + return insertRowStatementList != null + && insertRowStatementList.stream().anyMatch(InsertBaseStatement::hasFailedMeasurements); + } + + @Override + public int getFailedMeasurementNumber() { + return insertRowStatementList == null + ? 0 + : insertRowStatementList.stream() + .mapToInt(InsertBaseStatement::getFailedMeasurementNumber) + .sum(); + } + + @Override + public List getFailedMeasurements() { + return insertRowStatementList == null + ? Collections.emptyList() + : insertRowStatementList.stream() + .flatMap(statement -> statement.getFailedMeasurements().stream()) + .collect(Collectors.toList()); + } + + @Override + public List getFailedExceptions() { + return insertRowStatementList == null + ? Collections.emptyList() + : insertRowStatementList.stream() + .flatMap(statement -> statement.getFailedExceptions().stream()) + .collect(Collectors.toList()); + } + + @Override + public List getFailedMessages() { + return insertRowStatementList == null + ? Collections.emptyList() + : insertRowStatementList.stream() + .flatMap(statement -> statement.getFailedMessages().stream()) + .collect(Collectors.toList()); + } + @Override protected boolean checkAndCastDataType(int columnIndex, TSDataType dataType) { return false; diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertRowsStatement.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertRowsStatement.java index 01f07a6c7540..890a1f5787c4 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertRowsStatement.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertRowsStatement.java @@ -132,12 +132,51 @@ public List getSchemaValidationList() { public void updateAfterSchemaValidation(MPPQueryContext context) throws QueryProcessException { for (InsertRowStatement insertRowStatement : insertRowStatementList) { insertRowStatement.updateAfterSchemaValidation(context); - if (!this.hasFailedMeasurements() && insertRowStatement.hasFailedMeasurements()) { - this.failedMeasurementIndex2Info = insertRowStatement.failedMeasurementIndex2Info; - } } } + @Override + public boolean hasFailedMeasurements() { + return insertRowStatementList != null + && insertRowStatementList.stream().anyMatch(InsertBaseStatement::hasFailedMeasurements); + } + + @Override + public int getFailedMeasurementNumber() { + return insertRowStatementList == null + ? 0 + : insertRowStatementList.stream() + .mapToInt(InsertBaseStatement::getFailedMeasurementNumber) + .sum(); + } + + @Override + public List getFailedMeasurements() { + return insertRowStatementList == null + ? Collections.emptyList() + : insertRowStatementList.stream() + .flatMap(statement -> statement.getFailedMeasurements().stream()) + .collect(Collectors.toList()); + } + + @Override + public List getFailedExceptions() { + return insertRowStatementList == null + ? Collections.emptyList() + : insertRowStatementList.stream() + .flatMap(statement -> statement.getFailedExceptions().stream()) + .collect(Collectors.toList()); + } + + @Override + public List getFailedMessages() { + return insertRowStatementList == null + ? Collections.emptyList() + : insertRowStatementList.stream() + .flatMap(statement -> statement.getFailedMessages().stream()) + .collect(Collectors.toList()); + } + @Override protected boolean checkAndCastDataType(int columnIndex, TSDataType dataType) { return false; diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertStatementPartialInsertTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertStatementPartialInsertTest.java index b6b26cacc8ec..228737fd4563 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertStatementPartialInsertTest.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertStatementPartialInsertTest.java @@ -287,6 +287,58 @@ public void testDeviceMeasurementMapSkipsMissingTabletColumns() throws Exception Assert.assertEquals("s1", result.get(statement.getDevicePath()).get(0).left); } + @Test + public void testInsertRowsStatementAggregatesFailedMeasurements() throws Exception { + final InsertRowStatement statement1 = createInsertRowStatement(); + final InsertRowStatement statement2 = createInsertRowStatement(); + statement1.markFailedMeasurement(0, new RuntimeException("failed1")); + statement2.markFailedMeasurement(1, new RuntimeException("failed2")); + + final InsertRowsStatement rowsStatement = new InsertRowsStatement(); + rowsStatement.setInsertRowStatementList(Arrays.asList(statement1, statement2)); + + Assert.assertTrue(rowsStatement.hasFailedMeasurements()); + Assert.assertEquals(2, rowsStatement.getFailedMeasurementNumber()); + Assert.assertEquals(Arrays.asList("s1", "s2"), rowsStatement.getFailedMeasurements()); + Assert.assertEquals(Arrays.asList("failed1", "failed2"), rowsStatement.getFailedMessages()); + } + + @Test + public void testInsertRowsOfOneDeviceStatementAggregatesFailedMeasurements() throws Exception { + final InsertRowStatement statement1 = createInsertRowStatement(); + final InsertRowStatement statement2 = createInsertRowStatement(); + statement1.markFailedMeasurement(0, new RuntimeException("failed1")); + statement2.markFailedMeasurement(1, new RuntimeException("failed2")); + + final InsertRowsOfOneDeviceStatement rowsOfOneDeviceStatement = + new InsertRowsOfOneDeviceStatement(); + rowsOfOneDeviceStatement.setInsertRowStatementList(Arrays.asList(statement1, statement2)); + + Assert.assertTrue(rowsOfOneDeviceStatement.hasFailedMeasurements()); + Assert.assertEquals(2, rowsOfOneDeviceStatement.getFailedMeasurementNumber()); + Assert.assertEquals( + Arrays.asList("s1", "s2"), rowsOfOneDeviceStatement.getFailedMeasurements()); + Assert.assertEquals( + Arrays.asList("failed1", "failed2"), rowsOfOneDeviceStatement.getFailedMessages()); + } + + @Test + public void testInsertMultiTabletsStatementAggregatesFailedMeasurements() throws Exception { + final InsertTabletStatement statement1 = createInsertTabletStatement(); + final InsertTabletStatement statement2 = createInsertTabletStatement(); + statement1.markFailedMeasurement(0, new RuntimeException("failed1")); + statement2.markFailedMeasurement(1, new RuntimeException("failed2")); + + final InsertMultiTabletsStatement multiTabletsStatement = new InsertMultiTabletsStatement(); + multiTabletsStatement.setInsertTabletStatementList(Arrays.asList(statement1, statement2)); + + Assert.assertTrue(multiTabletsStatement.hasFailedMeasurements()); + Assert.assertEquals(2, multiTabletsStatement.getFailedMeasurementNumber()); + Assert.assertEquals(Arrays.asList("s1", "s2"), multiTabletsStatement.getFailedMeasurements()); + Assert.assertEquals( + Arrays.asList("failed1", "failed2"), multiTabletsStatement.getFailedMessages()); + } + private static InsertRowStatement createInsertRowStatement() throws Exception { final InsertRowStatement statement = new InsertRowStatement(); statement.setDevicePath(new PartialPath("root.sg.d1"));