This is an automated email from the ASF dual-hosted git repository.

zhangliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new 66d73d37b31 Add more test cases on MySQLJsonValueDecoderTest (#38183)
66d73d37b31 is described below

commit 66d73d37b319f3b8b7831f4f5aae73eecef7635d
Author: Liang Zhang <[email protected]>
AuthorDate: Tue Feb 24 20:53:14 2026 +0800

    Add more test cases on MySQLJsonValueDecoderTest (#38183)
    
    * Add more test cases on MySQLJsonValueDecoderTest
    
    * Add more test cases on MySQLJsonValueDecoderTest
---
 .../value/string/MySQLJsonValueDecoderTest.java    | 363 +++++++++------------
 1 file changed, 161 insertions(+), 202 deletions(-)

diff --git 
a/database/protocol/dialect/mysql/src/test/java/org/apache/shardingsphere/database/protocol/mysql/packet/binlog/row/column/value/string/MySQLJsonValueDecoderTest.java
 
b/database/protocol/dialect/mysql/src/test/java/org/apache/shardingsphere/database/protocol/mysql/packet/binlog/row/column/value/string/MySQLJsonValueDecoderTest.java
index 15145e743fd..c28fd848722 100644
--- 
a/database/protocol/dialect/mysql/src/test/java/org/apache/shardingsphere/database/protocol/mysql/packet/binlog/row/column/value/string/MySQLJsonValueDecoderTest.java
+++ 
b/database/protocol/dialect/mysql/src/test/java/org/apache/shardingsphere/database/protocol/mysql/packet/binlog/row/column/value/string/MySQLJsonValueDecoderTest.java
@@ -20,17 +20,22 @@ package 
org.apache.shardingsphere.database.protocol.mysql.packet.binlog.row.colu
 import com.google.common.base.Strings;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
 import 
org.apache.shardingsphere.database.protocol.mysql.packet.binlog.row.column.value.string.MySQLJsonValueDecoder.JsonValueTypes;
+import 
org.apache.shardingsphere.infra.exception.generic.UnsupportedSQLOperationException;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.stream.Stream;
 
-import static org.hamcrest.Matchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 
 class MySQLJsonValueDecoderTest {
     
@@ -48,203 +53,87 @@ class MySQLJsonValueDecoderTest {
     
     @Test
     void assertDecodeSmallJsonObjectWithLiteral() {
-        List<JsonEntry> jsonEntries = new LinkedList<>();
-        jsonEntries.add(new JsonEntry(JsonValueTypes.LITERAL, "key1", 
JsonValueTypes.LITERAL_NULL));
-        jsonEntries.add(new JsonEntry(JsonValueTypes.LITERAL, "key2", 
JsonValueTypes.LITERAL_TRUE));
-        jsonEntries.add(new JsonEntry(JsonValueTypes.LITERAL, "key3", 
JsonValueTypes.LITERAL_FALSE));
+        List<Object[]> jsonEntries = new LinkedList<>();
+        jsonEntries.add(new Object[]{JsonValueTypes.LITERAL, "key1", 
JsonValueTypes.LITERAL_NULL});
+        jsonEntries.add(new Object[]{JsonValueTypes.LITERAL, "key2", 
JsonValueTypes.LITERAL_TRUE});
+        jsonEntries.add(new Object[]{JsonValueTypes.LITERAL, "key3", 
JsonValueTypes.LITERAL_FALSE});
         ByteBuf payload = mockJsonObjectByteBuf(jsonEntries, true);
-        String actual = (String) MySQLJsonValueDecoder.decode(payload);
-        assertThat(actual, is("{\"key1\":null,\"key2\":true,\"key3\":false}"));
+        assertThat(MySQLJsonValueDecoder.decode(payload), 
is("{\"key1\":null,\"key2\":true,\"key3\":false}"));
     }
     
     @Test
     void assertDecodeLargeJsonObjectWithLiteral() {
-        List<JsonEntry> jsonEntries = new LinkedList<>();
-        jsonEntries.add(new JsonEntry(JsonValueTypes.LITERAL, "key1", 
JsonValueTypes.LITERAL_NULL));
-        jsonEntries.add(new JsonEntry(JsonValueTypes.LITERAL, "key2", 
JsonValueTypes.LITERAL_TRUE));
-        jsonEntries.add(new JsonEntry(JsonValueTypes.LITERAL, "key3", 
JsonValueTypes.LITERAL_FALSE));
-        ByteBuf payload = mockJsonObjectByteBuf(jsonEntries, false);
-        String actual = (String) MySQLJsonValueDecoder.decode(payload);
-        assertThat(actual, is("{\"key1\":null,\"key2\":true,\"key3\":false}"));
-    }
-    
-    @Test
-    void assertDecodeSmallJsonObjectWithInt16() {
-        List<JsonEntry> jsonEntries = new LinkedList<>();
-        jsonEntries.add(new JsonEntry(JsonValueTypes.INT16, "key1", 
0x00007fff));
-        jsonEntries.add(new JsonEntry(JsonValueTypes.INT16, "key2", 
0x00008000));
-        ByteBuf payload = mockJsonObjectByteBuf(jsonEntries, true);
-        String actual = (String) MySQLJsonValueDecoder.decode(payload);
-        assertThat(actual, is("{\"key1\":32767,\"key2\":-32768}"));
-    }
-    
-    @Test
-    void assertDecodeLargeJsonObjectWithInt16() {
-        List<JsonEntry> jsonEntries = new LinkedList<>();
-        jsonEntries.add(new JsonEntry(JsonValueTypes.INT16, "key1", 
0x00007fff));
-        jsonEntries.add(new JsonEntry(JsonValueTypes.INT16, "key2", 
0x00008000));
-        ByteBuf payload = mockJsonObjectByteBuf(jsonEntries, false);
-        String actual = (String) MySQLJsonValueDecoder.decode(payload);
-        assertThat(actual, is("{\"key1\":32767,\"key2\":-32768}"));
-    }
-    
-    @Test
-    void assertDecodeSmallJsonObjectWithUInt16() {
-        List<JsonEntry> jsonEntries = new LinkedList<>();
-        jsonEntries.add(new JsonEntry(JsonValueTypes.UINT16, "key1", 
0x00007fff));
-        jsonEntries.add(new JsonEntry(JsonValueTypes.UINT16, "key2", 
0x00008000));
-        ByteBuf payload = mockJsonObjectByteBuf(jsonEntries, true);
-        String actual = (String) MySQLJsonValueDecoder.decode(payload);
-        assertThat(actual, is("{\"key1\":32767,\"key2\":32768}"));
-    }
-    
-    @Test
-    void assertDecodeLargeJsonObjectWithUInt16() {
-        List<JsonEntry> jsonEntries = new LinkedList<>();
-        jsonEntries.add(new JsonEntry(JsonValueTypes.UINT16, "key1", 
0x00007fff));
-        jsonEntries.add(new JsonEntry(JsonValueTypes.UINT16, "key2", 
0x00008000));
-        ByteBuf payload = mockJsonObjectByteBuf(jsonEntries, false);
-        String actual = (String) MySQLJsonValueDecoder.decode(payload);
-        assertThat(actual, is("{\"key1\":32767,\"key2\":32768}"));
-    }
-    
-    @Test
-    void assertDecodeSmallJsonObjectWithInt32() {
-        List<JsonEntry> jsonEntries = new LinkedList<>();
-        jsonEntries.add(new JsonEntry(JsonValueTypes.INT32, "key1", 
Integer.MAX_VALUE));
-        jsonEntries.add(new JsonEntry(JsonValueTypes.INT32, "key2", 
Integer.MIN_VALUE));
-        ByteBuf payload = mockJsonObjectByteBuf(jsonEntries, true);
-        String actual = (String) MySQLJsonValueDecoder.decode(payload);
-        assertThat(actual, is("{\"key1\":2147483647,\"key2\":-2147483648}"));
-    }
-    
-    @Test
-    void assertDecodeLargeJsonObjectWithInt32() {
-        List<JsonEntry> jsonEntries = new LinkedList<>();
-        jsonEntries.add(new JsonEntry(JsonValueTypes.INT32, "key1", 
Integer.MAX_VALUE));
-        jsonEntries.add(new JsonEntry(JsonValueTypes.INT32, "key2", 
Integer.MIN_VALUE));
+        List<Object[]> jsonEntries = new LinkedList<>();
+        jsonEntries.add(new Object[]{JsonValueTypes.LITERAL, "key1", 
JsonValueTypes.LITERAL_NULL});
+        jsonEntries.add(new Object[]{JsonValueTypes.LITERAL, "key2", 
JsonValueTypes.LITERAL_TRUE});
+        jsonEntries.add(new Object[]{JsonValueTypes.LITERAL, "key3", 
JsonValueTypes.LITERAL_FALSE});
         ByteBuf payload = mockJsonObjectByteBuf(jsonEntries, false);
-        String actual = (String) MySQLJsonValueDecoder.decode(payload);
-        assertThat(actual, is("{\"key1\":2147483647,\"key2\":-2147483648}"));
+        assertThat(MySQLJsonValueDecoder.decode(payload), 
is("{\"key1\":null,\"key2\":true,\"key3\":false}"));
     }
     
     @Test
-    void assertDecodeSmallJsonObjectWithUInt32() {
-        List<JsonEntry> jsonEntries = new LinkedList<>();
-        jsonEntries.add(new JsonEntry(JsonValueTypes.UINT32, "key1", 
Integer.MAX_VALUE));
-        jsonEntries.add(new JsonEntry(JsonValueTypes.UINT32, "key2", 
Integer.MIN_VALUE));
-        ByteBuf payload = mockJsonObjectByteBuf(jsonEntries, true);
-        String actual = (String) MySQLJsonValueDecoder.decode(payload);
-        assertThat(actual, is("{\"key1\":2147483647,\"key2\":2147483648}"));
+    void assertDecodeSmallJsonArray() {
+        List<Object[]> jsonEntries = new LinkedList<>();
+        jsonEntries.add(new Object[]{JsonValueTypes.INT16, null, 0x00007fff});
+        jsonEntries.add(new Object[]{JsonValueTypes.INT16, null, 0x00008000});
+        ByteBuf payload = mockJsonArrayByteBuf(jsonEntries, true);
+        assertThat(MySQLJsonValueDecoder.decode(payload), 
is("[32767,-32768]"));
     }
     
     @Test
-    void assertDecodeLargeJsonObjectWithUInt32() {
-        List<JsonEntry> jsonEntries = new LinkedList<>();
-        jsonEntries.add(new JsonEntry(JsonValueTypes.UINT32, "key1", 
Integer.MAX_VALUE));
-        jsonEntries.add(new JsonEntry(JsonValueTypes.UINT32, "key2", 
Integer.MIN_VALUE));
-        ByteBuf payload = mockJsonObjectByteBuf(jsonEntries, false);
-        String actual = (String) MySQLJsonValueDecoder.decode(payload);
-        assertThat(actual, is("{\"key1\":2147483647,\"key2\":2147483648}"));
+    void assertDecodeLargeJsonArray() {
+        List<Object[]> jsonEntries = new LinkedList<>();
+        jsonEntries.add(new Object[]{JsonValueTypes.INT16, null, 0x00007fff});
+        jsonEntries.add(new Object[]{JsonValueTypes.INT16, null, 0x00008000});
+        ByteBuf payload = mockJsonArrayByteBuf(jsonEntries, false);
+        assertThat(MySQLJsonValueDecoder.decode(payload), 
is("[32767,-32768]"));
     }
     
-    @Test
-    void assertDecodeSmallJsonObjectWithInt64() {
-        List<JsonEntry> jsonEntries = new LinkedList<>();
-        jsonEntries.add(new JsonEntry(JsonValueTypes.INT64, "key1", 
Long.MAX_VALUE));
-        jsonEntries.add(new JsonEntry(JsonValueTypes.INT64, "key2", 
Long.MIN_VALUE));
-        ByteBuf payload = mockJsonObjectByteBuf(jsonEntries, true);
-        String actual = (String) MySQLJsonValueDecoder.decode(payload);
-        assertThat(actual, 
is("{\"key1\":9223372036854775807,\"key2\":-9223372036854775808}"));
+    @ParameterizedTest(name = "{0}")
+    @MethodSource("decodeTopLevelScalarArguments")
+    void assertDecodeTopLevelScalar(final String name, final ByteBuf payload, 
final String expected) {
+        assertThat(MySQLJsonValueDecoder.decode(payload), is(expected));
     }
     
-    @Test
-    void assertDecodeSmallJsonObjectWithUInt64() {
-        List<JsonEntry> jsonEntries = new LinkedList<>();
-        jsonEntries.add(new JsonEntry(JsonValueTypes.UINT64, "key1", 
Long.MAX_VALUE));
-        jsonEntries.add(new JsonEntry(JsonValueTypes.UINT64, "key2", 
Long.MIN_VALUE));
-        ByteBuf payload = mockJsonObjectByteBuf(jsonEntries, true);
-        String actual = (String) MySQLJsonValueDecoder.decode(payload);
-        assertThat(actual, 
is("{\"key1\":9223372036854775807,\"key2\":9223372036854775808}"));
+    @ParameterizedTest(name = "{0}")
+    @MethodSource("decodeUnsupportedArguments")
+    void assertDecodeUnsupportedOperation(final String name, final ByteBuf 
payload) {
+        assertThrows(UnsupportedSQLOperationException.class, () -> 
MySQLJsonValueDecoder.decode(payload));
     }
     
-    @Test
-    void assertDecodeSmallJsonObjectWithDouble() {
-        List<JsonEntry> jsonEntries = new LinkedList<>();
-        jsonEntries.add(new JsonEntry(JsonValueTypes.DOUBLE, "key1", 
Double.MAX_VALUE));
-        ByteBuf payload = mockJsonObjectByteBuf(jsonEntries, true);
-        String actual = (String) MySQLJsonValueDecoder.decode(payload);
-        assertThat(actual, is("{\"key1\":1.7976931348623157E308}"));
+    @ParameterizedTest(name = "{0}")
+    @MethodSource("decodeObjectWithInlineNumberArguments")
+    void assertDecodeObjectWithInlineNumber(final String name, final boolean 
isSmall, final byte type, final int firstValue, final int secondValue, final 
String expected) {
+        List<Object[]> jsonEntries = new LinkedList<>();
+        jsonEntries.add(new Object[]{type, "key1", firstValue});
+        jsonEntries.add(new Object[]{type, "key2", secondValue});
+        ByteBuf payload = mockJsonObjectByteBuf(jsonEntries, isSmall);
+        assertThat(MySQLJsonValueDecoder.decode(payload), is(expected));
     }
     
-    @Test
-    void assertDecodeSmallJsonObjectWithString() {
-        List<JsonEntry> jsonEntries = new LinkedList<>();
-        String value1 = "";
-        String value2 = Strings.repeat("1", (int) (Math.pow(2D, 7D) - 1D));
-        String value3 = Strings.repeat("1", (int) (Math.pow(2D, 7D) - 1D + 
1D));
-        String value4 = Strings.repeat("1", (int) (Math.pow(2D, 14D) - 1D));
-        jsonEntries.add(new JsonEntry(JsonValueTypes.STRING, "key1", value1));
-        jsonEntries.add(new JsonEntry(JsonValueTypes.STRING, "key2", value2));
-        jsonEntries.add(new JsonEntry(JsonValueTypes.STRING, "key3", value3));
-        jsonEntries.add(new JsonEntry(JsonValueTypes.STRING, "key4", value4));
+    @ParameterizedTest(name = "{0}")
+    @MethodSource("decodeSmallJsonObjectWithNonInlineTypeArguments")
+    void assertDecodeSmallJsonObjectWithNonInlineType(final String name, final 
List<Object[]> jsonEntries, final String expected) {
         ByteBuf payload = mockJsonObjectByteBuf(jsonEntries, true);
-        String actual = (String) MySQLJsonValueDecoder.decode(payload);
-        assertThat(actual, 
is(String.format("{\"key1\":\"%s\",\"key2\":\"%s\",\"key3\":\"%s\",\"key4\":\"%s\"}",
 value1, value2, value3, value4)));
-    }
-    
-    @Test
-    void assertDecodeSmallJsonObjectWithSubJson() {
-        List<JsonEntry> subJsons = Collections.singletonList(new 
JsonEntry(JsonValueTypes.INT32, "key1", 111));
-        ByteBuf payload = mockJsonObjectByteBuf(Collections.singletonList(new 
JsonEntry(JsonValueTypes.SMALL_JSON_OBJECT, "subJson", subJsons)), true);
-        String actual = (String) MySQLJsonValueDecoder.decode(payload);
-        assertThat(actual, is("{\"subJson\":{\"key1\":111}}"));
-    }
-    
-    @Test
-    void assertDecodeLargeJsonObjectWithSubJson() {
-        List<JsonEntry> subJsons = Collections.singletonList(new 
JsonEntry(JsonValueTypes.INT32, "key1", 111));
-        ByteBuf payload = mockJsonObjectByteBuf(Collections.singletonList(new 
JsonEntry(JsonValueTypes.SMALL_JSON_OBJECT, "subJson", subJsons)), false);
-        String actual = (String) MySQLJsonValueDecoder.decode(payload);
-        assertThat(actual, is("{\"subJson\":{\"key1\":111}}"));
-    }
-    
-    @Test
-    void assertDecodeSmallJsonObjectWithSubArray() {
-        List<JsonEntry> subArrays = Collections.singletonList(new 
JsonEntry(JsonValueTypes.INT32, null, 111));
-        ByteBuf payload = mockJsonObjectByteBuf(Collections.singletonList(new 
JsonEntry(JsonValueTypes.SMALL_JSON_ARRAY, "subJson", subArrays)), true);
-        String actual = (String) MySQLJsonValueDecoder.decode(payload);
-        assertThat(actual, is("{\"subJson\":[111]}"));
-    }
-    
-    @Test
-    void assertDecodeSmallJsonArray() {
-        List<JsonEntry> jsonEntries = new LinkedList<>();
-        jsonEntries.add(new JsonEntry(JsonValueTypes.INT16, null, 0x00007fff));
-        jsonEntries.add(new JsonEntry(JsonValueTypes.INT16, null, 0x00008000));
-        ByteBuf payload = mockJsonArrayByteBuf(jsonEntries, true);
-        String actual = (String) MySQLJsonValueDecoder.decode(payload);
-        assertThat(actual, is("[32767,-32768]"));
+        assertThat(MySQLJsonValueDecoder.decode(payload), is(expected));
     }
     
-    @Test
-    void assertDecodeLargeJsonArray() {
-        List<JsonEntry> jsonEntries = new LinkedList<>();
-        jsonEntries.add(new JsonEntry(JsonValueTypes.INT16, null, 0x00007fff));
-        jsonEntries.add(new JsonEntry(JsonValueTypes.INT16, null, 0x00008000));
-        ByteBuf payload = mockJsonArrayByteBuf(jsonEntries, false);
-        String actual = (String) MySQLJsonValueDecoder.decode(payload);
-        assertThat(actual, is("[32767,-32768]"));
+    @ParameterizedTest(name = "{0}")
+    @MethodSource("decodeNestedJsonArguments")
+    void assertDecodeNestedJson(final String name, final boolean isSmall, 
final byte nestedType, final String nestedKey, final String expected) {
+        List<Object[]> nestedEntries = Collections.singletonList(new 
Object[]{JsonValueTypes.INT32, nestedKey, 111});
+        ByteBuf payload = mockJsonObjectByteBuf(Collections.singletonList(new 
Object[]{nestedType, "subJson", nestedEntries}), isSmall);
+        assertThat(MySQLJsonValueDecoder.decode(payload), is(expected));
     }
     
-    private ByteBuf mockJsonObjectByteBuf(final List<JsonEntry> jsonEntries, 
final boolean isSmall) {
+    private ByteBuf mockJsonObjectByteBuf(final List<Object[]> jsonEntries, 
final boolean isSmall) {
         ByteBuf result = Unpooled.buffer();
         result.writeByte(isSmall ? JsonValueTypes.SMALL_JSON_OBJECT : 
JsonValueTypes.LARGE_JSON_OBJECT);
         result.writeBytes(mockJsonObjectByteBufValue(jsonEntries, isSmall));
         return result;
     }
     
-    private ByteBuf mockJsonObjectByteBufValue(final List<JsonEntry> 
jsonEntries, final boolean isSmall) {
+    private ByteBuf mockJsonObjectByteBufValue(final List<Object[]> 
jsonEntries, final boolean isSmall) {
         ByteBuf result = Unpooled.buffer();
         writeInt(result, jsonEntries.size(), isSmall);
         writeInt(result, 0, isSmall);
@@ -259,14 +148,14 @@ class MySQLJsonValueDecoderTest {
         return result;
     }
     
-    private ByteBuf mockJsonArrayByteBuf(final List<JsonEntry> jsonEntries, 
final boolean isSmall) {
+    private ByteBuf mockJsonArrayByteBuf(final List<Object[]> jsonEntries, 
final boolean isSmall) {
         ByteBuf result = Unpooled.buffer();
         result.writeByte(isSmall ? JsonValueTypes.SMALL_JSON_ARRAY : 
JsonValueTypes.LARGE_JSON_ARRAY);
         result.writeBytes(mockJsonArrayByteBufValue(jsonEntries, isSmall));
         return result;
     }
     
-    private ByteBuf mockJsonArrayByteBufValue(final List<JsonEntry> 
jsonEntries, final boolean isSmall) {
+    private ByteBuf mockJsonArrayByteBufValue(final List<Object[]> 
jsonEntries, final boolean isSmall) {
         ByteBuf result = Unpooled.buffer();
         writeInt(result, jsonEntries.size(), isSmall);
         writeInt(result, 0, isSmall);
@@ -286,21 +175,21 @@ class MySQLJsonValueDecoderTest {
         }
     }
     
-    private ByteBuf writeKeys(final ByteBuf jsonByteBuf, final List<JsonEntry> 
jsonEntries, final int startOffset, final boolean isSmall) {
+    private ByteBuf writeKeys(final ByteBuf jsonByteBuf, final List<Object[]> 
jsonEntries, final int startOffset, final boolean isSmall) {
         ByteBuf result = Unpooled.buffer();
-        for (JsonEntry each : jsonEntries) {
+        for (Object[] each : jsonEntries) {
             writeInt(jsonByteBuf, startOffset + result.readableBytes(), 
isSmall);
-            byte[] keyBytes = each.getKey().getBytes();
+            byte[] keyBytes = ((String) each[1]).getBytes();
             jsonByteBuf.writeShortLE(keyBytes.length);
             result.writeBytes(keyBytes);
         }
         return result;
     }
     
-    private ByteBuf writeValues(final ByteBuf jsonByteBuf, final 
List<JsonEntry> jsonEntries, final int startOffset, final boolean isSmall) {
+    private ByteBuf writeValues(final ByteBuf jsonByteBuf, final 
List<Object[]> jsonEntries, final int startOffset, final boolean isSmall) {
         ByteBuf result = Unpooled.buffer();
-        for (JsonEntry each : jsonEntries) {
-            jsonByteBuf.writeByte(each.getType());
+        for (Object[] each : jsonEntries) {
+            jsonByteBuf.writeByte((byte) each[0]);
             int offsetOrInlineValue = getOffsetOrInlineValue(startOffset, 
result.readableBytes(), each, isSmall);
             writeInt(jsonByteBuf, offsetOrInlineValue, isSmall);
             writeValueToByteBuf(each, result, isSmall);
@@ -308,51 +197,51 @@ class MySQLJsonValueDecoderTest {
         return result;
     }
     
-    private int getOffsetOrInlineValue(final int startOffset, final int 
readableBytes, final JsonEntry jsonEntry, final boolean isSmall) {
-        switch (jsonEntry.getType()) {
+    private int getOffsetOrInlineValue(final int startOffset, final int 
readableBytes, final Object[] jsonEntry, final boolean isSmall) {
+        switch ((byte) jsonEntry[0]) {
             case JsonValueTypes.INT16:
             case JsonValueTypes.UINT16:
-                return (int) jsonEntry.getValue();
+                return (int) jsonEntry[2];
             case JsonValueTypes.LITERAL:
-                return (byte) jsonEntry.getValue();
+                return (byte) jsonEntry[2];
             case JsonValueTypes.INT32:
             case JsonValueTypes.UINT32:
-                return isSmall ? startOffset + readableBytes : (int) 
jsonEntry.getValue();
+                return isSmall ? startOffset + readableBytes : (int) 
jsonEntry[2];
             default:
                 return startOffset + readableBytes;
         }
     }
     
     @SuppressWarnings("unchecked")
-    private void writeValueToByteBuf(final JsonEntry jsonEntry, final ByteBuf 
byteBuf, final boolean isSmall) {
-        switch (jsonEntry.getType()) {
+    private void writeValueToByteBuf(final Object[] jsonEntry, final ByteBuf 
byteBuf, final boolean isSmall) {
+        switch ((byte) jsonEntry[0]) {
             case JsonValueTypes.SMALL_JSON_OBJECT:
-                
byteBuf.writeBytes(mockJsonObjectByteBufValue((List<JsonEntry>) 
jsonEntry.getValue(), true));
+                byteBuf.writeBytes(mockJsonObjectByteBufValue((List<Object[]>) 
jsonEntry[2], true));
                 break;
             case JsonValueTypes.LARGE_JSON_OBJECT:
-                
byteBuf.writeBytes(mockJsonObjectByteBufValue((List<JsonEntry>) 
jsonEntry.getValue(), false));
+                byteBuf.writeBytes(mockJsonObjectByteBufValue((List<Object[]>) 
jsonEntry[2], false));
                 break;
             case JsonValueTypes.SMALL_JSON_ARRAY:
-                byteBuf.writeBytes(mockJsonArrayByteBufValue((List<JsonEntry>) 
jsonEntry.getValue(), true));
+                byteBuf.writeBytes(mockJsonArrayByteBufValue((List<Object[]>) 
jsonEntry[2], true));
                 break;
             case JsonValueTypes.LARGE_JSON_ARRAY:
-                byteBuf.writeBytes(mockJsonArrayByteBufValue((List<JsonEntry>) 
jsonEntry.getValue(), false));
+                byteBuf.writeBytes(mockJsonArrayByteBufValue((List<Object[]>) 
jsonEntry[2], false));
                 break;
             case JsonValueTypes.INT32:
             case JsonValueTypes.UINT32:
                 if (isSmall) {
-                    byteBuf.writeIntLE((int) jsonEntry.getValue());
+                    byteBuf.writeIntLE((int) jsonEntry[2]);
                 }
                 break;
             case JsonValueTypes.INT64:
             case JsonValueTypes.UINT64:
-                byteBuf.writeLongLE((long) jsonEntry.getValue());
+                byteBuf.writeLongLE((long) jsonEntry[2]);
                 break;
             case JsonValueTypes.DOUBLE:
-                byteBuf.writeDoubleLE((double) jsonEntry.getValue());
+                byteBuf.writeDoubleLE((double) jsonEntry[2]);
                 break;
             case JsonValueTypes.STRING:
-                writeString(byteBuf, (String) jsonEntry.getValue());
+                writeString(byteBuf, (String) jsonEntry[2]);
                 break;
             default:
         }
@@ -369,7 +258,6 @@ class MySQLJsonValueDecoderTest {
         for (int i = 0; i < lengthData.length; i++) {
             lengthData[i] = (byte) ((length >> (7 * i)) & 0x7f);
         }
-        // compress
         int index = lengthData.length - 1;
         while (index > 0) {
             if (0 != lengthData[index]) {
@@ -385,14 +273,85 @@ class MySQLJsonValueDecoderTest {
         return result;
     }
     
-    @RequiredArgsConstructor
-    @Getter
-    private static final class JsonEntry {
-        
-        private final byte type;
-        
-        private final String key;
-        
-        private final Object value;
+    private static Stream<Arguments> decodeTopLevelScalarArguments() {
+        return Stream.of(
+                Arguments.of("decode int16 top-level", 
mockTopLevelInt16ByteBuf(), "-32768"),
+                Arguments.of("decode uint16 top-level", 
mockTopLevelUInt16ByteBuf(), "65535"),
+                Arguments.of("decode string with escaped chars", 
mockTopLevelStringByteBuf(), "\"a\\\"\\\\b\""));
+    }
+    
+    private static Stream<Arguments> decodeUnsupportedArguments() {
+        MySQLJsonValueDecoderTest test = new MySQLJsonValueDecoderTest();
+        return Stream.of(
+                Arguments.of("throw unsupported exception for top-level custom 
type", mockUnsupportedTopLevelTypeByteBuf()),
+                Arguments.of("throw unsupported exception for value entry 
custom type",
+                        
test.mockJsonObjectByteBuf(Collections.singletonList(new 
Object[]{JsonValueTypes.CUSTOM_DATA, "key1", 1}), true)),
+                Arguments.of("throw unsupported exception for literal inline 
value",
+                        
test.mockJsonObjectByteBuf(Collections.singletonList(new 
Object[]{JsonValueTypes.LITERAL, "key1", (byte) 3}), true)));
+    }
+    
+    private static Stream<Arguments> decodeObjectWithInlineNumberArguments() {
+        return Stream.of(
+                Arguments.of("decode small object with int16", true, 
JsonValueTypes.INT16, 0x00007fff, 0x00008000, 
"{\"key1\":32767,\"key2\":-32768}"),
+                Arguments.of("decode large object with int16", false, 
JsonValueTypes.INT16, 0x00007fff, 0x00008000, 
"{\"key1\":32767,\"key2\":-32768}"),
+                Arguments.of("decode small object with uint16", true, 
JsonValueTypes.UINT16, 0x00007fff, 0x00008000, 
"{\"key1\":32767,\"key2\":32768}"),
+                Arguments.of("decode large object with uint16", false, 
JsonValueTypes.UINT16, 0x00007fff, 0x00008000, 
"{\"key1\":32767,\"key2\":32768}"),
+                Arguments.of("decode small object with int32", true, 
JsonValueTypes.INT32, Integer.MAX_VALUE, Integer.MIN_VALUE, 
"{\"key1\":2147483647,\"key2\":-2147483648}"),
+                Arguments.of("decode large object with int32", false, 
JsonValueTypes.INT32, Integer.MAX_VALUE, Integer.MIN_VALUE, 
"{\"key1\":2147483647,\"key2\":-2147483648}"),
+                Arguments.of("decode small object with uint32", true, 
JsonValueTypes.UINT32, Integer.MAX_VALUE, Integer.MIN_VALUE, 
"{\"key1\":2147483647,\"key2\":2147483648}"),
+                Arguments.of("decode large object with uint32", false, 
JsonValueTypes.UINT32, Integer.MAX_VALUE, Integer.MIN_VALUE, 
"{\"key1\":2147483647,\"key2\":2147483648}"));
+    }
+    
+    private static Stream<Arguments> 
decodeSmallJsonObjectWithNonInlineTypeArguments() {
+        String value1 = "";
+        String value2 = Strings.repeat("1", (int) (Math.pow(2D, 7D) - 1D));
+        String value3 = Strings.repeat("1", (int) (Math.pow(2D, 7D) - 1D + 
1D));
+        String value4 = Strings.repeat("1", (int) (Math.pow(2D, 14D) - 1D));
+        return Stream.of(
+                Arguments.of("decode small object with int64", 
Arrays.asList(new Object[]{JsonValueTypes.INT64, "key1", Long.MAX_VALUE}, new 
Object[]{JsonValueTypes.INT64, "key2", Long.MIN_VALUE}),
+                        
"{\"key1\":9223372036854775807,\"key2\":-9223372036854775808}"),
+                Arguments.of("decode small object with uint64", 
Arrays.asList(new Object[]{JsonValueTypes.UINT64, "key1", Long.MAX_VALUE}, new 
Object[]{JsonValueTypes.UINT64, "key2", Long.MIN_VALUE}),
+                        
"{\"key1\":9223372036854775807,\"key2\":9223372036854775808}"),
+                Arguments.of("decode small object with double", 
Arrays.asList(new Object[][]{new Object[]{JsonValueTypes.DOUBLE, "key1", 
Double.MAX_VALUE}}),
+                        "{\"key1\":1.7976931348623157E308}"),
+                Arguments.of("decode small object with string",
+                        Arrays.asList(new Object[]{JsonValueTypes.STRING, 
"key1", value1}, new Object[]{JsonValueTypes.STRING, "key2", value2}, new 
Object[]{JsonValueTypes.STRING, "key3", value3},
+                                new Object[]{JsonValueTypes.STRING, "key4", 
value4}),
+                        
String.format("{\"key1\":\"%s\",\"key2\":\"%s\",\"key3\":\"%s\",\"key4\":\"%s\"}",
 value1, value2, value3, value4)));
+    }
+    
+    private static Stream<Arguments> decodeNestedJsonArguments() {
+        return Stream.of(
+                Arguments.of("decode small object with sub json", true, 
JsonValueTypes.SMALL_JSON_OBJECT, "key1", "{\"subJson\":{\"key1\":111}}"),
+                Arguments.of("decode large object with sub json", false, 
JsonValueTypes.SMALL_JSON_OBJECT, "key1", "{\"subJson\":{\"key1\":111}}"),
+                Arguments.of("decode small object with sub array", true, 
JsonValueTypes.SMALL_JSON_ARRAY, null, "{\"subJson\":[111]}"));
+    }
+    
+    private static ByteBuf mockTopLevelInt16ByteBuf() {
+        ByteBuf result = Unpooled.buffer();
+        result.writeByte(JsonValueTypes.INT16);
+        result.writeShortLE(32768);
+        return result;
+    }
+    
+    private static ByteBuf mockTopLevelUInt16ByteBuf() {
+        ByteBuf result = Unpooled.buffer();
+        result.writeByte(JsonValueTypes.UINT16);
+        result.writeShortLE(65535);
+        return result;
+    }
+    
+    private static ByteBuf mockTopLevelStringByteBuf() {
+        ByteBuf result = Unpooled.buffer();
+        result.writeByte(JsonValueTypes.STRING);
+        result.writeByte("a\"\\b".length());
+        result.writeBytes("a\"\\b".getBytes());
+        return result;
+    }
+    
+    private static ByteBuf mockUnsupportedTopLevelTypeByteBuf() {
+        ByteBuf result = Unpooled.buffer();
+        result.writeByte(JsonValueTypes.CUSTOM_DATA);
+        return result;
     }
 }

Reply via email to