1515import java .time .LocalDateTime ;
1616import java .time .ZonedDateTime ;
1717import java .util .Arrays ;
18+ import java .util .List ;
1819import java .util .TimeZone ;
1920import java .util .function .Consumer ;
2021
@@ -576,4 +577,273 @@ public void testGetObjectArrayPrimitiveTypes() throws Exception {
576577 Assert .assertEquals (floatResult [0 ], 1.5 );
577578 Assert .assertEquals (floatResult [1 ], 2.5 );
578579 }
580+
581+ @ Test
582+ public void testReadingArraysByIndex () throws Exception {
583+ ByteArrayOutputStream out = new ByteArrayOutputStream ();
584+ String [] names = new String []{"a1" , "a2" , "a3" , "a4" , "a5" , "a6" , "a7" , "a8" };
585+ String [] types = new String []{"Array(Int8)" , "Array(String)" , "Array(Int16)" , "Array(Int32)" ,
586+ "Array(Int64)" , "Array(Float32)" , "Array(Float64)" , "Array(Bool)" };
587+
588+ BinaryStreamUtils .writeVarInt (out , names .length );
589+ for (String name : names ) {
590+ BinaryStreamUtils .writeString (out , name );
591+ }
592+ for (String type : types ) {
593+ BinaryStreamUtils .writeString (out , type );
594+ }
595+
596+ // write data
597+ BinaryStreamUtils .writeVarInt (out , 2 );
598+ BinaryStreamUtils .writeInt8 (out , (byte ) 1 );
599+ BinaryStreamUtils .writeInt8 (out , (byte ) 2 );
600+
601+ BinaryStreamUtils .writeVarInt (out , 2 );
602+ BinaryStreamUtils .writeString (out , "a" );
603+ BinaryStreamUtils .writeString (out , "b" );
604+
605+ BinaryStreamUtils .writeVarInt (out , 2 );
606+ BinaryStreamUtils .writeInt16 (out , (short ) 1 );
607+ BinaryStreamUtils .writeInt16 (out , (short ) 2 );
608+
609+ BinaryStreamUtils .writeVarInt (out , 2 );
610+ BinaryStreamUtils .writeInt32 (out , (int ) 1 );
611+ BinaryStreamUtils .writeInt32 (out , (int ) 2 );
612+
613+ BinaryStreamUtils .writeVarInt (out , 2 );
614+ BinaryStreamUtils .writeInt64 (out , (long ) 1 );
615+ BinaryStreamUtils .writeInt64 (out , (long ) 2 );
616+
617+ BinaryStreamUtils .writeVarInt (out , 2 );
618+ BinaryStreamUtils .writeFloat32 (out , 1.5f );
619+ BinaryStreamUtils .writeFloat32 (out , 2.5f );
620+
621+ BinaryStreamUtils .writeVarInt (out , 2 );
622+ BinaryStreamUtils .writeFloat64 (out , 1.5 );
623+ BinaryStreamUtils .writeFloat64 (out , 2.5 );
624+
625+ BinaryStreamUtils .writeVarInt (out , 2 );
626+ BinaryStreamUtils .writeBoolean (out , true );
627+ BinaryStreamUtils .writeBoolean (out , false );
628+
629+ InputStream in = new ByteArrayInputStream (out .toByteArray ());
630+ QuerySettings querySettings = new QuerySettings ().setUseTimeZone (TimeZone .getTimeZone ("UTC" ).toZoneId ().getId ());
631+ RowBinaryWithNamesAndTypesFormatReader reader =
632+ new RowBinaryWithNamesAndTypesFormatReader (in , querySettings , new BinaryStreamReader .CachingByteBufferAllocator ());
633+
634+ reader .next ();
635+
636+ // Test all array methods with index parameters
637+ Assert .assertEquals (reader .getByteArray (1 ), new byte [] {(byte ) 1 , (byte ) 2 });
638+ Assert .assertEquals (reader .getStringArray (2 ), new String [] {"a" , "b" });
639+ Assert .assertEquals (reader .getShortArray (3 ), new short [] {(short ) 1 , (short ) 2 });
640+ Assert .assertEquals (reader .getIntArray (4 ), new int [] {1 , 2 });
641+ Assert .assertEquals (reader .getLongArray (5 ), new long [] {1L , 2L });
642+ Assert .assertEquals (reader .getFloatArray (6 ), new float [] {1.5f , 2.5f });
643+ Assert .assertEquals (reader .getDoubleArray (7 ), new double [] {1.5 , 2.5 }, 0.001 );
644+ Assert .assertEquals (reader .getBooleanArray (8 ), new boolean [] {true , false });
645+ }
646+
647+ @ Test
648+ public void testGetObjectArrayByIndex () throws Exception {
649+ ByteArrayOutputStream out = new ByteArrayOutputStream ();
650+
651+ String [] names = new String []{"uint64_arr" , "enum_arr" , "dt_arr" , "str_arr" };
652+ String [] types = new String []{
653+ "Array(UInt64)" ,
654+ "Array(Enum8('abc' = 1, 'cde' = 2))" ,
655+ "Array(DateTime('UTC'))" ,
656+ "Array(String)"
657+ };
658+
659+ BinaryStreamUtils .writeVarInt (out , names .length );
660+ for (String name : names ) {
661+ BinaryStreamUtils .writeString (out , name );
662+ }
663+ for (String type : types ) {
664+ BinaryStreamUtils .writeString (out , type );
665+ }
666+
667+ // Array(UInt64): [100, 200]
668+ BinaryStreamUtils .writeVarInt (out , 2 );
669+ BinaryStreamUtils .writeUnsignedInt64 (out , BigInteger .valueOf (100 ));
670+ BinaryStreamUtils .writeUnsignedInt64 (out , BigInteger .valueOf (200 ));
671+
672+ // Array(Enum8('abc' = 1, 'cde' = 2)): [1, 2]
673+ BinaryStreamUtils .writeVarInt (out , 2 );
674+ BinaryStreamUtils .writeEnum8 (out , (byte ) 1 );
675+ BinaryStreamUtils .writeEnum8 (out , (byte ) 2 );
676+
677+ // Array(DateTime('UTC')): two timestamps
678+ LocalDateTime dt1 = LocalDateTime .of (2030 , 10 , 9 , 8 , 7 , 6 );
679+ LocalDateTime dt2 = LocalDateTime .of (2031 , 10 , 9 , 8 , 7 , 6 );
680+ BinaryStreamUtils .writeVarInt (out , 2 );
681+ BinaryStreamUtils .writeDateTime32 (out , dt1 , TimeZone .getTimeZone ("UTC" ));
682+ BinaryStreamUtils .writeDateTime32 (out , dt2 , TimeZone .getTimeZone ("UTC" ));
683+
684+ // Array(String): ["hello", "world"]
685+ BinaryStreamUtils .writeVarInt (out , 2 );
686+ BinaryStreamUtils .writeString (out , "hello" );
687+ BinaryStreamUtils .writeString (out , "world" );
688+
689+ InputStream in = new ByteArrayInputStream (out .toByteArray ());
690+ QuerySettings querySettings = new QuerySettings ().setUseTimeZone ("UTC" );
691+ RowBinaryWithNamesAndTypesFormatReader reader =
692+ new RowBinaryWithNamesAndTypesFormatReader (in , querySettings , new BinaryStreamReader .CachingByteBufferAllocator ());
693+ reader .next ();
694+
695+ // Test getObjectArray with index parameters
696+ Object [] uint64Result = reader .getObjectArray (1 );
697+ Assert .assertNotNull (uint64Result );
698+ Assert .assertEquals (uint64Result .length , 2 );
699+ Assert .assertEquals (uint64Result [0 ], BigInteger .valueOf (100 ));
700+ Assert .assertEquals (uint64Result [1 ], BigInteger .valueOf (200 ));
701+
702+ Object [] enumResult = reader .getObjectArray (2 );
703+ Assert .assertNotNull (enumResult );
704+ Assert .assertEquals (enumResult .length , 2 );
705+ Assert .assertTrue (enumResult [0 ] instanceof BinaryStreamReader .EnumValue );
706+ Assert .assertEquals (enumResult [0 ].toString (), "abc" );
707+ Assert .assertEquals (enumResult [1 ].toString (), "cde" );
708+
709+ Object [] dtResult = reader .getObjectArray (3 );
710+ Assert .assertNotNull (dtResult );
711+ Assert .assertEquals (dtResult .length , 2 );
712+ Assert .assertTrue (dtResult [0 ] instanceof ZonedDateTime );
713+ ZonedDateTime zdt1 = (ZonedDateTime ) dtResult [0 ];
714+ ZonedDateTime zdt2 = (ZonedDateTime ) dtResult [1 ];
715+ Assert .assertEquals (zdt1 .toLocalDateTime (), dt1 );
716+ Assert .assertEquals (zdt2 .toLocalDateTime (), dt2 );
717+
718+ Object [] strResult = reader .getObjectArray (4 );
719+ Assert .assertNotNull (strResult );
720+ Assert .assertEquals (strResult .length , 2 );
721+ Assert .assertEquals (strResult [0 ], "hello" );
722+ Assert .assertEquals (strResult [1 ], "world" );
723+ }
724+
725+ @ Test
726+ public void testGetListByIndex () throws Exception {
727+ ByteArrayOutputStream out = new ByteArrayOutputStream ();
728+
729+ String [] names = new String []{"int_list" , "string_list" , "nested_list" };
730+ String [] types = new String []{"Array(Int32)" , "Array(String)" , "Array(Array(Int64))" };
731+
732+ BinaryStreamUtils .writeVarInt (out , names .length );
733+ for (String name : names ) {
734+ BinaryStreamUtils .writeString (out , name );
735+ }
736+ for (String type : types ) {
737+ BinaryStreamUtils .writeString (out , type );
738+ }
739+
740+ // Array(Int32): [10, 20, 30]
741+ BinaryStreamUtils .writeVarInt (out , 3 );
742+ BinaryStreamUtils .writeInt32 (out , 10 );
743+ BinaryStreamUtils .writeInt32 (out , 20 );
744+ BinaryStreamUtils .writeInt32 (out , 30 );
745+
746+ // Array(String): ["a", "b", "c"]
747+ BinaryStreamUtils .writeVarInt (out , 3 );
748+ BinaryStreamUtils .writeString (out , "a" );
749+ BinaryStreamUtils .writeString (out , "b" );
750+ BinaryStreamUtils .writeString (out , "c" );
751+
752+ // Array(Array(Int64)): [[1, 2], [3, 4]]
753+ BinaryStreamUtils .writeVarInt (out , 2 ); // outer array length
754+ BinaryStreamUtils .writeVarInt (out , 2 ); // inner[0] length
755+ BinaryStreamUtils .writeInt64 (out , 1L );
756+ BinaryStreamUtils .writeInt64 (out , 2L );
757+ BinaryStreamUtils .writeVarInt (out , 2 ); // inner[1] length
758+ BinaryStreamUtils .writeInt64 (out , 3L );
759+ BinaryStreamUtils .writeInt64 (out , 4L );
760+
761+ InputStream in = new ByteArrayInputStream (out .toByteArray ());
762+ QuerySettings querySettings = new QuerySettings ().setUseTimeZone ("UTC" );
763+ RowBinaryWithNamesAndTypesFormatReader reader =
764+ new RowBinaryWithNamesAndTypesFormatReader (in , querySettings , new BinaryStreamReader .CachingByteBufferAllocator ());
765+ reader .next ();
766+
767+ // Test getList with index parameters
768+ List <Integer > intList = reader .getList (1 );
769+ Assert .assertEquals (intList , Arrays .asList (10 , 20 , 30 ));
770+
771+ List <String > stringList = reader .getList (2 );
772+ Assert .assertEquals (stringList , Arrays .asList ("a" , "b" , "c" ));
773+
774+ List <List <Long >> nestedList = reader .getList (3 );
775+ Assert .assertEquals (nestedList .size (), 2 );
776+ Assert .assertEquals (nestedList .get (0 ), Arrays .asList (1L , 2L ));
777+ Assert .assertEquals (nestedList .get (1 ), Arrays .asList (3L , 4L ));
778+ }
779+
780+ @ Test
781+ public void testArrayMethodsErrorConditions () throws Exception {
782+ ByteArrayOutputStream out = new ByteArrayOutputStream ();
783+ String [] names = new String []{"int_col" , "string_col" };
784+ String [] types = new String []{"Int32" , "String" };
785+
786+ BinaryStreamUtils .writeVarInt (out , names .length );
787+ for (String name : names ) {
788+ BinaryStreamUtils .writeString (out , name );
789+ }
790+ for (String type : types ) {
791+ BinaryStreamUtils .writeString (out , type );
792+ }
793+
794+ BinaryStreamUtils .writeInt32 (out , 42 );
795+ BinaryStreamUtils .writeString (out , "test" );
796+
797+ InputStream in = new ByteArrayInputStream (out .toByteArray ());
798+ QuerySettings querySettings = new QuerySettings ().setUseTimeZone ("UTC" );
799+ RowBinaryWithNamesAndTypesFormatReader reader =
800+ new RowBinaryWithNamesAndTypesFormatReader (in , querySettings , new BinaryStreamReader .CachingByteBufferAllocator ());
801+ reader .next ();
802+
803+ // Test that calling array methods on non-array columns throws exceptions
804+ Assert .assertThrows (Exception .class , () -> reader .getByteArray (1 ));
805+ Assert .assertThrows (Exception .class , () -> reader .getStringArray (1 ));
806+ Assert .assertThrows (Exception .class , () -> reader .getShortArray (1 ));
807+ Assert .assertThrows (Exception .class , () -> reader .getIntArray (1 ));
808+ Assert .assertThrows (Exception .class , () -> reader .getLongArray (1 ));
809+ Assert .assertThrows (Exception .class , () -> reader .getFloatArray (1 ));
810+ Assert .assertThrows (Exception .class , () -> reader .getDoubleArray (1 ));
811+ Assert .assertThrows (Exception .class , () -> reader .getBooleanArray (1 ));
812+ Assert .assertThrows (Exception .class , () -> reader .getObjectArray (1 ));
813+ Assert .assertThrows (Exception .class , () -> reader .getList (1 ));
814+ }
815+
816+ @ Test
817+ public void testEmptyArraysByIndex () throws Exception {
818+ ByteArrayOutputStream out = new ByteArrayOutputStream ();
819+ String [] names = new String []{"empty_int_arr" , "empty_str_arr" , "empty_obj_arr" };
820+ String [] types = new String []{"Array(Int32)" , "Array(String)" , "Array(Array(Int64))" };
821+
822+ BinaryStreamUtils .writeVarInt (out , names .length );
823+ for (String name : names ) {
824+ BinaryStreamUtils .writeString (out , name );
825+ }
826+ for (String type : types ) {
827+ BinaryStreamUtils .writeString (out , type );
828+ }
829+
830+ // Empty arrays
831+ BinaryStreamUtils .writeVarInt (out , 0 ); // empty_int_arr
832+ BinaryStreamUtils .writeVarInt (out , 0 ); // empty_str_arr
833+ BinaryStreamUtils .writeVarInt (out , 0 ); // empty_obj_arr
834+
835+ InputStream in = new ByteArrayInputStream (out .toByteArray ());
836+ QuerySettings querySettings = new QuerySettings ().setUseTimeZone ("UTC" );
837+ RowBinaryWithNamesAndTypesFormatReader reader =
838+ new RowBinaryWithNamesAndTypesFormatReader (in , querySettings , new BinaryStreamReader .CachingByteBufferAllocator ());
839+ reader .next ();
840+
841+ // Test empty arrays
842+ Assert .assertEquals (reader .getIntArray (1 ).length , 0 );
843+ Assert .assertEquals (reader .getStringArray (2 ).length , 0 );
844+ Assert .assertEquals (reader .getObjectArray (3 ).length , 0 );
845+ Assert .assertEquals (reader .getList (1 ).size (), 0 );
846+ Assert .assertEquals (reader .getList (2 ).size (), 0 );
847+ Assert .assertEquals (reader .getList (3 ).size (), 0 );
848+ }
579849}
0 commit comments