@@ -74,6 +74,11 @@ public static function makeJsonBinaryDecoder(string $data): self
7474 */
7575 public function parseToString (): string
7676 {
77+ // Sometimes, we can insert a NULL JSON even we set the JSON field as NOT NULL.
78+ // If we meet this case, we can return a 'null' value.
79+ if ($ this ->binaryDataReader ->getBinaryDataLength () === 0 ) {
80+ return 'null ' ;
81+ }
7782 $ this ->parseJson ($ this ->binaryDataReader ->readUInt8 ());
7883
7984 return $ this ->jsonBinaryDecoderFormatter ->getJsonString ();
@@ -198,7 +203,7 @@ private function parseArrayOrObject(int $type, int $intSize): array
198203
199204 $ entries = [];
200205 for ($ i = 0 ; $ i !== $ elementCount ; ++$ i ) {
201- $ entries [$ i ] = $ this ->getOffsetOrInLinedValue ($ bytes , $ intSize );
206+ $ entries [$ i ] = $ this ->getOffsetOrInLinedValue ($ bytes , $ intSize, $ valueEntrySize );
202207 }
203208
204209 $ keys = [];
@@ -238,11 +243,21 @@ private static function valueEntrySize(bool $large): int
238243 * @throws BinaryDataReaderException
239244 * @throws JsonBinaryDecoderException
240245 */
241- private function getOffsetOrInLinedValue (int $ bytes , int $ intSize ): JsonBinaryDecoderValue
246+ private function getOffsetOrInLinedValue (int $ bytes , int $ intSize, int $ valueEntrySize ): JsonBinaryDecoderValue
242247 {
243248 $ type = $ this ->binaryDataReader ->readUInt8 ();
249+
244250 if (self ::isInLinedType ($ type , $ intSize )) {
245- return $ this ->parseScalar ($ type );
251+ $ scalar = $ this ->parseScalar ($ type );
252+
253+ // In binlog format, JSON arrays are fixed width elements, even though type value can be smaller.
254+ // In order to properly process this case, we need to move cursor to the next element, which is on position 1 + $valueEntrySize (1 is length of type)
255+ if ($ type === self ::UINT16 || $ type === self ::INT16 ) {
256+ $ readNextBytes = $ valueEntrySize - 2 - 1 ;
257+ $ this ->binaryDataReader ->read ($ readNextBytes );
258+ }
259+
260+ return $ scalar ;
246261 }
247262
248263 $ offset = $ this ->binaryDataReader ->readUIntBySize ($ intSize );
@@ -371,4 +386,4 @@ private function ensureOffset(?int $ensureOffset): void
371386 $ this ->binaryDataReader ->advance ($ ensureOffset + 1 - $ pos );
372387 }
373388 }
374- }
389+ }
0 commit comments