imbajin commented on code in PR #771:
URL: 
https://github.com/apache/hugegraph-toolchain/pull/771#discussion_r4150239515


##########
hugegraph-loader/src/main/java/org/apache/hugegraph/loader/util/JsonUtil.java:
##########
@@ -47,6 +48,15 @@ public final class JsonUtil {
     private static final Logger LOG = Log.logger(JsonUtil.class);
     private static final ObjectMapper MAPPER = new ObjectMapper();
 
+    static {
+        /*
+         * Read JSON fraction literals as BigDecimal: a DECIMAL column keeps
+         * every digit (a double would keep 17), the other numeric types are
+         * narrowed by DataTypeUtil as before.
+         */
+        MAPPER.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);

Review Comment:
   ⚠️ Blocking: yes. Summary: This changes JSON fractions from Double to 
scale-preserving BigDecimal, so a value like 1.00 no longer matches an existing 
mapping key "1.0"; preserve the prior canonical string for mapping lookup. 
Evidence: ElementBuilder.mappingValue() uses String.valueOf(fieldValue), then 
ElementMapping.mappingValue() performs an exact Map.get(rawValue).



##########
hugegraph-loader/src/main/java/org/apache/hugegraph/loader/util/DataTypeUtil.java:
##########
@@ -200,7 +202,17 @@ private static Object parseSingleValue(String key, Object 
rawValue,
             }
         } else if (dataType.isUUID()) {
             return parseUUID(key, value);
+        } else if (dataType.isDecimal()) {
+            return parseDecimal(key, value);
         } else if (dataType.isText()) {
+            if (value instanceof BigDecimal && fromJsonParser(source)) {
+                // JSON fractions are parsed as BigDecimal (see JsonUtil);
+                // a TEXT key keeps the string the double path produced
+                // ("1.5", not "1.50"), so existing ids do not change.
+                // A BigDecimal from any other source (JDBC DECIMAL/NUMERIC)
+                // keeps its own text, as before
+                return Double.toString(((BigDecimal) value).doubleValue());

Review Comment:
   ⚠️ Blocking: no. Summary: JSON -0.0 now becomes TEXT "0.0", which can change 
an existing text value or ID; preserve signed zero when converting JSON 
BigDecimal values. Evidence: USE_BIG_DECIMAL_FOR_FLOATS loses the negative-zero 
sign and this branch converts through doubleValue() before Double.toString().



##########
hugegraph-loader/src/main/java/org/apache/hugegraph/loader/builder/ElementBuilder.java:
##########
@@ -212,7 +214,42 @@ protected boolean retainField(String fieldName, Object 
fieldValue) {
         }
 
         return !nullableKeys.contains(mappedKey) ||
-               !nullValues.contains(fieldValue);
+               !isNullValue(nullValues, fieldValue);
+    }
+
+    /**
+     * Numbers are matched by value: JSON rows and the mapping's null_values
+     * are both parsed as BigDecimal now, whose equals() is scale-sensitive
+     * (1.0 vs 1.00); before, both were Double and matched.
+     */
+    public static boolean isNullValue(Set<Object> nullValues, Object 
fieldValue) {
+        if (nullValues.contains(fieldValue)) {
+            return true;
+        }
+        if (!(fieldValue instanceof Number)) {
+            return false;
+        }
+        BigDecimal value = toBigDecimal((Number) fieldValue);
+        for (Object nullValue : nullValues) {
+            if (nullValue instanceof Number &&
+                value.compareTo(toBigDecimal((Number) nullValue)) == 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static BigDecimal toBigDecimal(Number number) {
+        if (number instanceof BigDecimal) {
+            return (BigDecimal) number;
+        }
+        if (number instanceof BigInteger) {
+            return new BigDecimal((BigInteger) number);
+        }
+        if (number instanceof Double || number instanceof Float) {
+            return new BigDecimal(number.toString());

Review Comment:
   ⚠️ Blocking: no. Summary: A JDBC Float/Double NaN or Infinity throws during 
null-value filtering when it is not itself listed as null; handle non-finite 
numbers before constructing BigDecimal. Evidence: retainField() calls this 
conversion for nullable keys, and new BigDecimal(number.toString()) rejects 
those values.



##########
hugegraph-loader/src/main/java/org/apache/hugegraph/loader/util/DataTypeUtil.java:
##########
@@ -328,6 +353,40 @@ private static Number parseNumber(String key, Object value,
         }
     }
 
+    private static boolean fromJsonParser(InputSource source) {
+        if (source instanceof FileSource) {
+            return ((FileSource) source).format() == FileFormat.JSON;
+        }
+        if (source instanceof KafkaSource) {
+            return ((KafkaSource) source).getFormat() == FileFormat.JSON;
+        }
+        return false;
+    }
+
+    private static boolean withinDecimalBounds(BigDecimal decimal) {
+        try {
+            DataType.checkDecimalBounds(decimal);
+            return true;
+        } catch (IllegalArgumentException e) {
+            return false;
+        }
+    }
+
+    private static BigDecimal parseDecimal(String key, Object rawValue) {
+        BigDecimal decimal;
+        try {
+            decimal = DataType.DECIMAL.valueToDecimal(rawValue);
+        } catch (IllegalArgumentException e) {
+            throw new IllegalArgumentException(String.format(
+                      "Failed to convert value(key='%s') '%s'(%s) to Decimal",
+                      key, rawValue, rawValue.getClass()), e);
+        }
+        E.checkArgument(decimal != null,
+                        "Failed to convert value(key='%s') '%s'(%s) to 
Decimal",
+                        key, rawValue, rawValue.getClass());

Review Comment:
   🧹 Blocking: no. Summary: A null element in a DECIMAL collection raises 
NullPointerException instead of a conversion error; reject null explicitly or 
build the error without dereferencing it. Evidence: valueToDecimal(null) 
returns null, then this error argument evaluates rawValue.getClass().



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to