@@ -29,16 +29,37 @@ import (
2929
3030// ParseDestination parses the string representation of a ShardDestination
3131// of the form keyspace:shard@tablet_type. You can use a / instead of a :.
32- func ParseDestination (targetString string , defaultTabletType topodatapb.TabletType ) (string , topodatapb.TabletType , key.ShardDestination , error ) {
32+ // It also supports tablet-specific routing with keyspace@tablet-alias where
33+ // tablet-alias is in the format cell-uid (e.g., zone1-0000000100).
34+ func ParseDestination (targetString string , defaultTabletType topodatapb.TabletType ) (string , topodatapb.TabletType , key.ShardDestination , * topodatapb.TabletAlias , error ) {
3335 var dest key.ShardDestination
3436 var keyspace string
37+ var tabletAlias * topodatapb.TabletAlias
3538 tabletType := defaultTabletType
3639
3740 last := strings .LastIndexAny (targetString , "@" )
3841 if last != - 1 {
39- // No need to check the error. UNKNOWN will be returned on
40- // error and it will fail downstream.
41- tabletType , _ = ParseTabletType (targetString [last + 1 :])
42+ afterAt := targetString [last + 1 :]
43+ // Try parsing as tablet type first (backward compatible)
44+ parsedTabletType , err := ParseTabletType (afterAt )
45+ // If tablet type parsing fails or returns UNKNOWN, try parsing as tablet alias
46+ if err != nil || parsedTabletType == topodatapb .TabletType_UNKNOWN {
47+ // Check if it looks like a tablet alias (contains a dash)
48+ if strings .Contains (afterAt , "-" ) {
49+ alias , aliasErr := ParseTabletAlias (afterAt )
50+ if aliasErr == nil {
51+ tabletAlias = alias
52+ // Keep tabletType as defaultTabletType when using tablet alias
53+ } else {
54+ // If both tablet type and tablet alias parsing fail, keep the UNKNOWN tablet type
55+ // which will cause appropriate error handling downstream
56+ tabletType = topodatapb .TabletType_UNKNOWN
57+ }
58+ }
59+ } else {
60+ // Successfully parsed as tablet type
61+ tabletType = parsedTabletType
62+ }
4263 targetString = targetString [:last ]
4364 }
4465 last = strings .LastIndexAny (targetString , "/:" )
@@ -51,29 +72,29 @@ func ParseDestination(targetString string, defaultTabletType topodatapb.TabletTy
5172 if last != - 1 {
5273 rangeEnd := strings .LastIndexAny (targetString , "]" )
5374 if rangeEnd == - 1 {
54- return keyspace , tabletType , dest , vterrors .Errorf (vtrpcpb .Code_INVALID_ARGUMENT , "invalid key range provided. Couldn't find range end ']'" )
75+ return keyspace , tabletType , dest , nil , vterrors .Errorf (vtrpcpb .Code_INVALID_ARGUMENT , "invalid key range provided. Couldn't find range end ']'" )
5576 }
5677 rangeString := targetString [last + 1 : rangeEnd ]
5778 if strings .Contains (rangeString , "-" ) {
5879 // Parse as range
5980 keyRange , err := key .ParseShardingSpec (rangeString )
6081 if err != nil {
61- return keyspace , tabletType , dest , err
82+ return keyspace , tabletType , dest , nil , err
6283 }
6384 if len (keyRange ) != 1 {
64- return keyspace , tabletType , dest , vterrors .Errorf (vtrpcpb .Code_INVALID_ARGUMENT , "single keyrange expected in %s" , rangeString )
85+ return keyspace , tabletType , dest , nil , vterrors .Errorf (vtrpcpb .Code_INVALID_ARGUMENT , "single keyrange expected in %s" , rangeString )
6586 }
6687 dest = key.DestinationExactKeyRange {KeyRange : keyRange [0 ]}
6788 } else {
6889 // Parse as keyspace id
6990 destBytes , err := hex .DecodeString (rangeString )
7091 if err != nil {
71- return keyspace , tabletType , dest , vterrors .Errorf (vtrpcpb .Code_INVALID_ARGUMENT , "expected valid hex in keyspace id %s" , rangeString )
92+ return keyspace , tabletType , dest , nil , vterrors .Errorf (vtrpcpb .Code_INVALID_ARGUMENT , "expected valid hex in keyspace id %s" , rangeString )
7293 }
7394 dest = key .DestinationKeyspaceID (destBytes )
7495 }
7596 targetString = targetString [:last ]
7697 }
7798 keyspace = targetString
78- return keyspace , tabletType , dest , nil
99+ return keyspace , tabletType , dest , tabletAlias , nil
79100}
0 commit comments