@@ -790,3 +790,108 @@ func TestSSTBatcherCloseWithoutFlush(t *testing.T) {
790790 // There should be no rows written since all the flushes were blocked and cancelled.
791791 tdb .CheckQueryResults (t , `SELECT count(*) FROM kv` , [][]string {{"0" }})
792792}
793+
794+ func TestSSTBatcherSplitBetweenColumnFamilies (t * testing.T ) {
795+ defer leaktest .AfterTest (t )()
796+ defer log .Scope (t ).Close (t )
797+ ctx := context .Background ()
798+
799+ tc := testcluster .StartTestCluster (t , 5 , base.TestClusterArgs {})
800+ defer tc .Stopper ().Stop (ctx )
801+ s := tc .ApplicationLayer (0 )
802+ db := tc .ServerConn (0 )
803+ kvDB := s .DB ()
804+
805+ tdb := sqlutils .MakeSQLRunner (db )
806+
807+ // Create a table with multiple column families and a secondary index.
808+ tdb .Exec (t , `
809+ CREATE TABLE t (
810+ pk INT PRIMARY KEY,
811+ a INT,
812+ b STRING,
813+ INDEX idx_a (a),
814+ FAMILY f0 (pk, a),
815+ FAMILY f1 (b)
816+ )
817+ ` )
818+
819+ // Insert some rows.
820+ for i := 1 ; i <= 11 ; i ++ {
821+ tdb .Exec (t , `INSERT INTO t VALUES ($1, $2, $3)` , i , i * 10 , fmt .Sprintf ("b-%d" , i ))
822+ }
823+
824+ // Get the table descriptor to construct keys.
825+ tableDesc := desctestutils .TestingGetPublicTableDescriptor (kvDB , s .Codec (), "defaultdb" , "t" )
826+ tableID := tableDesc .GetID ()
827+
828+ // The primary index has ID 1.
829+ indexPrefix := s .Codec ().IndexPrefix (uint32 (tableID ), 1 )
830+
831+ // Create unsafe split keys between family 0 and family 1 for each row.
832+ for pk := 1 ; pk <= 11 ; pk ++ {
833+ pkKey := encoding .EncodeVarintAscending (append ([]byte {}, indexPrefix ... ), int64 (pk ))
834+ family0Key := keys .MakeFamilyKey (pkKey , 0 )
835+ unsafeSplitKey := roachpb .Key (family0Key ).Next ()
836+
837+ splitReq := & kvpb.AdminSplitRequest {
838+ RequestHeader : kvpb.RequestHeader {
839+ Key : unsafeSplitKey ,
840+ },
841+ SplitKey : unsafeSplitKey ,
842+ }
843+
844+ _ , pErr := kv .SendWrapped (ctx , kvDB .NonTransactionalSender (), splitReq )
845+ require .Nil (t , pErr , "AdminSplit at unsafe key should succeed" )
846+ }
847+
848+ // Use the first unsafe split key for subsequent checks.
849+ //pkKey := encoding.EncodeVarintAscending(append([]byte{}, indexPrefix...), 1)
850+ //family0Key := keys.MakeFamilyKey(pkKey, 0)
851+ //unsafeSplitKey := roachpb.Key(family0Key).Next()
852+ //t.Logf("Family 0 key for pk=1: %s", roachpb.Key(family0Key))
853+ //t.Logf("Unsafe split key: %s", unsafeSplitKey)
854+
855+ tdb .Exec (t , `ALTER TABLE t SCATTER` )
856+
857+ // Clear the range cache to ensure it's updated with all the new splits.
858+ // This ensures any subsequent operations have fresh range descriptor information.
859+ s .DistSenderI ().(* kvcoord.DistSender ).RangeDescriptorCache ().Clear ()
860+
861+ // Verify the split occurred by checking range boundaries.
862+ ranges := tdb .QueryStr (t , `SELECT start_key, end_key, replicas FROM [SHOW RANGES FROM TABLE t]` )
863+ t .Logf ("Ranges after split:" )
864+ for i , r := range ranges {
865+ t .Logf (" Range %d: [%s, %s), replicas %s" , i , r [0 ], r [1 ], r [2 ])
866+ }
867+
868+ tdb .Exec (t , `SET streamer_enabled = true` )
869+
870+ // Query each value of 'a' individually in a loop
871+ for pk := 1 ; pk <= 11 ; pk ++ {
872+ aValue := pk * 10
873+ row := tdb .QueryStr (t , `SELECT * FROM t WHERE a = $1` , aValue )
874+ expectedRow := [][]string {{fmt .Sprintf ("%d" , pk ), fmt .Sprintf ("%d" , aValue ), fmt .Sprintf ("b-%d" , pk )}}
875+ require .Equal (t , expectedRow , row , "row with pk=%d should have correct values" , pk )
876+ }
877+
878+ // Scan over the table key space and verify the row is split.
879+ //tableSpan := tableDesc.TableSpan(s.Codec())
880+
881+ //kvs, err := kvDB.Scan(ctx, tableSpan.Key, unsafeSplitKey, 0 /* maxRows */)
882+ //require.NoError(t, err)
883+
884+ //for i, kv := range kvs {
885+ // t.Logf("(Before Split Key) Key %d: %s (len=%d, value len=%d)", i, kv.Key, len(kv.Key), len(kv.Value.RawBytes))
886+ //}
887+
888+ //afterKvs, err := kvDB.Scan(ctx, unsafeSplitKey, tableSpan.EndKey, 0 /* maxRows */)
889+ //require.NoError(t, err)
890+
891+ // for i, kv := range afterKvs {
892+ // t.Logf("(After Split Key) Key %d: %s (len=%d, value len=%d)", i, kv.Key, len(kv.Key), len(kv.Value.RawBytes))
893+ //}
894+
895+ //err := sqlutils.RunInspect(db, "defaultdb", "t")
896+ //require.NoError(t, err)
897+ }
0 commit comments