@@ -701,6 +701,183 @@ public void testLongArrayShrinkingSize() throws Exception {
701701 });
702702 }
703703
704+ @ Test
705+ public void testGetExistingColumnReturnsOrderedColumnsAcrossRows () throws Exception {
706+ assertMemoryLeak (() -> {
707+ try (QwpTableBuffer table = new QwpTableBuffer ("test" )) {
708+ QwpTableBuffer .ColumnBuffer colA = table .getOrCreateColumn ("a" , QwpConstants .TYPE_LONG , false );
709+ QwpTableBuffer .ColumnBuffer colB = table .getOrCreateColumn ("b" , QwpConstants .TYPE_STRING , true );
710+ colA .addLong (1 );
711+ colB .addString ("x" );
712+ table .nextRow ();
713+
714+ QwpTableBuffer .ColumnBuffer existingA = table .getExistingColumn ("a" , QwpConstants .TYPE_LONG );
715+ QwpTableBuffer .ColumnBuffer existingB = table .getExistingColumn ("b" , QwpConstants .TYPE_STRING );
716+
717+ assertSame (colA , existingA );
718+ assertSame (colB , existingB );
719+
720+ existingA .addLong (2 );
721+ existingB .addString ("y" );
722+ table .nextRow ();
723+
724+ assertEquals (2 , table .getRowCount ());
725+ assertEquals (2 , colA .getSize ());
726+ assertEquals (2 , colA .getValueCount ());
727+ assertEquals (2 , colB .getSize ());
728+ assertEquals (2 , colB .getValueCount ());
729+ }
730+ });
731+ }
732+
733+ @ Test
734+ public void testGetExistingColumnReturnsOutOfOrderColumns () throws Exception {
735+ assertMemoryLeak (() -> {
736+ try (QwpTableBuffer table = new QwpTableBuffer ("test" )) {
737+ QwpTableBuffer .ColumnBuffer colA = table .getOrCreateColumn ("a" , QwpConstants .TYPE_LONG , false );
738+ QwpTableBuffer .ColumnBuffer colB = table .getOrCreateColumn ("b" , QwpConstants .TYPE_STRING , true );
739+ colA .addLong (1 );
740+ colB .addString ("x" );
741+ table .nextRow ();
742+
743+ QwpTableBuffer .ColumnBuffer existingB = table .getExistingColumn ("b" , QwpConstants .TYPE_STRING );
744+ QwpTableBuffer .ColumnBuffer existingA = table .getExistingColumn ("a" , QwpConstants .TYPE_LONG );
745+
746+ assertSame (colB , existingB );
747+ assertSame (colA , existingA );
748+
749+ existingB .addString ("y" );
750+ existingA .addLong (2 );
751+ table .nextRow ();
752+
753+ assertEquals (2 , table .getRowCount ());
754+ assertEquals (2 , colA .getSize ());
755+ assertEquals (2 , colA .getValueCount ());
756+ assertEquals (2 , colB .getSize ());
757+ assertEquals (2 , colB .getValueCount ());
758+ }
759+ });
760+ }
761+
762+ @ Test
763+ public void testGetExistingColumnReturnsNullWithoutCreatingColumn () throws Exception {
764+ assertMemoryLeak (() -> {
765+ try (QwpTableBuffer table = new QwpTableBuffer ("test" )) {
766+ QwpTableBuffer .ColumnBuffer colA = table .getOrCreateColumn ("a" , QwpConstants .TYPE_LONG , false );
767+ colA .addLong (1 );
768+ table .nextRow ();
769+
770+ assertNull (table .getExistingColumn ("missing" , QwpConstants .TYPE_STRING ));
771+ assertEquals (1 , table .getColumnCount ());
772+
773+ QwpTableBuffer .ColumnBuffer colB = table .getOrCreateColumn ("b" , QwpConstants .TYPE_STRING , true );
774+ assertNotNull (colB );
775+ assertEquals (2 , table .getColumnCount ());
776+ }
777+ });
778+ }
779+
780+ @ Test
781+ public void testGetExistingColumnTypeMismatchOnOrderedPathThrows () throws Exception {
782+ assertMemoryLeak (() -> {
783+ try (QwpTableBuffer table = new QwpTableBuffer ("test" )) {
784+ QwpTableBuffer .ColumnBuffer colA = table .getOrCreateColumn ("a" , QwpConstants .TYPE_LONG , false );
785+ table .getOrCreateColumn ("b" , QwpConstants .TYPE_STRING , true );
786+ colA .addLong (1 );
787+ table .nextRow ();
788+
789+ try {
790+ table .getExistingColumn ("a" , QwpConstants .TYPE_STRING );
791+ fail ("Expected LineSenderException for ordered-path type mismatch" );
792+ } catch (LineSenderException e ) {
793+ assertTrue (e .getMessage ().contains ("Column type mismatch" ));
794+ assertTrue (e .getMessage ().contains ("column 'a'" ));
795+ }
796+ }
797+ });
798+ }
799+
800+ @ Test
801+ public void testGetExistingColumnTypeMismatchOnHashPathThrows () throws Exception {
802+ assertMemoryLeak (() -> {
803+ try (QwpTableBuffer table = new QwpTableBuffer ("test" )) {
804+ QwpTableBuffer .ColumnBuffer colA = table .getOrCreateColumn ("a" , QwpConstants .TYPE_LONG , false );
805+ QwpTableBuffer .ColumnBuffer colB = table .getOrCreateColumn ("b" , QwpConstants .TYPE_STRING , true );
806+ colA .addLong (1 );
807+ colB .addString ("x" );
808+ table .nextRow ();
809+
810+ try {
811+ table .getExistingColumn ("b" , QwpConstants .TYPE_LONG );
812+ fail ("Expected LineSenderException for hash-path type mismatch" );
813+ } catch (LineSenderException e ) {
814+ assertTrue (e .getMessage ().contains ("Column type mismatch" ));
815+ assertTrue (e .getMessage ().contains ("column 'b'" ));
816+ }
817+ }
818+ });
819+ }
820+
821+ @ Test
822+ public void testGetExistingColumnWorksAfterReset () throws Exception {
823+ assertMemoryLeak (() -> {
824+ try (QwpTableBuffer table = new QwpTableBuffer ("test" )) {
825+ QwpTableBuffer .ColumnBuffer colA = table .getOrCreateColumn ("a" , QwpConstants .TYPE_LONG , false );
826+ QwpTableBuffer .ColumnBuffer colB = table .getOrCreateColumn ("b" , QwpConstants .TYPE_STRING , true );
827+ colA .addLong (1 );
828+ colB .addString ("x" );
829+ table .nextRow ();
830+
831+ table .reset ();
832+
833+ QwpTableBuffer .ColumnBuffer existingA = table .getExistingColumn ("a" , QwpConstants .TYPE_LONG );
834+ QwpTableBuffer .ColumnBuffer existingB = table .getExistingColumn ("b" , QwpConstants .TYPE_STRING );
835+
836+ assertSame (colA , existingA );
837+ assertSame (colB , existingB );
838+
839+ existingA .addLong (2 );
840+ existingB .addString ("y" );
841+ table .nextRow ();
842+
843+ assertEquals (1 , table .getRowCount ());
844+ assertEquals (1 , colA .getSize ());
845+ assertEquals (1 , colA .getValueCount ());
846+ assertEquals (1 , colB .getSize ());
847+ assertEquals (1 , colB .getValueCount ());
848+ }
849+ });
850+ }
851+
852+ @ Test
853+ public void testGetExistingColumnWorksForLateAddedColumnAfterCancelRow () throws Exception {
854+ assertMemoryLeak (() -> {
855+ try (QwpTableBuffer table = new QwpTableBuffer ("test" )) {
856+ table .getOrCreateColumn ("a" , QwpConstants .TYPE_LONG , false ).addLong (1 );
857+ table .nextRow ();
858+
859+ table .getOrCreateColumn ("a" , QwpConstants .TYPE_LONG , false ).addLong (2 );
860+ QwpTableBuffer .ColumnBuffer late = table .getOrCreateColumn ("late" , QwpConstants .TYPE_STRING , true );
861+ late .addString ("stale" );
862+ table .cancelCurrentRow ();
863+
864+ QwpTableBuffer .ColumnBuffer existingLate = table .getExistingColumn ("late" , QwpConstants .TYPE_STRING );
865+ assertSame (late , existingLate );
866+ assertEquals (0 , existingLate .getSize ());
867+ assertEquals (0 , existingLate .getValueCount ());
868+
869+ table .getExistingColumn ("a" , QwpConstants .TYPE_LONG ).addLong (2 );
870+ table .nextRow ();
871+
872+ assertEquals (2 , table .getRowCount ());
873+ assertEquals (2 , existingLate .getSize ());
874+ assertEquals (0 , existingLate .getValueCount ());
875+ assertTrue (existingLate .isNull (0 ));
876+ assertTrue (existingLate .isNull (1 ));
877+ }
878+ });
879+ }
880+
704881 /**
705882 * Simulates the encoder's walk over array data — the same logic as
706883 * QwpWebSocketEncoder.writeDoubleArrayColumn(). Returns the flat
0 commit comments