@@ -171,6 +171,7 @@ type HostInfo struct {
171171 port int
172172 dataCenter string
173173 rack string
174+ missingRack bool
174175 hostId string
175176 workload string
176177 graph bool
@@ -413,8 +414,9 @@ func (h *HostInfo) update(from *HostInfo) {
413414 if h .dataCenter == "" {
414415 h .dataCenter = from .dataCenter
415416 }
416- if h .rack == "" {
417+ if h .missingRack || h . rack == "" {
417418 h .rack = from .rack
419+ h .missingRack = from .missingRack
418420 }
419421 if h .hostId == "" {
420422 h .hostId = from .hostId
@@ -530,7 +532,7 @@ func newHostInfoFromRow(s *Session, defaultAddr net.IP, defaultPort int, row map
530532 const assertErrorMsg = "Assertion failed for %s, type was %T"
531533 var ok bool
532534
533- host := & HostInfo {connectAddress : defaultAddr , port : defaultPort }
535+ host := & HostInfo {connectAddress : defaultAddr , port : defaultPort , missingRack : true }
534536
535537 // Process all fields from the row
536538 for key , value := range row {
@@ -541,14 +543,30 @@ func newHostInfoFromRow(s *Session, defaultAddr net.IP, defaultPort int, row map
541543 return nil , fmt .Errorf (assertErrorMsg , "data_center" , value )
542544 }
543545 case "rack" :
544- host . rack , ok = value .(string )
546+ rack , ok : = value .(* string )
545547 if ! ok {
546- return nil , fmt .Errorf (assertErrorMsg , "rack" , value )
548+ if rack , ok := value .(string ); ! ok {
549+ return nil , fmt .Errorf (assertErrorMsg , "rack" , value )
550+ } else {
551+ host .rack = rack
552+ host .missingRack = false
553+ }
554+ } else if rack != nil {
555+ host .rack = * rack
556+ host .missingRack = false
547557 }
548558 case "host_id" :
549559 hostId , ok := value .(UUID )
550560 if ! ok {
551- return nil , fmt .Errorf (assertErrorMsg , "host_id" , value )
561+ if str , ok := value .(string ); ok {
562+ var err error
563+ hostId , err = ParseUUID (str )
564+ if err != nil {
565+ return nil , fmt .Errorf ("failed to parse host_id: %w" , err )
566+ }
567+ } else {
568+ return nil , fmt .Errorf (assertErrorMsg , "host_id" , value )
569+ }
552570 }
553571 host .hostId = hostId .String ()
554572 case "release_version" :
@@ -560,7 +578,11 @@ func newHostInfoFromRow(s *Session, defaultAddr net.IP, defaultPort int, row map
560578 case "peer" :
561579 ip , ok := value .(net.IP )
562580 if ! ok {
563- return nil , fmt .Errorf (assertErrorMsg , "peer" , value )
581+ if str , ok := value .(string ); ok {
582+ ip = net .ParseIP (str )
583+ } else {
584+ return nil , fmt .Errorf (assertErrorMsg , "peer" , value )
585+ }
564586 }
565587 host .peer = ip
566588 case "cluster_name" :
@@ -576,31 +598,51 @@ func newHostInfoFromRow(s *Session, defaultAddr net.IP, defaultPort int, row map
576598 case "broadcast_address" :
577599 ip , ok := value .(net.IP )
578600 if ! ok {
579- return nil , fmt .Errorf (assertErrorMsg , "broadcast_address" , value )
601+ if str , ok := value .(string ); ok {
602+ ip = net .ParseIP (str )
603+ } else {
604+ return nil , fmt .Errorf (assertErrorMsg , "broadcast_address" , value )
605+ }
580606 }
581607 host .broadcastAddress = ip
582608 case "preferred_ip" :
583609 ip , ok := value .(net.IP )
584610 if ! ok {
585- return nil , fmt .Errorf (assertErrorMsg , "preferred_ip" , value )
611+ if str , ok := value .(string ); ok {
612+ ip = net .ParseIP (str )
613+ } else {
614+ return nil , fmt .Errorf (assertErrorMsg , "preferred_ip" , value )
615+ }
586616 }
587617 host .preferredIP = ip
588618 case "rpc_address" :
589619 ip , ok := value .(net.IP )
590620 if ! ok {
591- return nil , fmt .Errorf (assertErrorMsg , "rpc_address" , value )
621+ if str , ok := value .(string ); ok {
622+ ip = net .ParseIP (str )
623+ } else {
624+ return nil , fmt .Errorf (assertErrorMsg , "rpc_address" , value )
625+ }
592626 }
593627 host .rpcAddress = ip
594628 case "native_address" :
595629 ip , ok := value .(net.IP )
596630 if ! ok {
597- return nil , fmt .Errorf (assertErrorMsg , "native_address" , value )
631+ if str , ok := value .(string ); ok {
632+ ip = net .ParseIP (str )
633+ } else {
634+ return nil , fmt .Errorf (assertErrorMsg , "native_address" , value )
635+ }
598636 }
599637 host .rpcAddress = ip
600638 case "listen_address" :
601639 ip , ok := value .(net.IP )
602640 if ! ok {
603- return nil , fmt .Errorf (assertErrorMsg , "listen_address" , value )
641+ if str , ok := value .(string ); ok {
642+ ip = net .ParseIP (str )
643+ } else {
644+ return nil , fmt .Errorf (assertErrorMsg , "listen_address" , value )
645+ }
604646 }
605647 host .listenAddress = ip
606648 case "native_port" :
@@ -667,17 +709,22 @@ func newHostInfoFromRow(s *Session, defaultAddr net.IP, defaultPort int, row map
667709}
668710
669711func (s * Session ) hostInfoFromIter (iter * Iter , connectAddress net.IP , defaultPort int ) (* HostInfo , error ) {
670- rows , err := iter .SliceMap ()
671- if err != nil {
672- // TODO(zariel): make typed error
673- return nil , err
712+ // TODO: switch this to a new iterator method once CASSGO-36 is solved
713+ m := map [string ]interface {}{
714+ // we set rack to a pointer so we can know if it's NULL or not since we
715+ // need to be able to filter out NULL rack hosts but not empty string hosts
716+ // see CASSGO-6
717+ "rack" : new (string ),
674718 }
675-
676- if len (rows ) == 0 {
719+ if ! iter .MapScan (m ) {
677720 return nil , errors .New ("query returned 0 rows" )
678721 }
722+ if err := iter .Close (); err != nil {
723+ // TODO(zariel): make typed error
724+ return nil , err
725+ }
679726
680- host , err := s .newHostInfoFromMap (connectAddress , defaultPort , rows [ 0 ] )
727+ host , err := s .newHostInfoFromMap (connectAddress , defaultPort , m )
681728 if err != nil {
682729 return nil , err
683730 }
@@ -720,8 +767,21 @@ func (r *ringDescriber) getClusterPeerInfo(localHost *HostInfo) ([]*HostInfo, er
720767 return nil , errNoControl
721768 }
722769
723- rows , err := iter .SliceMap ()
724- if err != nil {
770+ // TODO: switch this to a new iterator method once CASSGO-36 is solved
771+ var rows []map [string ]interface {}
772+ for {
773+ m := map [string ]interface {}{
774+ // we set rack to a pointer so we can know if it's NULL or not since we
775+ // need to be able to filter out NULL rack hosts but not empty string hosts
776+ // see CASSGO-6
777+ "rack" : new (string ),
778+ }
779+ if ! iter .MapScan (m ) {
780+ break
781+ }
782+ rows = append (rows , m )
783+ }
784+ if err := iter .Close (); err != nil {
725785 // TODO(zariel): make typed error
726786 return nil , fmt .Errorf ("unable to fetch peer host info: %s" , err )
727787 }
@@ -749,7 +809,7 @@ func isValidPeer(host *HostInfo) bool {
749809 return ! (len (host .RPCAddress ()) == 0 ||
750810 host .hostId == "" ||
751811 host .dataCenter == "" ||
752- host .rack == "" ||
812+ host .missingRack ||
753813 len (host .tokens ) == 0 )
754814}
755815
0 commit comments