{"record":{"id":"28f5592b79624d48","repo":"alibaba/DataX","slug":"biginteger-null-left-s-rig","errorCode":null,"errorMessage":"对 BigInteger 进行切分时，其左右区间不能为 null. 此处:left=[%s],right=[%s].","messagePattern":"对 BigInteger 进行切分时，其左右区间不能为 null\\. 此处:left=\\[(.+?)\\],right=\\[(.+?)\\]\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"common/src/main/java/com/alibaba/datax/common/util/RangeSplitUtil.java","lineNumber":50,"sourceCode":"\n    public static long[] doLongSplit(long left, long right, int expectSliceNumber) {\n        BigInteger[] result = doBigIntegerSplit(BigInteger.valueOf(left),\n                BigInteger.valueOf(right), expectSliceNumber);\n        long[] returnResult = new long[result.length];\n        for (int i = 0, len = result.length; i < len; i++) {\n            returnResult[i] = result[i].longValue();\n        }\n        return returnResult;\n    }\n\n    public static BigInteger[] doBigIntegerSplit(BigInteger left, BigInteger right, int expectSliceNumber) {\n        if (expectSliceNumber < 1) {\n            throw new IllegalArgumentException(String.format(\n                    \"切分份数不能小于1. 此处:expectSliceNumber=[%s].\", expectSliceNumber));\n        }\n\n        if (null == left || null == right) {\n            throw new IllegalArgumentException(String.format(\n                    \"对 BigInteger 进行切分时，其左右区间不能为 null. 此处:left=[%s],right=[%s].\", left, right));\n        }\n\n        if (left.compareTo(right) == 0) {\n            return new BigInteger[]{left, right};\n        } else {\n            // 调整大小顺序，确保 left < right\n            if (left.compareTo(right) > 0) {\n                BigInteger temp = left;\n                left = right;\n                right = temp;\n            }\n\n            //left < right\n            BigInteger endAndStartGap = right.subtract(left);\n\n            BigInteger step = endAndStartGap.divide(BigInteger.valueOf(expectSliceNumber));\n            BigInteger remainder = endAndStartGap.remainder(BigInteger.valueOf(expectSliceNumber));","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/alibaba/DataX/blob/80ec23d5c5328eb90ca364d2749e92dfaf44541e/common/src/main/java/com/alibaba/datax/common/util/RangeSplitUtil.java#L32-L68","documentation":"RangeSplitUtil.doBigIntegerSplit throws IllegalArgumentException when either the left or right boundary BigInteger is null. The splitter needs concrete numeric endpoints to compute sub-ranges; null endpoints indicate the caller failed to derive a range (e.g. from a null splitPk value).","triggerScenarios":"Calling doBigIntegerSplit(null, x, n) or doBigIntegerSplit(x, null, n). In practice: a splitPk column whose min/max could not be read (all-null column, query failure silently swallowed) yields null endpoints that reach this method.","commonSituations":"Choosing a splitPk column that is nullable and entirely NULL in the source table; reader plugins that return null when the range query returns no rows.","solutions":["Pick a splitPk column that is NOT NULL (ideally indexed) — a primary key.","If the range cannot be determined, skip splitting and run a single channel instead of calling the splitter.","Guard at the call site: if (left == null || right == null) fall back to a non-split task."],"exampleFix":"// before\nBigInteger[] points = RangeSplitUtil.doBigIntegerSplit(min, max, n);\n\n// after\nif (min == null || max == null) {\n    // single-task fallback, no split\n    return Collections.singletonList(new Range(defaultLeft, defaultRight));\n}\nBigInteger[] points = RangeSplitUtil.doBigIntegerSplit(min, max, n);","handlingStrategy":"type-guard","validationCode":"if (minBig == null || maxBig == null) {\n    return singleTaskFallback(); // no split\n}\nreturn RangeSplitUtil.doBigIntegerSplit(minBig, maxBig, n);","typeGuard":"static boolean hasValidRange(BigInteger l, BigInteger r) {\n    return l != null && r != null;\n}","tryCatchPattern":"catch (IllegalArgumentException e) when message mentions null: skip splitting, run one task.","preventionTips":["Prefer NOT NULL primary keys as splitPk.","Null-check boundaries right after querying min/max."],"tags":["datax","split","null-safety","validation"],"backgroundTag":null,"analyzedSha":"80ec23d5c5328eb90ca364d2749e92dfaf44541e","analyzedAt":"2026-08-14T15:33:51.187Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}