From 52c9929019cf2d75d92cdf267ec27271e45012b5 Mon Sep 17 00:00:00 2001 From: Tom Date: Tue, 25 Jun 2024 13:42:52 -0700 Subject: [PATCH] Column name in parse exceptions (#16529) * first pass * more changes * fix tests and formatting * fix kinesis failing tests * fix kafka tests * add dimension name to float parse errors * double and convertToType handling of dimensionName can report parse errors with dimension name * fix checkstyle issue * fix tests * more cases to have better parse exception messages * fix test * fix tests * partially address comments * annotate method parameter with nullable * address comments * fix tests * let float, double, long dimensionIndexer pass dimensionName down to dimensionHandlerUtils * fix compilation error and clean up formatting * clean up whitespace * address feedback. undo change, pass down report parse exception for convertToType * fix test --- .../indexing/kafka/KafkaIndexTaskTest.java | 4 +- .../kinesis/KinesisIndexTaskTest.java | 4 +- .../druid/indexer/InputRowSerdeTest.java | 6 +- .../indexing/common/task/IndexTaskTest.java | 4 +- .../druid/segment/DimensionHandlerUtils.java | 267 ++++++++++++++---- .../druid/segment/DoubleDimensionHandler.java | 2 +- .../druid/segment/DoubleDimensionIndexer.java | 14 +- .../druid/segment/FloatDimensionHandler.java | 2 +- .../druid/segment/FloatDimensionIndexer.java | 14 +- .../druid/segment/LongDimensionHandler.java | 2 +- .../druid/segment/LongDimensionIndexer.java | 14 +- .../incremental/IncrementalIndexTest.java | 12 +- .../druid/sql/calcite/run/SqlResults.java | 6 +- 13 files changed, 272 insertions(+), 79 deletions(-) diff --git a/extensions-core/kafka-indexing-service/src/test/java/org/apache/druid/indexing/kafka/KafkaIndexTaskTest.java b/extensions-core/kafka-indexing-service/src/test/java/org/apache/druid/indexing/kafka/KafkaIndexTaskTest.java index 1309ed0dde0b..58f982e71b4f 100644 --- a/extensions-core/kafka-indexing-service/src/test/java/org/apache/druid/indexing/kafka/KafkaIndexTaskTest.java +++ b/extensions-core/kafka-indexing-service/src/test/java/org/apache/druid/indexing/kafka/KafkaIndexTaskTest.java @@ -1634,8 +1634,8 @@ public void testMultipleParseExceptionsSuccess() throws Exception List expectedMessages = Arrays.asList( "Unable to parse value[notanumber] for field[met1]", - "could not convert value [notanumber] to float", - "could not convert value [notanumber] to long", + "Could not convert value [notanumber] to float for dimension [dimFloat].", + "Could not convert value [notanumber] to long for dimension [dimLong].", "Unable to parse [] as the intermediateRow resulted in empty input row (Record: 1)", "Unable to parse row [unparseable] (Record: 1)", "Encountered row with timestamp[246140482-04-24T15:36:27.903Z] that cannot be represented as a long: [{timestamp=246140482-04-24T15:36:27.903Z, dim1=x, dim2=z, dimLong=10, dimFloat=20.0, met1=1.0}] (Record: 1)" diff --git a/extensions-core/kinesis-indexing-service/src/test/java/org/apache/druid/indexing/kinesis/KinesisIndexTaskTest.java b/extensions-core/kinesis-indexing-service/src/test/java/org/apache/druid/indexing/kinesis/KinesisIndexTaskTest.java index c1adf018b216..527a6738ffe9 100644 --- a/extensions-core/kinesis-indexing-service/src/test/java/org/apache/druid/indexing/kinesis/KinesisIndexTaskTest.java +++ b/extensions-core/kinesis-indexing-service/src/test/java/org/apache/druid/indexing/kinesis/KinesisIndexTaskTest.java @@ -1201,8 +1201,8 @@ public void testMultipleParseExceptionsSuccess() throws Exception List expectedMessages = Arrays.asList( "Unable to parse value[notanumber] for field[met1]", - "could not convert value [notanumber] to float", - "could not convert value [notanumber] to long", + "Could not convert value [notanumber] to float for dimension [dimFloat].", + "Could not convert value [notanumber] to long for dimension [dimLong].", "Timestamp[null] is unparseable! Event: {} (Record: 1)", "Unable to parse [] as the intermediateRow resulted in empty input row (Record: 1)", "Unable to parse row [unparseable] (Record: 1)", diff --git a/indexing-hadoop/src/test/java/org/apache/druid/indexer/InputRowSerdeTest.java b/indexing-hadoop/src/test/java/org/apache/druid/indexer/InputRowSerdeTest.java index 31891c04dd34..4ff03c77e95d 100644 --- a/indexing-hadoop/src/test/java/org/apache/druid/indexer/InputRowSerdeTest.java +++ b/indexing-hadoop/src/test/java/org/apache/druid/indexer/InputRowSerdeTest.java @@ -220,7 +220,7 @@ public void testDimensionParseExceptions() ); result = InputRowSerde.toBytes(InputRowSerde.getTypeHelperMap(dimensionsSpec), in, aggregatorFactories); Assert.assertEquals( - Collections.singletonList("could not convert value [d1v] to long"), + Collections.singletonList("Could not convert value [d1v] to long."), result.getParseExceptionMessages() ); @@ -231,7 +231,7 @@ public void testDimensionParseExceptions() ); result = InputRowSerde.toBytes(InputRowSerde.getTypeHelperMap(dimensionsSpec), in, aggregatorFactories); Assert.assertEquals( - Collections.singletonList("could not convert value [d1v] to float"), + Collections.singletonList("Could not convert value [d1v] to float."), result.getParseExceptionMessages() ); @@ -242,7 +242,7 @@ public void testDimensionParseExceptions() ); result = InputRowSerde.toBytes(InputRowSerde.getTypeHelperMap(dimensionsSpec), in, aggregatorFactories); Assert.assertEquals( - Collections.singletonList("could not convert value [d1v] to double"), + Collections.singletonList("Could not convert value [d1v] to double."), result.getParseExceptionMessages() ); } diff --git a/indexing-service/src/test/java/org/apache/druid/indexing/common/task/IndexTaskTest.java b/indexing-service/src/test/java/org/apache/druid/indexing/common/task/IndexTaskTest.java index f0e0198e35b0..1a5cf19a21a6 100644 --- a/indexing-service/src/test/java/org/apache/druid/indexing/common/task/IndexTaskTest.java +++ b/indexing-service/src/test/java/org/apache/druid/indexing/common/task/IndexTaskTest.java @@ -1603,8 +1603,8 @@ public void testMultipleParseExceptionsSuccess() throws Exception tmpFile.toURI() ), "Unable to parse value[notnumber] for field[val]", - "could not convert value [notnumber] to float", - "could not convert value [notnumber] to long", + "Could not convert value [notnumber] to float for dimension [dimFloat].", + "Could not convert value [notnumber] to long for dimension [dimLong].", StringUtils.format( "Timestamp[unparseable] is unparseable! Event: {time=unparseable, dim=a, dimLong=2, dimFloat=3.0, val=1} (Path: %s, Record: 1, Line: 1)", tmpFile.toURI() diff --git a/processing/src/main/java/org/apache/druid/segment/DimensionHandlerUtils.java b/processing/src/main/java/org/apache/druid/segment/DimensionHandlerUtils.java index da63413cb4ba..e129ceb41778 100644 --- a/processing/src/main/java/org/apache/druid/segment/DimensionHandlerUtils.java +++ b/processing/src/main/java/org/apache/druid/segment/DimensionHandlerUtils.java @@ -28,6 +28,7 @@ import org.apache.druid.error.DruidException; import org.apache.druid.java.util.common.IAE; import org.apache.druid.java.util.common.ISE; +import org.apache.druid.java.util.common.StringUtils; import org.apache.druid.java.util.common.parsers.ParseException; import org.apache.druid.math.expr.Evals; import org.apache.druid.query.ColumnSelectorPlus; @@ -309,13 +310,11 @@ public static String convertObjectToString(@Nullable Object valObj) } @Nullable - public static Long convertObjectToLong(@Nullable Object valObj) - { - return convertObjectToLong(valObj, false); - } - - @Nullable - public static Long convertObjectToLong(@Nullable Object valObj, boolean reportParseExceptions) + public static Long convertObjectToLong( + @Nullable Object valObj, + boolean reportParseExceptions, + @Nullable String objectKey + ) { if (valObj == null) { return null; @@ -330,25 +329,82 @@ public static Long convertObjectToLong(@Nullable Object valObj, boolean reportPa } else if (valObj instanceof String) { Long ret = DimensionHandlerUtils.getExactLongFromDecimalString((String) valObj); if (reportParseExceptions && ret == null) { - throw new ParseException((String) valObj, "could not convert value [%s] to long", valObj); + final String message; + if (objectKey != null) { + message = StringUtils.nonStrictFormat( + "Could not convert value [%s] to long for dimension [%s].", + valObj, + objectKey + ); + } else { + message = StringUtils.nonStrictFormat( + "Could not convert value [%s] to long.", + valObj + ); + } + throw new ParseException((String) valObj, message); } return ret; } else if (valObj instanceof List) { + final String message; + if (objectKey != null) { + message = StringUtils.nonStrictFormat( + "Could not ingest value [%s] as long for dimension [%s]. A long column cannot have multiple values in the same row.", + valObj, + objectKey + ); + } else { + message = StringUtils.nonStrictFormat( + "Could not ingest value [%s] as long. A long column cannot have multiple values in the same row.", + valObj + ); + } throw new ParseException( valObj.getClass().toString(), - "Could not ingest value %s as long. A long column cannot have multiple values in the same row.", - valObj + message ); } else { + final String message; + if (objectKey != null) { + message = StringUtils.nonStrictFormat( + "Could not convert value [%s] to long for dimension [%s]. Invalid type: [%s]", + valObj, + objectKey, + valObj.getClass() + ); + } else { + message = StringUtils.nonStrictFormat( + valObj.getClass().toString(), + "Could not convert value [%s] to long. Invalid type: [%s]", + valObj, + valObj.getClass() + ); + } throw new ParseException( valObj.getClass().toString(), - "Could not convert value [%s] to long. Invalid type: [%s]", - valObj, - valObj.getClass() + message ); } } + @Nullable + public static Long convertObjectToLong(@Nullable Object valObj) + { + return convertObjectToLong(valObj, false); + } + + @Nullable + public static Long convertObjectToLong(@Nullable Object valObj, boolean reportParseExceptions) + { + return convertObjectToLong(valObj, reportParseExceptions, null); + } + + @Nullable + public static Long convertObjectToLong(@Nullable Object valObj, @Nullable String fieldName) + { + return convertObjectToLong(valObj, false, fieldName); + } + @Nullable public static Float convertObjectToFloat(@Nullable Object valObj) { @@ -358,33 +414,85 @@ public static Float convertObjectToFloat(@Nullable Object valObj) @Nullable public static Float convertObjectToFloat(@Nullable Object valObj, boolean reportParseExceptions) { - if (valObj == null) { - return null; - } + return convertObjectToFloat(valObj, reportParseExceptions, null); + } - if (valObj instanceof Float) { - return (Float) valObj; - } else if (valObj instanceof Number) { - return ((Number) valObj).floatValue(); - } else if (valObj instanceof String) { - Float ret = Floats.tryParse((String) valObj); - if (reportParseExceptions && ret == null) { - throw new ParseException((String) valObj, "could not convert value [%s] to float", valObj); + @Nullable + public static Float convertObjectToFloat(@Nullable Object valObj, @Nullable String fieldName) + { + return convertObjectToFloat(valObj, false, fieldName); + } + + @Nullable + public static Float convertObjectToFloat(@Nullable Object valObj, boolean reportParseExceptions, @Nullable String fieldName) + { + { + if (valObj == null) { + return null; + } + + if (valObj instanceof Float) { + return (Float) valObj; + } else if (valObj instanceof Number) { + return ((Number) valObj).floatValue(); + } else if (valObj instanceof String) { + Float ret = Floats.tryParse((String) valObj); + if (reportParseExceptions && ret == null) { + final String message; + if (fieldName != null) { + message = StringUtils.nonStrictFormat( + "Could not convert value [%s] to float for dimension [%s].", + valObj, + fieldName + ); + } else { + message = StringUtils.nonStrictFormat( + "Could not convert value [%s] to float.", + valObj + ); + } + throw new ParseException((String) valObj, message); + } + return ret; + } else if (valObj instanceof List) { + final String message; + if (fieldName != null) { + message = StringUtils.nonStrictFormat( + "Could not ingest value [%s] as float for dimension [%s]. A float column cannot have multiple values in the same row.", + valObj, + fieldName + ); + } else { + message = StringUtils.nonStrictFormat( + "Could not ingest value [%s] as float. A float column cannot have multiple values in the same row.", + valObj + ); + } + throw new ParseException( + valObj.getClass().toString(), + message + ); + } else { + final String message; + if (fieldName != null) { + message = StringUtils.nonStrictFormat( + "Could not convert value [%s] to float for dimension [%s]. Invalid type: [%s]", + valObj, + fieldName, + valObj.getClass() + ); + } else { + message = StringUtils.nonStrictFormat( + "Could not convert value [%s] to float. Invalid type: [%s]", + valObj, + valObj.getClass() + ); + } + throw new ParseException( + valObj.getClass().toString(), + message + ); } - return ret; - } else if (valObj instanceof List) { - throw new ParseException( - valObj.getClass().toString(), - "Could not ingest value %s as float. A float column cannot have multiple values in the same row.", - valObj - ); - } else { - throw new ParseException( - valObj.getClass().toString(), - "Could not convert value [%s] to float. Invalid type: [%s]", - valObj, - valObj.getClass() - ); } } @@ -392,24 +500,25 @@ public static Float convertObjectToFloat(@Nullable Object valObj, boolean report public static Object convertObjectToType( @Nullable final Object obj, final TypeSignature type, - final boolean reportParseExceptions + final boolean reportParseExceptions, + @Nullable final String fieldName ) { Preconditions.checkNotNull(type, "type"); switch (type.getType()) { case LONG: - return convertObjectToLong(obj, reportParseExceptions); + return convertObjectToLong(obj, reportParseExceptions, fieldName); case FLOAT: - return convertObjectToFloat(obj, reportParseExceptions); + return convertObjectToFloat(obj, reportParseExceptions, fieldName); case DOUBLE: - return convertObjectToDouble(obj, reportParseExceptions); + return convertObjectToDouble(obj, reportParseExceptions, fieldName); case STRING: return convertObjectToString(obj); case ARRAY: return coerceToObjectArrayWithElementCoercionFunction( obj, - x -> DimensionHandlerUtils.convertObjectToType(x, type.getElementType()) + x -> DimensionHandlerUtils.convertObjectToType(x, type.getElementType(), reportParseExceptions, fieldName) ); case COMPLEX: // Can't coerce complex objects, and we shouldn't need to. If in future selectors behave weirdly, or we need to @@ -420,6 +529,16 @@ public static Object convertObjectToType( } } + @Nullable + public static Object convertObjectToType( + @Nullable final Object obj, + final TypeSignature type, + final boolean reportParseExceptions + ) + { + return convertObjectToType(obj, type, reportParseExceptions, null); + } + @Nullable public static Object[] convertToArray(Object obj, TypeSignature elementType) { @@ -506,6 +625,18 @@ public static Double convertObjectToDouble(@Nullable Object valObj) @Nullable public static Double convertObjectToDouble(@Nullable Object valObj, boolean reportParseExceptions) + { + return convertObjectToDouble(valObj, reportParseExceptions, null); + } + + @Nullable + public static Double convertObjectToDouble(@Nullable Object valObj, @Nullable String fieldName) + { + return convertObjectToDouble(valObj, false, fieldName); + } + + @Nullable + public static Double convertObjectToDouble(@Nullable Object valObj, boolean reportParseExceptions, @Nullable String fieldName) { if (valObj == null) { return null; @@ -518,21 +649,59 @@ public static Double convertObjectToDouble(@Nullable Object valObj, boolean repo } else if (valObj instanceof String) { Double ret = Doubles.tryParse((String) valObj); if (reportParseExceptions && ret == null) { - throw new ParseException((String) valObj, "could not convert value [%s] to double", valObj); + final String message; + if (fieldName != null) { + message = StringUtils.nonStrictFormat( + "Could not convert value [%s] to double for dimension [%s].", + valObj, + fieldName + ); + } else { + message = StringUtils.nonStrictFormat( + "Could not convert value [%s] to double.", + valObj + ); + } + throw new ParseException((String) valObj, message); } return ret; } else if (valObj instanceof List) { + final String message; + if (fieldName != null) { + message = StringUtils.nonStrictFormat( + "Could not ingest value [%s] as double for dimension [%s]. A double column cannot have multiple values in the same row.", + valObj, + fieldName + ); + } else { + message = StringUtils.nonStrictFormat( + "Could not ingest value [%s] as double. A double column cannot have multiple values in the same row.", + valObj + ); + } + throw new ParseException( valObj.getClass().toString(), - "Could not ingest value %s as double. A double column cannot have multiple values in the same row.", - valObj + message ); } else { + final String message; + if (fieldName != null) { + message = StringUtils.nonStrictFormat( + "Could not convert value [%s] to double for dimension [%s]. Invalid type: [%s]", + valObj, + fieldName, + valObj.getClass() + ); + } else { + message = StringUtils.nonStrictFormat( + "Could not convert value [%s] to double. Invalid type: [%s]", + valObj, valObj.getClass() + ); + } throw new ParseException( valObj.getClass().toString(), - "Could not convert value [%s] to double. Invalid type: [%s]", - valObj, - valObj.getClass() + message ); } } diff --git a/processing/src/main/java/org/apache/druid/segment/DoubleDimensionHandler.java b/processing/src/main/java/org/apache/druid/segment/DoubleDimensionHandler.java index 9fbc9436be6d..e81667089227 100644 --- a/processing/src/main/java/org/apache/druid/segment/DoubleDimensionHandler.java +++ b/processing/src/main/java/org/apache/druid/segment/DoubleDimensionHandler.java @@ -72,7 +72,7 @@ public DimensionSchema getDimensionSchema(ColumnCapabilities capabilities) @Override public DimensionIndexer makeIndexer(boolean useMaxMemoryEstimates) { - return new DoubleDimensionIndexer(); + return new DoubleDimensionIndexer(dimensionName); } @Override diff --git a/processing/src/main/java/org/apache/druid/segment/DoubleDimensionIndexer.java b/processing/src/main/java/org/apache/druid/segment/DoubleDimensionIndexer.java index f4e13cca565e..6f1e5184747a 100644 --- a/processing/src/main/java/org/apache/druid/segment/DoubleDimensionIndexer.java +++ b/processing/src/main/java/org/apache/druid/segment/DoubleDimensionIndexer.java @@ -39,13 +39,21 @@ public class DoubleDimensionIndexer implements DimensionIndexer { public static final Comparator DOUBLE_COMPARATOR = Comparators.naturalNullsFirst(); - + private final String dimensionName; private volatile boolean hasNulls = false; + public DoubleDimensionIndexer(String dimensionName) + { + this.dimensionName = dimensionName; + } + @Override - public EncodedKeyComponent processRowValsToUnsortedEncodedKeyComponent(@Nullable Object dimValues, boolean reportParseExceptions) + public EncodedKeyComponent processRowValsToUnsortedEncodedKeyComponent( + @Nullable Object dimValues, + boolean reportParseExceptions + ) { - Double d = DimensionHandlerUtils.convertObjectToDouble(dimValues, reportParseExceptions); + Double d = DimensionHandlerUtils.convertObjectToDouble(dimValues, reportParseExceptions, dimensionName); if (d == null) { hasNulls = NullHandling.sqlCompatible(); } diff --git a/processing/src/main/java/org/apache/druid/segment/FloatDimensionHandler.java b/processing/src/main/java/org/apache/druid/segment/FloatDimensionHandler.java index 4763b0e8be12..8d3471a4d924 100644 --- a/processing/src/main/java/org/apache/druid/segment/FloatDimensionHandler.java +++ b/processing/src/main/java/org/apache/druid/segment/FloatDimensionHandler.java @@ -72,7 +72,7 @@ public DimensionSchema getDimensionSchema(ColumnCapabilities capabilities) @Override public DimensionIndexer makeIndexer(boolean useMaxMemoryEstimates) { - return new FloatDimensionIndexer(); + return new FloatDimensionIndexer(dimensionName); } @Override diff --git a/processing/src/main/java/org/apache/druid/segment/FloatDimensionIndexer.java b/processing/src/main/java/org/apache/druid/segment/FloatDimensionIndexer.java index be5e86b7bb65..16b3c9f70528 100644 --- a/processing/src/main/java/org/apache/druid/segment/FloatDimensionIndexer.java +++ b/processing/src/main/java/org/apache/druid/segment/FloatDimensionIndexer.java @@ -39,13 +39,21 @@ public class FloatDimensionIndexer implements DimensionIndexer { public static final Comparator FLOAT_COMPARATOR = Comparators.naturalNullsFirst(); - + private final String dimensionName; private volatile boolean hasNulls = false; + public FloatDimensionIndexer(String dimensionName) + { + this.dimensionName = dimensionName; + } + @Override - public EncodedKeyComponent processRowValsToUnsortedEncodedKeyComponent(@Nullable Object dimValues, boolean reportParseExceptions) + public EncodedKeyComponent processRowValsToUnsortedEncodedKeyComponent( + @Nullable Object dimValues, + boolean reportParseExceptions + ) { - Float f = DimensionHandlerUtils.convertObjectToFloat(dimValues, reportParseExceptions); + Float f = DimensionHandlerUtils.convertObjectToFloat(dimValues, reportParseExceptions, dimensionName); if (f == null) { hasNulls = NullHandling.sqlCompatible(); } diff --git a/processing/src/main/java/org/apache/druid/segment/LongDimensionHandler.java b/processing/src/main/java/org/apache/druid/segment/LongDimensionHandler.java index 51e13396840c..64a9f98cd44c 100644 --- a/processing/src/main/java/org/apache/druid/segment/LongDimensionHandler.java +++ b/processing/src/main/java/org/apache/druid/segment/LongDimensionHandler.java @@ -72,7 +72,7 @@ public DimensionSchema getDimensionSchema(ColumnCapabilities capabilities) @Override public DimensionIndexer makeIndexer(boolean useMaxMemoryEstimates) { - return new LongDimensionIndexer(); + return new LongDimensionIndexer(dimensionName); } @Override diff --git a/processing/src/main/java/org/apache/druid/segment/LongDimensionIndexer.java b/processing/src/main/java/org/apache/druid/segment/LongDimensionIndexer.java index 85ed29b9c288..3b273bb7f021 100644 --- a/processing/src/main/java/org/apache/druid/segment/LongDimensionIndexer.java +++ b/processing/src/main/java/org/apache/druid/segment/LongDimensionIndexer.java @@ -39,13 +39,21 @@ public class LongDimensionIndexer implements DimensionIndexer { public static final Comparator LONG_COMPARATOR = Comparators.naturalNullsFirst(); - + private final String dimensionName; private volatile boolean hasNulls = false; + public LongDimensionIndexer(String dimensionName) + { + this.dimensionName = dimensionName; + } + @Override - public EncodedKeyComponent processRowValsToUnsortedEncodedKeyComponent(@Nullable Object dimValues, boolean reportParseExceptions) + public EncodedKeyComponent processRowValsToUnsortedEncodedKeyComponent( + @Nullable Object dimValues, + boolean reportParseExceptions + ) { - Long l = DimensionHandlerUtils.convertObjectToLong(dimValues, reportParseExceptions); + Long l = DimensionHandlerUtils.convertObjectToLong(dimValues, reportParseExceptions, dimensionName); if (l == null) { hasNulls = NullHandling.sqlCompatible(); } diff --git a/processing/src/test/java/org/apache/druid/segment/incremental/IncrementalIndexTest.java b/processing/src/test/java/org/apache/druid/segment/incremental/IncrementalIndexTest.java index c83c4f0da4c0..067c078f5bc3 100644 --- a/processing/src/test/java/org/apache/druid/segment/incremental/IncrementalIndexTest.java +++ b/processing/src/test/java/org/apache/druid/segment/incremental/IncrementalIndexTest.java @@ -197,7 +197,7 @@ public void testUnparseableNumerics() throws IndexSizeExceededException result.getParseException().getInput() ); Assert.assertEquals( - "Found unparseable columns in row: [{string=A, float=19.0, long=asdj, double=21.0}], exceptions: [could not convert value [asdj] to long]", + "Found unparseable columns in row: [{string=A, float=19.0, long=asdj, double=21.0}], exceptions: [Could not convert value [asdj] to long for dimension [long].]", result.getParseException().getMessage() ); @@ -219,7 +219,7 @@ public void testUnparseableNumerics() throws IndexSizeExceededException result.getParseException().getInput() ); Assert.assertEquals( - "Found unparseable columns in row: [{string=A, float=aaa, long=20, double=21.0}], exceptions: [could not convert value [aaa] to float]", + "Found unparseable columns in row: [{string=A, float=aaa, long=20, double=21.0}], exceptions: [Could not convert value [aaa] to float for dimension [float].]", result.getParseException().getMessage() ); @@ -241,7 +241,7 @@ public void testUnparseableNumerics() throws IndexSizeExceededException result.getParseException().getInput() ); Assert.assertEquals( - "Found unparseable columns in row: [{string=A, float=19.0, long=20, double=}], exceptions: [could not convert value [] to double]", + "Found unparseable columns in row: [{string=A, float=19.0, long=20, double=}], exceptions: [Could not convert value [] to double for dimension [double].]", result.getParseException().getMessage() ); } @@ -270,7 +270,7 @@ public void testMultiValuedNumericDimensions() throws IndexSizeExceededException result.getParseException().getInput() ); Assert.assertEquals( - "Found unparseable columns in row: [{string=A, float=19.0, long=[10, 5], double=21.0}], exceptions: [Could not ingest value [10, 5] as long. A long column cannot have multiple values in the same row.]", + "Found unparseable columns in row: [{string=A, float=19.0, long=[10, 5], double=21.0}], exceptions: [Could not ingest value [[10, 5]] as long for dimension [long]. A long column cannot have multiple values in the same row.]", result.getParseException().getMessage() ); @@ -292,7 +292,7 @@ public void testMultiValuedNumericDimensions() throws IndexSizeExceededException result.getParseException().getInput() ); Assert.assertEquals( - "Found unparseable columns in row: [{string=A, float=[10.0, 5.0], long=20, double=21.0}], exceptions: [Could not ingest value [10.0, 5.0] as float. A float column cannot have multiple values in the same row.]", + "Found unparseable columns in row: [{string=A, float=[10.0, 5.0], long=20, double=21.0}], exceptions: [Could not ingest value [[10.0, 5.0]] as float for dimension [float]. A float column cannot have multiple values in the same row.]", result.getParseException().getMessage() ); @@ -314,7 +314,7 @@ public void testMultiValuedNumericDimensions() throws IndexSizeExceededException result.getParseException().getInput() ); Assert.assertEquals( - "Found unparseable columns in row: [{string=A, float=19.0, long=20, double=[10.0, 5.0]}], exceptions: [Could not ingest value [10.0, 5.0] as double. A double column cannot have multiple values in the same row.]", + "Found unparseable columns in row: [{string=A, float=19.0, long=20, double=[10.0, 5.0]}], exceptions: [Could not ingest value [[10.0, 5.0]] as double for dimension [double]. A double column cannot have multiple values in the same row.]", result.getParseException().getMessage() ); } diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/run/SqlResults.java b/sql/src/main/java/org/apache/druid/sql/calcite/run/SqlResults.java index 486c23f67c9a..38b3ab1fd890 100644 --- a/sql/src/main/java/org/apache/druid/sql/calcite/run/SqlResults.java +++ b/sql/src/main/java/org/apache/druid/sql/calcite/run/SqlResults.java @@ -114,21 +114,21 @@ public static Object coerce( } } else if (sqlTypeName == SqlTypeName.BIGINT) { try { - coercedValue = DimensionHandlerUtils.convertObjectToLong(value); + coercedValue = DimensionHandlerUtils.convertObjectToLong(value, fieldName); } catch (Exception e) { throw cannotCoerce(value, sqlTypeName, fieldName); } } else if (sqlTypeName == SqlTypeName.FLOAT) { try { - coercedValue = DimensionHandlerUtils.convertObjectToFloat(value); + coercedValue = DimensionHandlerUtils.convertObjectToFloat(value, fieldName); } catch (Exception e) { throw cannotCoerce(value, sqlTypeName, fieldName); } } else if (SqlTypeName.FRACTIONAL_TYPES.contains(sqlTypeName)) { try { - coercedValue = DimensionHandlerUtils.convertObjectToDouble(value); + coercedValue = DimensionHandlerUtils.convertObjectToDouble(value, fieldName); } catch (Exception e) { throw cannotCoerce(value, sqlTypeName, fieldName);