Copilot commented on code in PR #7836:
URL: https://github.com/apache/ignite-3/pull/7836#discussion_r2965382098


##########
modules/compatibility-tests/src/integrationTest/java/org/apache/ignite/internal/client/ClientCompatibilityTests.java:
##########
@@ -236,6 +237,50 @@ default void testSqlBatch() {
         assertEquals(2, rows.size());
     }
 
+    @Test
+    default void testSqlBatchException() {
+        // Insert initial row to trigger constraint violation
+        int duplicateId = idGen().incrementAndGet();
+        client().sql().execute("INSERT INTO " + TABLE_NAME_TEST + " (id, name) 
VALUES (?, ?)", duplicateId, "initial");
+
+        // Create batch where some rows will succeed and one will fail with 
duplicate key
+        int id1 = idGen().incrementAndGet();
+        int id2 = idGen().incrementAndGet();
+        int id3 = idGen().incrementAndGet();
+        int id4 = idGen().incrementAndGet();
+
+        BatchedArguments args = BatchedArguments.create()
+                .add(id1, "test1")
+                .add(id2, "test2")
+                .add(id3, "test3")
+                .add(duplicateId, "duplicate") // This will fail - duplicate 
primary key
+                .add(id4, "test4"); // This won't be executed due to error
+
+        var ex = assertThrows(
+                SqlBatchException.class,
+                () -> client().sql().executeBatch("INSERT INTO " + 
TABLE_NAME_TEST + " (id, name) VALUES (?, ?)", args));
+

Review Comment:
   This new compatibility test calls `client().sql().execute(String, ...)` and 
`client().sql().executeBatch(String, ...)`. In the compatibility suite, tests 
are executed with older client binaries; these convenience overloads may not 
exist in some base versions, leading to `NoSuchMethodError` even when the 
transaction/cancellation-token overloads exist. To keep the test runnable 
across all supported base versions, use the explicit overloads already used 
elsewhere in this file (e.g., `execute((Transaction) null, ...)` and 
`executeBatch((Transaction) null, ...)`).



##########
modules/client-common/src/main/java/org/apache/ignite/internal/client/proto/ClientMessageUnpacker.java:
##########
@@ -791,6 +791,24 @@ public long[] unpackLongArray() {
         return res;
     }
 
+    /**
+     * Reads a long array from a single binary value.
+     *
+     * @return Array of longs.
+     */
+    public long[] unpackLongArrayAsBinary() {
+        assert refCnt > 0 : "Unpacker is closed";
+
+        int binSize = unpackBinaryHeader();
+        long[] res = new long[binSize / 8];
+
+        for (int i = 0; i < res.length; i++) {
+            res[i] = buf.readLong();
+        }
+
+        return res;
+    }

Review Comment:
   `unpackLongArrayAsBinary()` calculates the array length as `binSize / 8` but 
does not validate that `binSize` is a multiple of 8. If the payload size is 
malformed (or if the encoding changes), the method will leave unread trailing 
bytes in the buffer and corrupt subsequent unpacking. Add a guard (e.g., throw 
when `binSize % Long.BYTES != 0`) and consider using `Long.BYTES` instead of 
the magic number.



##########
modules/client-common/src/main/java/org/apache/ignite/internal/client/proto/ClientMessagePacker.java:
##########
@@ -630,6 +630,27 @@ public void packLongArray(long[] arr) {
         }
     }
 
+    /**
+     * Writes a long array as a single binary value.
+     *
+     * @param arr Long array value.
+     */
+    public void packLongArrayAsBinary(long[] arr) {
+        assert !closed : "Packer is closed";
+
+        if (arr == null) {
+            packNil();
+
+            return;
+        }
+
+        packBinaryHeader(arr.length * 8);
+
+        for (long value : arr) {
+            buf.writeLong(value);
+        }
+    }

Review Comment:
   `packLongArrayAsBinary()` writes raw `long` bytes without 
documenting/standardizing endianness (it currently relies on Netty's default 
big-endian `writeLong`). Since this is part of the cross-language client 
protocol, please explicitly define the byte order in the protocol/Javadoc and 
use the corresponding `writeLongLE`/`readLongLE` or `writeLong`/`readLong` 
consistently on both sides.



##########
modules/client-common/src/main/java/org/apache/ignite/internal/client/proto/ClientMessageUnpacker.java:
##########
@@ -791,6 +791,24 @@ public long[] unpackLongArray() {
         return res;
     }
 
+    /**
+     * Reads a long array from a single binary value.
+     *
+     * @return Array of longs.
+     */
+    public long[] unpackLongArrayAsBinary() {
+        assert refCnt > 0 : "Unpacker is closed";
+
+        int binSize = unpackBinaryHeader();
+        long[] res = new long[binSize / 8];
+
+        for (int i = 0; i < res.length; i++) {
+            res[i] = buf.readLong();
+        }
+
+        return res;
+    }

Review Comment:
   `unpackLongArrayAsBinary()` assumes the next value is a binary and does not 
handle `nil`. Since `packLongArrayAsBinary()` can write `nil` (when the array 
is null), the unpacker should either support `nil` (e.g., return null/empty) or 
the caller should check `tryUnpackNil()` before calling this method to avoid 
protocol desync/type exceptions.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to