@@ -275,6 +275,39 @@ public void testHeapBufferFallbackDoesNotDetach() throws Exception {
275275 }
276276 }
277277
278+ /** Verifies fallback to InputStream path when getByteBuffer() returns null. */
279+ @ Test
280+ public void testNullByteBufferFallbackToInputStream () throws Exception {
281+ byte [] appMetadataBytes = new byte [] {20 , 21 , 22 };
282+ byte [] bodyBytes = new byte [] {30 , 31 , 32 , 33 };
283+ FlightDescriptor expectedDescriptor = createTestDescriptor ();
284+
285+ byte [] serialized = buildFlightDataWithBothFields (appMetadataBytes , bodyBytes );
286+ MockGrpcInputStream stream =
287+ new MockGrpcInputStream (
288+ ByteBuffer .wrap (serialized ),
289+ false );
290+
291+ try (ArrowMessage message = ArrowMessage .createMarshaller (allocator ).parse (stream )) {
292+ assertEquals (expectedDescriptor , message .getDescriptor ());
293+
294+ ArrowBuf appMetadata = message .getApplicationMetadata ();
295+ assertNotNull (appMetadata );
296+ byte [] actualAppMetadata = new byte [appMetadataBytes .length ];
297+ appMetadata .getBytes (0 , actualAppMetadata );
298+ assertArrayEquals (appMetadataBytes , actualAppMetadata );
299+
300+ ArrowBuf body = Iterables .getOnlyElement (message .getBufs ());
301+ assertNotNull (body );
302+ byte [] actualBody = new byte [bodyBytes .length ];
303+ body .getBytes (0 , actualBody );
304+ assertArrayEquals (bodyBytes , actualBody );
305+
306+ assertEquals (0 , stream .getDetachCount ());
307+ }
308+ assertEquals (0 , allocator .getAllocatedMemory ());
309+ }
310+
278311 // Helper methods to build complete FlightData messages
279312
280313 private FlightDescriptor createTestDescriptor () {
0 commit comments