From 63f0b6b706dcbc8e92a8ff3ee8b81d6d6900aa67 Mon Sep 17 00:00:00 2001 From: Apoorv Bhawsar Date: Tue, 29 Sep 2020 19:23:33 +0530 Subject: [PATCH] SOLR-14767 : Fix NumberFormatException when int/long field value is floating num (#1775) --- solr/CHANGES.txt | 3 +++ .../org/apache/solr/schema/IntPointField.java | 14 +++++++--- .../apache/solr/schema/LongPointField.java | 14 +++++++--- .../org/apache/solr/schema/TrieField.java | 26 ++++++++++++++----- .../org/apache/solr/update/TestUpdate.java | 10 +++++++ 5 files changed, 55 insertions(+), 12 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 77cb773658c..f2e77dbc892 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -251,6 +251,9 @@ Bug Fixes * SOLR-14850: Fix ExactStatsCache NullPointerException when shards.tolerant=true. (Yevhen Tienkaiev via ab) +* SOLR-14767: Fix NumberFormatException when integer/long field value is specified as floating number + (Apoorv Bhawsar, Munendra S N) + Other Changes --------------------- diff --git a/solr/core/src/java/org/apache/solr/schema/IntPointField.java b/solr/core/src/java/org/apache/solr/schema/IntPointField.java index 84a9a781153..d1493cddcb4 100644 --- a/solr/core/src/java/org/apache/solr/schema/IntPointField.java +++ b/solr/core/src/java/org/apache/solr/schema/IntPointField.java @@ -51,8 +51,7 @@ public class IntPointField extends PointField implements IntValueFieldType { try { if (val instanceof CharSequence) return Integer.parseInt( val.toString()); } catch (NumberFormatException e) { - Float v = Float.parseFloat(val.toString()); - return v.intValue(); + return (int)Float.parseFloat(val.toString()); } return super.toNativeType(val); } @@ -146,7 +145,16 @@ public class IntPointField extends PointField implements IntValueFieldType { @Override public IndexableField createField(SchemaField field, Object value) { - int intValue = (value instanceof Number) ? ((Number) value).intValue() : Integer.parseInt(value.toString()); + int intValue; + if (value instanceof Number) { + intValue = ((Number) value).intValue(); + } else { + try { + intValue = Integer.parseInt(value.toString()); + } catch (NumberFormatException e) { + intValue = (int) Float.parseFloat(value.toString()); + } + } return new IntPoint(field.getName(), intValue); } diff --git a/solr/core/src/java/org/apache/solr/schema/LongPointField.java b/solr/core/src/java/org/apache/solr/schema/LongPointField.java index 83a6ed3cefb..6fd011da525 100644 --- a/solr/core/src/java/org/apache/solr/schema/LongPointField.java +++ b/solr/core/src/java/org/apache/solr/schema/LongPointField.java @@ -50,8 +50,7 @@ public class LongPointField extends PointField implements LongValueFieldType { try { if (val instanceof CharSequence) return Long.parseLong(val.toString()); } catch (NumberFormatException e) { - Double v = Double.parseDouble(val.toString()); - return v.longValue(); + return (long)Double.parseDouble(val.toString()); } return super.toNativeType(val); } @@ -151,7 +150,16 @@ public class LongPointField extends PointField implements LongValueFieldType { @Override public IndexableField createField(SchemaField field, Object value) { - long longValue = (value instanceof Number) ? ((Number) value).longValue() : Long.parseLong(value.toString()); + long longValue; + if (value instanceof Number) { + longValue = ((Number) value).longValue(); + } else { + try { + longValue = Long.parseLong(value.toString()); + } catch (NumberFormatException e) { + longValue = (long) Double.parseDouble(value.toString()); + } + } return new LongPoint(field.getName(), longValue); } diff --git a/solr/core/src/java/org/apache/solr/schema/TrieField.java b/solr/core/src/java/org/apache/solr/schema/TrieField.java index a80cae79835..c0f04de9b00 100644 --- a/solr/core/src/java/org/apache/solr/schema/TrieField.java +++ b/solr/core/src/java/org/apache/solr/schema/TrieField.java @@ -553,9 +553,16 @@ public class TrieField extends NumericFieldType { switch (type) { case INTEGER: - int i = (value instanceof Number) - ? ((Number)value).intValue() - : Integer.parseInt(value.toString()); + int i; + if (value instanceof Number) { + i = ((Number) value).intValue(); + } else { + try { + i = Integer.parseInt(value.toString()); + } catch (NumberFormatException e) { + i = (int) Float.parseFloat(value.toString()); + } + } f = new LegacyIntField(field.getName(), i, ft); break; case FLOAT: @@ -565,9 +572,16 @@ public class TrieField extends NumericFieldType { f = new LegacyFloatField(field.getName(), fl, ft); break; case LONG: - long l = (value instanceof Number) - ? ((Number)value).longValue() - : Long.parseLong(value.toString()); + long l; + if (value instanceof Number) { + l = ((Number) value).longValue(); + } else { + try { + l = Long.parseLong(value.toString()); + } catch (NumberFormatException e) { + l = (long) Double.parseDouble(value.toString()); + } + } f = new LegacyLongField(field.getName(), l, ft); break; case DOUBLE: diff --git a/solr/core/src/test/org/apache/solr/update/TestUpdate.java b/solr/core/src/test/org/apache/solr/update/TestUpdate.java index d93b844a0ec..04b8c405c7b 100644 --- a/solr/core/src/test/org/apache/solr/update/TestUpdate.java +++ b/solr/core/src/test/org/apache/solr/update/TestUpdate.java @@ -238,4 +238,14 @@ public class TestUpdate extends SolrTestCaseJ4 { fail(); } + @Test // SOLR-14767 + public void testStringUpdateOnLongAndIntFields() throws Exception { + clearIndex(); + + addAndGetVersion(sdoc("id","1", "val_is", "42.0", "val_is", 12, "val_i", "12.1", "val_l", + "42.0", "val_ll", "12.1", "val_ll", "32"), null); + assertJQ(req("qt","/get", "id","1", "fl","id,val*") + ,"=={'doc':{'id':'1', 'val_i':12, 'val_is':[42,12], 'val_l':42, 'val_ll':[12,32]}}" + ); + } }