From 89c37b0bcda2fabf05de3d71dc1ad8ab39c0039e Mon Sep 17 00:00:00 2001 From: lw112 <131352377+felixwluo@users.noreply.github.com> Date: Thu, 4 Sep 2025 21:22:40 +0800 Subject: [PATCH] [bugfix](catalog) replace Math.abs with bitwise AND to ensure non-negative ID generation (#55183) ### What problem does this PR solve? Problem Summary: `Replace Math.abs() with bitwise AND operation in genIdByName() method` problem: - Math.abs(Long.MIN_VALUE) returns Long.MIN_VALUE (still negative) due to overflow - This violates the requirement that external db/table IDs must be >= 0 - Could cause issues in DescriptorTable.toThrift() as mentioned in comments fix: - Use bitwise AND with Long.MAX_VALUE to clear the sign bit - Guarantees non-negative result in range [0, Long.MAX_VALUE] - Better performance than Math.abs() conditional check ### Release note None ### Check List (For Author) - Test - [ ] Regression test - [ ] Unit Test - [ ] Manual test (add detailed scripts or steps below) - [ ] No need to test or manual test. Explain why: - [ ] This is a refactor/code format and no logic has been changed. - [ ] Previous test can cover this change. - [ ] No code files have been changed. - [ ] Other reason - Behavior changed: - [ ] No. - [ ] Yes. - Does this need documentation? - [ ] No. - [ ] Yes. ### Check List (For Reviewer who merge this PR) - [ ] Confirm the release note - [ ] Confirm test cases - [ ] Confirm document - [ ] Add branch pick label --- .../main/java/org/apache/doris/common/util/Util.java | 7 ++++++- .../java/org/apache/doris/common/util/UtilTest.java | 12 ++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/common/util/Util.java b/fe/fe-core/src/main/java/org/apache/doris/common/util/Util.java index 3c10a6af6d75f6..463d8a6e613c85 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/common/util/Util.java +++ b/fe/fe-core/src/main/java/org/apache/doris/common/util/Util.java @@ -685,7 +685,12 @@ public static long sha256long(String str) { MessageDigest digest = MessageDigest.getInstance("SHA-256"); byte[] hash = digest.digest(str.getBytes(StandardCharsets.UTF_8)); ByteBuffer buffer = ByteBuffer.wrap(hash); - return buffer.getLong(); + long result = buffer.getLong(); + // Handle Long.MIN_VALUE case to ensure non-negative ID generation + if (result == Long.MIN_VALUE) { + return str.hashCode(); + } + return result; } catch (NoSuchAlgorithmException e) { return str.hashCode(); } diff --git a/fe/fe-core/src/test/java/org/apache/doris/common/util/UtilTest.java b/fe/fe-core/src/test/java/org/apache/doris/common/util/UtilTest.java index dc8419ddd1f56d..88403effa3199f 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/common/util/UtilTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/common/util/UtilTest.java @@ -90,4 +90,16 @@ public void sha256longEcoding() { String str1 = "东方卫视"; Assertions.assertNotEquals(Util.sha256long(str), Util.sha256long(str1)); } + + @Test + public void sha256longHandlesLongMinValue() { + String testStr = "test_long_min_value_case"; + long result = Util.sha256long(testStr); + + Assertions.assertNotEquals(Long.MIN_VALUE, result, + "sha256long should not return Long.MIN_VALUE"); + + Assertions.assertEquals(result, Util.sha256long(testStr), + "Same input should produce same output"); + } }