Skip to content

Commit faf1dcf

Browse files
committed
Unable to discover cluster nodes with an empty rack name fix
1 parent 63b6d78 commit faf1dcf

File tree

4 files changed

+88
-13
lines changed

4 files changed

+88
-13
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4848

4949
- gocql.Compressor interface changes to follow append-like design. Bumped Go version to 1.19 (CASSGO-1)
5050

51+
- Unable to discover cluster nodes with an empty rack name (CASSGO-6)
52+
5153
### Fixed
5254
- Cassandra version unmarshal fix (CASSGO-49)
5355

cluster_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
package gocql
2626

2727
import (
28+
"errors"
2829
"net"
2930
"reflect"
3031
"testing"
@@ -80,3 +81,59 @@ func TestClusterConfig_translateAddressAndPort_Success(t *testing.T) {
8081
assertTrue(t, "translated address", net.ParseIP("10.10.10.10").Equal(newAddr))
8182
assertEqual(t, "translated port", 5432, newPort)
8283
}
84+
85+
func TestEmptyRack(t *testing.T) {
86+
s := &Session{}
87+
host := &HostInfo{}
88+
89+
row := make(map[string]interface{})
90+
91+
row["preferred_ip"] = "172.3.0.2"
92+
row["rpc_address"] = "172.3.0.2"
93+
row["host_id"] = UUIDFromTime(time.Now())
94+
row["data_center"] = "dc1"
95+
row["tokens"] = []string{"t1", "t2"}
96+
row["rack"] = "rack1"
97+
98+
validHost, err := s.hostInfoFromMap(row, host)
99+
if err != nil {
100+
t.Fatal(err)
101+
}
102+
if !isValidPeer(validHost) {
103+
t.Fatal(errors.New("expected valid host"))
104+
}
105+
106+
row["rack"] = ""
107+
108+
validHost, err = s.hostInfoFromMap(row, host)
109+
if err != nil {
110+
t.Fatal(err)
111+
}
112+
if !isValidPeer(validHost) {
113+
t.Fatal(errors.New("expected valid host"))
114+
}
115+
116+
strPtr := new(string)
117+
*strPtr = "rack"
118+
row["rack"] = strPtr
119+
120+
validHost, err = s.hostInfoFromMap(row, host)
121+
if err != nil {
122+
t.Fatal(err)
123+
}
124+
if !isValidPeer(validHost) {
125+
t.Fatal(errors.New("expected valid host"))
126+
}
127+
128+
strPtr = new(string)
129+
strPtr = nil
130+
row["rack"] = strPtr
131+
132+
validHost, err = s.hostInfoFromMap(row, host)
133+
if err != nil {
134+
t.Fatal(err)
135+
}
136+
if isValidPeer(validHost) {
137+
t.Fatal(errors.New("expected valid host"))
138+
}
139+
}

helpers.go

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -332,23 +332,29 @@ func (iter *Iter) RowData() (RowData, error) {
332332
values := make([]interface{}, 0, len(iter.Columns()))
333333

334334
for _, column := range iter.Columns() {
335-
if c, ok := column.TypeInfo.(TupleTypeInfo); !ok {
336-
val, err := column.TypeInfo.NewWithError()
337-
if err != nil {
338-
iter.err = err
339-
return RowData{}, err
340-
}
335+
if column.Name == "rack" && column.Keyspace == "system" && (column.Table == "peers_v2" || column.Table == "peers") {
336+
var strPtr = new(string)
341337
columns = append(columns, column.Name)
342-
values = append(values, val)
338+
values = append(values, &strPtr)
343339
} else {
344-
for i, elem := range c.Elems {
345-
columns = append(columns, TupleColumnName(column.Name, i))
346-
val, err := elem.NewWithError()
340+
if c, ok := column.TypeInfo.(TupleTypeInfo); !ok {
341+
val, err := column.TypeInfo.NewWithError()
347342
if err != nil {
348343
iter.err = err
349344
return RowData{}, err
350345
}
346+
columns = append(columns, column.Name)
351347
values = append(values, val)
348+
} else {
349+
for i, elem := range c.Elems {
350+
columns = append(columns, TupleColumnName(column.Name, i))
351+
val, err := elem.NewWithError()
352+
if err != nil {
353+
iter.err = err
354+
return RowData{}, err
355+
}
356+
values = append(values, val)
357+
}
352358
}
353359
}
354360
}

host_source.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ type HostInfo struct {
179179
state nodeState
180180
schemaVersion string
181181
tokens []string
182+
isRackNil bool
182183
}
183184

184185
func newHostInfo(addr net.IP, port int) (*HostInfo, error) {
@@ -509,9 +510,18 @@ func (s *Session) hostInfoFromMap(row map[string]interface{}, host *HostInfo) (*
509510
return nil, fmt.Errorf(assertErrorMsg, "data_center")
510511
}
511512
case "rack":
512-
host.rack, ok = value.(string)
513+
rack, ok := value.(*string)
513514
if !ok {
514-
return nil, fmt.Errorf(assertErrorMsg, "rack")
515+
host.rack, ok = value.(string)
516+
if !ok {
517+
return nil, fmt.Errorf(assertErrorMsg, "rack")
518+
}
519+
} else {
520+
if rack != nil {
521+
host.rack = *rack
522+
} else {
523+
host.isRackNil = true
524+
}
515525
}
516526
case "host_id":
517527
hostId, ok := value.(UUID)
@@ -701,7 +711,7 @@ func isValidPeer(host *HostInfo) bool {
701711
return !(len(host.RPCAddress()) == 0 ||
702712
host.hostId == "" ||
703713
host.dataCenter == "" ||
704-
host.rack == "" ||
714+
host.isRackNil ||
705715
len(host.tokens) == 0)
706716
}
707717

0 commit comments

Comments
 (0)