Skip to content

Commit

Permalink
Fix metadata tuple parsing (apache#1190)
Browse files Browse the repository at this point in the history
* Fix metadata tuple parsing

* adding failing tests for tuple and map in getCassandraType
  • Loading branch information
beltran authored and Zariel committed Sep 20, 2018
1 parent 5a139e8 commit 799fb03
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 2 deletions.
38 changes: 36 additions & 2 deletions helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,14 +132,20 @@ func getCassandraType(name string) TypeInfo {
Elem: getCassandraType(strings.TrimPrefix(name[:len(name)-1], "list<")),
}
} else if strings.HasPrefix(name, "map<") {
names := strings.SplitN(strings.TrimPrefix(name[:len(name)-1], "map<"), ", ", 2)
names := splitCompositeTypes(strings.TrimPrefix(name[:len(name)-1], "map<"))
if len(names) != 2 {
Logger.Printf("Error parsing map type, it has %d subelements, expecting 2\n", len(names))
return NativeType{
typ: TypeCustom,
}
}
return CollectionType{
NativeType: NativeType{typ: TypeMap},
Key: getCassandraType(names[0]),
Elem: getCassandraType(names[1]),
}
} else if strings.HasPrefix(name, "tuple<") {
names := strings.Split(strings.TrimPrefix(name[:len(name)-1], "tuple<"), ", ")
names := splitCompositeTypes(strings.TrimPrefix(name[:len(name)-1], "tuple<"))
types := make([]TypeInfo, len(names))

for i, name := range names {
Expand All @@ -157,6 +163,34 @@ func getCassandraType(name string) TypeInfo {
}
}

func splitCompositeTypes(name string) []string {
if !strings.Contains(name, "<") {
return strings.Split(name, ", ")
}
var parts []string
lessCount := 0
segment := ""
for _, char := range name {
if char == ',' && lessCount == 0 {
if segment != "" {
parts = append(parts, strings.TrimSpace(segment))
}
segment = ""
continue
}
segment += string(char)
if char == '<' {
lessCount++
} else if char == '>' {
lessCount--
}
}
if segment != "" {
parts = append(parts, strings.TrimSpace(segment))
}
return parts
}

func getApacheCassandraType(class string) Type {
switch strings.TrimPrefix(class, apacheCassandraTypePrefix) {
case "AsciiType":
Expand Down
94 changes: 94 additions & 0 deletions helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,100 @@ func TestGetCassandraType(t *testing.T) {
},
},
},
{
"frozen<tuple<frozen<tuple<text, frozen<list<frozen<tuple<int, int>>>>>>, frozen<tuple<text, frozen<list<frozen<tuple<int, int>>>>>>, frozen<map<text, frozen<list<frozen<tuple<int, int>>>>>>>>",
TupleTypeInfo{
NativeType: NativeType{typ: TypeTuple},
Elems: []TypeInfo{
TupleTypeInfo{
NativeType: NativeType{typ: TypeTuple},
Elems: []TypeInfo{
NativeType{typ: TypeText},
CollectionType{
NativeType: NativeType{typ: TypeList},
Elem: TupleTypeInfo{
NativeType: NativeType{typ: TypeTuple},
Elems: []TypeInfo{
NativeType{typ: TypeInt},
NativeType{typ: TypeInt},
},
},
},
},
},
TupleTypeInfo{
NativeType: NativeType{typ: TypeTuple},
Elems: []TypeInfo{
NativeType{typ: TypeText},
CollectionType{
NativeType: NativeType{typ: TypeList},
Elem: TupleTypeInfo{
NativeType: NativeType{typ: TypeTuple},
Elems: []TypeInfo{
NativeType{typ: TypeInt},
NativeType{typ: TypeInt},
},
},
},
},
},
CollectionType{
NativeType: NativeType{typ: TypeMap},
Key: NativeType{typ: TypeText},
Elem: CollectionType{
NativeType: NativeType{typ: TypeList},
Elem: TupleTypeInfo{
NativeType: NativeType{typ: TypeTuple},
Elems: []TypeInfo{
NativeType{typ: TypeInt},
NativeType{typ: TypeInt},
},
},
},
},
},
},
},
{
"frozen<tuple<frozen<tuple<int, int>>, int, frozen<tuple<int, int>>>>", TupleTypeInfo{
NativeType: NativeType{typ: TypeTuple},

Elems: []TypeInfo{
TupleTypeInfo{
NativeType: NativeType{typ: TypeTuple},

Elems: []TypeInfo{
NativeType{typ: TypeInt},
NativeType{typ: TypeInt},
},
},
NativeType{typ: TypeInt},
TupleTypeInfo{
NativeType: NativeType{typ: TypeTuple},

Elems: []TypeInfo{
NativeType{typ: TypeInt},
NativeType{typ: TypeInt},
},
},
},
},
},
{
"frozen<map<frozen<tuple<int, int>>, int>>", CollectionType{
NativeType: NativeType{typ: TypeMap},

Key: TupleTypeInfo{
NativeType: NativeType{typ: TypeTuple},

Elems: []TypeInfo{
NativeType{typ: TypeInt},
NativeType{typ: TypeInt},
},
},
Elem: NativeType{typ: TypeInt},
},
},
}

for _, test := range tests {
Expand Down

0 comments on commit 799fb03

Please sign in to comment.