This is an automated email from the ASF dual-hosted git repository. haonan pushed a commit to branch type_execption in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 78b9989fd70082e6910ea34783943df39bd49c9c Author: HTHou <[email protected]> AuthorDate: Tue Jun 14 23:20:58 2022 +0800 [IOTDB-3495] Print detailed error message when insert wrong datatype --- .../metadata/DataTypeMismatchException.java | 11 ++++-- .../metadata/schemaregion/SchemaRegionUtils.java | 8 ++++- .../plan/node/write/InsertMultiTabletsNode.java | 10 ++++++ .../plan/planner/plan/node/write/InsertNode.java | 8 ++++- .../planner/plan/node/write/InsertRowNode.java | 17 +++++++-- .../planner/plan/node/write/InsertRowsNode.java | 10 ++++++ .../plan/node/write/InsertRowsOfOneDeviceNode.java | 10 ++++++ .../planner/plan/node/write/InsertTabletNode.java | 40 ++++++++++++++++++++++ .../qp/physical/crud/InsertMultiTabletsPlan.java | 6 ++++ .../iotdb/db/qp/physical/crud/InsertPlan.java | 2 ++ .../iotdb/db/qp/physical/crud/InsertRowPlan.java | 12 +++++-- .../physical/crud/InsertRowsOfOneDevicePlan.java | 6 ++++ .../iotdb/db/qp/physical/crud/InsertRowsPlan.java | 6 ++++ .../db/qp/physical/crud/InsertTabletPlan.java | 35 +++++++++++++++++++ .../db/wal/recover/file/TsFilePlanRedoer.java | 4 ++- 15 files changed, 173 insertions(+), 12 deletions(-) diff --git a/server/src/main/java/org/apache/iotdb/db/exception/metadata/DataTypeMismatchException.java b/server/src/main/java/org/apache/iotdb/db/exception/metadata/DataTypeMismatchException.java index 189900e6ae..73a2578766 100644 --- a/server/src/main/java/org/apache/iotdb/db/exception/metadata/DataTypeMismatchException.java +++ b/server/src/main/java/org/apache/iotdb/db/exception/metadata/DataTypeMismatchException.java @@ -23,10 +23,15 @@ import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType; public class DataTypeMismatchException extends MetadataException { public DataTypeMismatchException( - String deviceName, String measurementName, TSDataType insertType, TSDataType realType) { + String deviceName, + String measurementName, + TSDataType insertType, + TSDataType realType, + long time, + Object value) { super( String.format( - "DataType mismatch, Insert timeseries %s.%s type %s, metadata tree type %s", - deviceName, measurementName, insertType, realType)); + "data type of %s.%s is not consistent, registered type %s, inserting type %s, timestamp %s, value %s", + deviceName, measurementName, realType, insertType, time, value)); } } diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/schemaregion/SchemaRegionUtils.java b/server/src/main/java/org/apache/iotdb/db/metadata/schemaregion/SchemaRegionUtils.java index 4a8d57613c..7b43d86c20 100644 --- a/server/src/main/java/org/apache/iotdb/db/metadata/schemaregion/SchemaRegionUtils.java +++ b/server/src/main/java/org/apache/iotdb/db/metadata/schemaregion/SchemaRegionUtils.java @@ -84,7 +84,13 @@ public class SchemaRegionUtils { if (dataType != insertDataType) { String measurement = plan.getMeasurements()[loc]; String device = plan.getDevicePath().getFullPath(); - throw new DataTypeMismatchException(device, measurement, insertDataType, dataType); + throw new DataTypeMismatchException( + device, + measurement, + insertDataType, + dataType, + plan.getMinTime(), + plan.getFirstValueOfIndex(loc)); } } diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertMultiTabletsNode.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertMultiTabletsNode.java index 4b9f269302..1d1a0f682b 100644 --- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertMultiTabletsNode.java +++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertMultiTabletsNode.java @@ -313,4 +313,14 @@ public class InsertMultiTabletsNode extends InsertNode implements BatchInsertNod public <R, C> R accept(PlanVisitor<R, C> visitor, C context) { return visitor.visitInsertMultiTablets(this, context); } + + @Override + public long getMinTime() { + throw new NotImplementedException(); + } + + @Override + public Object getFirstValueOfIndex(int index) { + throw new NotImplementedException(); + } } diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertNode.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertNode.java index 92dc6e6e63..aa3f6aaebb 100644 --- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertNode.java +++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertNode.java @@ -242,13 +242,19 @@ public abstract class InsertNode extends WritePlanNode { devicePath.getFullPath(), measurements[i], measurementSchemas[i].getType(), - dataTypes[i])); + dataTypes[i], + getMinTime(), + getFirstValueOfIndex(i))); } } } return true; } + public abstract long getMinTime(); + + public abstract Object getFirstValueOfIndex(int index); + // region partial insert /** * Mark failed measurement, measurements[index], dataTypes[index] and values/columns[index] would diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertRowNode.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertRowNode.java index d5b75c05f0..1fc190e8ed 100644 --- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertRowNode.java +++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertRowNode.java @@ -221,11 +221,12 @@ public class InsertRowNode extends InsertNode implements WALEntryValue { values[i] = CommonUtils.parseValue(dataTypes[i], values[i].toString()); } catch (Exception e) { logger.warn( - "{}.{} data type is not consistent, input {}, registered {}", + "data type of {}.{} is not consistent, registered type {}, inserting timestamp {}, value {}", devicePath, measurements[i], - values[i], - dataTypes[i]); + dataTypes[i], + time, + values[i]); if (!IoTDBDescriptor.getInstance().getConfig().isEnablePartialInsert()) { throw e; } else { @@ -500,6 +501,16 @@ public class InsertRowNode extends InsertNode implements WALEntryValue { } } + @Override + public long getMinTime() { + return getTime(); + } + + @Override + public Object getFirstValueOfIndex(int index) { + throw new NotImplementedException(); + } + // region serialize & deserialize methods for WAL /** Serialized size for wal */ @Override diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertRowsNode.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertRowsNode.java index 9b3d405d8e..509886aa21 100644 --- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertRowsNode.java +++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertRowsNode.java @@ -285,4 +285,14 @@ public class InsertRowsNode extends InsertNode implements BatchInsertNode { public <R, C> R accept(PlanVisitor<R, C> visitor, C context) { return visitor.visitInsertRows(this, context); } + + @Override + public long getMinTime() { + throw new NotImplementedException(); + } + + @Override + public Object getFirstValueOfIndex(int index) { + throw new NotImplementedException(); + } } diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertRowsOfOneDeviceNode.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertRowsOfOneDeviceNode.java index 58c9aeffd9..fc32377954 100644 --- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertRowsOfOneDeviceNode.java +++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertRowsOfOneDeviceNode.java @@ -327,4 +327,14 @@ public class InsertRowsOfOneDeviceNode extends InsertNode implements BatchInsert public <R, C> R accept(PlanVisitor<R, C> visitor, C context) { return visitor.visitInsertRowsOfOneDevice(this, context); } + + @Override + public long getMinTime() { + throw new NotImplementedException(); + } + + @Override + public Object getFirstValueOfIndex(int index) { + throw new NotImplementedException(); + } } diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertTabletNode.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertTabletNode.java index 794520470e..c4c447c039 100644 --- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertTabletNode.java +++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertTabletNode.java @@ -358,6 +358,46 @@ public class InsertTabletNode extends InsertNode implements WALEntryValue { columns[index] = null; } + @Override + public long getMinTime() { + return times[0]; + } + + @Override + public Object getFirstValueOfIndex(int index) { + Object value; + switch (dataTypes[index]) { + case INT32: + int[] intValues = (int[]) columns[index]; + value = intValues[0]; + break; + case INT64: + long[] longValues = (long[]) columns[index]; + value = longValues[0]; + break; + case FLOAT: + float[] floatValues = (float[]) columns[index]; + value = floatValues[0]; + break; + case DOUBLE: + double[] doubleValues = (double[]) columns[index]; + value = doubleValues[0]; + break; + case BOOLEAN: + boolean[] boolValues = (boolean[]) columns[index]; + value = boolValues[0]; + break; + case TEXT: + Binary[] binaryValues = (Binary[]) columns[index]; + value = binaryValues[0]; + break; + default: + throw new UnSupportedDataTypeException( + String.format(DATATYPE_UNSUPPORTED, dataTypes[index])); + } + return value; + } + @Override protected void serializeAttributes(ByteBuffer byteBuffer) { PlanNodeType.INSERT_TABLET.serialize(byteBuffer); diff --git a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertMultiTabletsPlan.java b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertMultiTabletsPlan.java index c649fb1633..d653cfc83d 100644 --- a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertMultiTabletsPlan.java +++ b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertMultiTabletsPlan.java @@ -26,6 +26,7 @@ import org.apache.iotdb.db.conf.IoTDBDescriptor; import org.apache.iotdb.db.exception.query.QueryProcessException; import org.apache.iotdb.db.qp.logical.Operator.OperatorType; import org.apache.iotdb.db.qp.physical.BatchPlan; +import org.apache.iotdb.tsfile.exception.NotImplementedException; import java.io.DataOutputStream; import java.io.IOException; @@ -169,6 +170,11 @@ public class InsertMultiTabletsPlan extends InsertPlan implements BatchPlan { return maxTime; } + @Override + public Object getFirstValueOfIndex(int index) { + throw new NotImplementedException(); + } + public int getTabletsSize() { return insertTabletPlanList.size(); } diff --git a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertPlan.java b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertPlan.java index 3a0caebdfa..f2208dffd9 100644 --- a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertPlan.java +++ b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertPlan.java @@ -123,6 +123,8 @@ public abstract class InsertPlan extends PhysicalPlan { public abstract long getMinTime(); + public abstract Object getFirstValueOfIndex(int index); + /** * This method is overrided in InsertRowPlan and InsertTabletPlan. After marking failed * measurements, the failed values or columns would be null as well. We'd better use diff --git a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertRowPlan.java b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertRowPlan.java index d390935bb5..0e7bc1e7fe 100644 --- a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertRowPlan.java +++ b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertRowPlan.java @@ -251,11 +251,12 @@ public class InsertRowPlan extends InsertPlan implements WALEntryValue { values[i] = CommonUtils.parseValue(dataTypes[i], values[i].toString()); } catch (Exception e) { logger.warn( - "{}.{} data type is not consistent, input {}, registered {}", + "data type of {}.{} is not consistent, registered type {}, inserting timestamp {}, value {}", devicePath, measurements[i], - values[i], - dataTypes[i]); + dataTypes[i], + time, + values[i]); if (IoTDBDescriptor.getInstance().getConfig().isEnablePartialInsert()) { markFailedMeasurementInsertion(i, e); measurementMNodes[i] = null; @@ -272,6 +273,11 @@ public class InsertRowPlan extends InsertPlan implements WALEntryValue { return getTime(); } + @Override + public Object getFirstValueOfIndex(int index) { + return values[index]; + } + @Override public void markFailedMeasurementInsertion(int index, Exception e) { if (measurements[index] == null) { diff --git a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertRowsOfOneDevicePlan.java b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertRowsOfOneDevicePlan.java index 460cce80fe..09bb299f54 100644 --- a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertRowsOfOneDevicePlan.java +++ b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertRowsOfOneDevicePlan.java @@ -24,6 +24,7 @@ import org.apache.iotdb.commons.path.PartialPath; import org.apache.iotdb.db.exception.query.QueryProcessException; import org.apache.iotdb.db.qp.logical.Operator.OperatorType; import org.apache.iotdb.db.qp.physical.BatchPlan; +import org.apache.iotdb.tsfile.exception.NotImplementedException; import java.io.DataOutputStream; import java.io.IOException; @@ -142,6 +143,11 @@ public class InsertRowsOfOneDevicePlan extends InsertPlan implements BatchPlan { return minTime; } + @Override + public Object getFirstValueOfIndex(int index) { + throw new NotImplementedException(); + } + @Override public void serialize(DataOutputStream stream) throws IOException { int type = PhysicalPlanType.BATCH_INSERT_ONE_DEVICE.ordinal(); diff --git a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertRowsPlan.java b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertRowsPlan.java index e6fd8172a7..9faf111599 100644 --- a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertRowsPlan.java +++ b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertRowsPlan.java @@ -25,6 +25,7 @@ import org.apache.iotdb.commons.utils.StatusUtils; import org.apache.iotdb.db.exception.query.QueryProcessException; import org.apache.iotdb.db.qp.logical.Operator.OperatorType; import org.apache.iotdb.db.qp.physical.BatchPlan; +import org.apache.iotdb.tsfile.exception.NotImplementedException; import java.io.DataOutputStream; import java.io.IOException; @@ -79,6 +80,11 @@ public class InsertRowsPlan extends InsertPlan implements BatchPlan { return minTime; } + @Override + public Object getFirstValueOfIndex(int index) { + throw new NotImplementedException(); + } + @Override public List<PartialPath> getPaths() { if (paths != null) { diff --git a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertTabletPlan.java b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertTabletPlan.java index 38c5ee66e6..57e9995c66 100644 --- a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertTabletPlan.java +++ b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertTabletPlan.java @@ -691,6 +691,41 @@ public class InsertTabletPlan extends InsertPlan implements WALEntryValue { return times.length != 0 ? times[times.length - 1] : Long.MAX_VALUE; } + @Override + public Object getFirstValueOfIndex(int index) { + Object value; + switch (dataTypes[index]) { + case INT32: + int[] intValues = (int[]) columns[index]; + value = intValues[0]; + break; + case INT64: + long[] longValues = (long[]) columns[index]; + value = longValues[0]; + break; + case FLOAT: + float[] floatValues = (float[]) columns[index]; + value = floatValues[0]; + break; + case DOUBLE: + double[] doubleValues = (double[]) columns[index]; + value = doubleValues[0]; + break; + case BOOLEAN: + boolean[] boolValues = (boolean[]) columns[index]; + value = boolValues[0]; + break; + case TEXT: + Binary[] binaryValues = (Binary[]) columns[index]; + value = binaryValues[0]; + break; + default: + throw new UnSupportedDataTypeException( + String.format(DATATYPE_UNSUPPORTED, dataTypes[index])); + } + return value; + } + public TimeValuePair composeLastTimeValuePair(int measurementIndex) { if (measurementIndex >= columns.length) { return null; diff --git a/server/src/main/java/org/apache/iotdb/db/wal/recover/file/TsFilePlanRedoer.java b/server/src/main/java/org/apache/iotdb/db/wal/recover/file/TsFilePlanRedoer.java index ad28d86fdb..379008ebb7 100644 --- a/server/src/main/java/org/apache/iotdb/db/wal/recover/file/TsFilePlanRedoer.java +++ b/server/src/main/java/org/apache/iotdb/db/wal/recover/file/TsFilePlanRedoer.java @@ -195,7 +195,9 @@ public class TsFilePlanRedoer { tPlan.getDevicePath().getFullPath(), mNodes[i].getName(), tPlan.getDataTypes()[i], - mNodes[i].getSchema().getType())); + mNodes[i].getSchema().getType(), + tPlan.getMinTime(), + tPlan.getFirstValueOfIndex(i))); } } }
