@@ -39,7 +39,7 @@ public static function fromLockId(
3939 $ lockStringId = (string )$ lockId ;
4040
4141 return new self (
42- id: self ::generateIdFromString ($ lockStringId ),
42+ id: self ::convertStringToSignedInt32 ($ lockStringId ),
4343 humanReadableValue: $ lockStringId ,
4444 );
4545 }
@@ -51,15 +51,19 @@ public static function fromLockId(
5151 * The crc32 function returns an unsigned 32-bit integer (0 to 4_294_967_295).
5252 * Postgres advisory locks require a signed 32-bit integer (-2_147_483_648 to 2_147_483_647).
5353 *
54- * This method shifts the crc32 output into the signed int32 range by subtracting (2^31) + 1 ,
55- * ensuring the result fits within Postgres's required range and preserves uniqueness .
54+ * This method converts the unsigned crc32 result to a signed 32-bit integer ,
55+ * matching the way PostgreSQL interprets int4 values internally .
5656 *
57- * @param string $string The input string to hash into an int32 lock ID.
57+ * @param string $string The input string to hash into a signed int32 lock ID.
5858 * @return int The signed 32-bit integer suitable for Postgres advisory locks.
5959 */
60- private static function generateIdFromString (
60+ private static function convertStringToSignedInt32 (
6161 string $ string ,
6262 ): int {
63- return crc32 ($ string ) - self ::DB_INT32_VALUE_MAX - 1 ;
63+ $ unsignedInt = crc32 ($ string );
64+
65+ return $ unsignedInt > 0x7FFFFFFF
66+ ? $ unsignedInt - 0x100000000
67+ : $ unsignedInt ;
6468 }
6569}
0 commit comments