@@ -164,20 +164,21 @@ func getCassandraBaseType(name string) Type {
164164 }
165165}
166166
167+ // TODO: Cover with unit tests.
167168// Parses long Java-style type definition to internal data structures.
168169func getCassandraLongType (name string , protoVer byte , logger StdLogger ) TypeInfo {
169170 if strings .HasPrefix (name , SET_TYPE ) {
170171 return CollectionType {
171172 NativeType : NewNativeType (protoVer , TypeSet ),
172- Elem : getCassandraLongType (strings . TrimPrefix (name [: len ( name ) - 1 ] , SET_TYPE + "(" ), protoVer , logger ),
173+ Elem : getCassandraLongType (unwrapCompositeTypeDefinition (name , SET_TYPE , '(' ), protoVer , logger ),
173174 }
174175 } else if strings .HasPrefix (name , LIST_TYPE ) {
175176 return CollectionType {
176177 NativeType : NewNativeType (protoVer , TypeList ),
177- Elem : getCassandraLongType (strings . TrimPrefix (name [: len ( name ) - 1 ] , LIST_TYPE + "(" ), protoVer , logger ),
178+ Elem : getCassandraLongType (unwrapCompositeTypeDefinition (name , LIST_TYPE , '(' ), protoVer , logger ),
178179 }
179180 } else if strings .HasPrefix (name , MAP_TYPE ) {
180- names := splitJavaCompositeTypes (strings . TrimPrefix ( name [: len ( name ) - 1 ] , MAP_TYPE + "(" ) )
181+ names := splitJavaCompositeTypes (name , MAP_TYPE )
181182 if len (names ) != 2 {
182183 logger .Printf ("gocql: error parsing map type, it has %d subelements, expecting 2\n " , len (names ))
183184 return NewNativeType (protoVer , TypeCustom )
@@ -188,7 +189,7 @@ func getCassandraLongType(name string, protoVer byte, logger StdLogger) TypeInfo
188189 Elem : getCassandraLongType (names [1 ], protoVer , logger ),
189190 }
190191 } else if strings .HasPrefix (name , TUPLE_TYPE ) {
191- names := splitJavaCompositeTypes (strings . TrimPrefix ( name [: len ( name ) - 1 ] , TUPLE_TYPE + "(" ) )
192+ names := splitJavaCompositeTypes (name , TUPLE_TYPE )
192193 types := make ([]TypeInfo , len (names ))
193194
194195 for i , name := range names {
@@ -200,7 +201,7 @@ func getCassandraLongType(name string, protoVer byte, logger StdLogger) TypeInfo
200201 Elems : types ,
201202 }
202203 } else if strings .HasPrefix (name , UDT_TYPE ) {
203- names := splitJavaCompositeTypes (strings . TrimPrefix ( name [: len ( name ) - 1 ] , UDT_TYPE + "(" ) )
204+ names := splitJavaCompositeTypes (name , UDT_TYPE )
204205 fields := make ([]UDTField , len (names )- 2 )
205206
206207 for i := 2 ; i < len (names ); i ++ {
@@ -220,7 +221,7 @@ func getCassandraLongType(name string, protoVer byte, logger StdLogger) TypeInfo
220221 Elements : fields ,
221222 }
222223 } else if strings .HasPrefix (name , VECTOR_TYPE ) {
223- names := splitJavaCompositeTypes (strings . TrimPrefix ( name [: len ( name ) - 1 ] , VECTOR_TYPE + "(" ) )
224+ names := splitJavaCompositeTypes (name , VECTOR_TYPE )
224225 subType := getCassandraLongType (strings .TrimSpace (names [0 ]), protoVer , logger )
225226 dim , err := strconv .Atoi (strings .TrimSpace (names [1 ]))
226227 if err != nil {
@@ -245,19 +246,19 @@ func getCassandraLongType(name string, protoVer byte, logger StdLogger) TypeInfo
245246// Parses short CQL type representation (e.g. map<text, text>) to internal data structures.
246247func getCassandraType (name string , protoVer byte , logger StdLogger ) TypeInfo {
247248 if strings .HasPrefix (name , "frozen<" ) {
248- return getCassandraType (strings . TrimPrefix (name [: len ( name ) - 1 ] , "frozen<" ), protoVer , logger )
249+ return getCassandraType (unwrapCompositeTypeDefinition (name , "frozen" , '<' ), protoVer , logger )
249250 } else if strings .HasPrefix (name , "set<" ) {
250251 return CollectionType {
251252 NativeType : NewNativeType (protoVer , TypeSet ),
252- Elem : getCassandraType (strings . TrimPrefix (name [: len ( name ) - 1 ] , "set<" ), protoVer , logger ),
253+ Elem : getCassandraType (unwrapCompositeTypeDefinition (name , "set" , '<' ), protoVer , logger ),
253254 }
254255 } else if strings .HasPrefix (name , "list<" ) {
255256 return CollectionType {
256257 NativeType : NewNativeType (protoVer , TypeList ),
257- Elem : getCassandraType (strings . TrimPrefix (name [: len ( name ) - 1 ] , "list<" ), protoVer , logger ),
258+ Elem : getCassandraType (unwrapCompositeTypeDefinition (name , "list" , '<' ), protoVer , logger ),
258259 }
259260 } else if strings .HasPrefix (name , "map<" ) {
260- names := splitCQLCompositeTypes (strings . TrimPrefix ( name [: len ( name ) - 1 ] , "map<" ) )
261+ names := splitCQLCompositeTypes (name , "map" )
261262 if len (names ) != 2 {
262263 logger .Printf ("Error parsing map type, it has %d subelements, expecting 2\n " , len (names ))
263264 return NewNativeType (protoVer , TypeCustom )
@@ -268,7 +269,7 @@ func getCassandraType(name string, protoVer byte, logger StdLogger) TypeInfo {
268269 Elem : getCassandraType (names [1 ], protoVer , logger ),
269270 }
270271 } else if strings .HasPrefix (name , "tuple<" ) {
271- names := splitCQLCompositeTypes (strings . TrimPrefix ( name [: len ( name ) - 1 ] , "tuple<" ) )
272+ names := splitCQLCompositeTypes (name , "tuple" )
272273 types := make ([]TypeInfo , len (names ))
273274
274275 for i , name := range names {
@@ -280,7 +281,7 @@ func getCassandraType(name string, protoVer byte, logger StdLogger) TypeInfo {
280281 Elems : types ,
281282 }
282283 } else if strings .HasPrefix (name , "vector<" ) {
283- names := splitCQLCompositeTypes (strings . TrimPrefix ( name [: len ( name ) - 1 ] , "vector<" ) )
284+ names := splitCQLCompositeTypes (name , "vector" )
284285 subType := getCassandraType (strings .TrimSpace (names [0 ]), protoVer , logger )
285286 dim , _ := strconv .Atoi (strings .TrimSpace (names [1 ]))
286287
@@ -297,17 +298,22 @@ func getCassandraType(name string, protoVer byte, logger StdLogger) TypeInfo {
297298 }
298299}
299300
300- func splitCQLCompositeTypes (name string ) []string {
301- return splitCompositeTypes (name , '<' , '>' )
301+ func splitCQLCompositeTypes (name string , typeName string ) []string {
302+ return splitCompositeTypes (name , typeName , '<' , '>' )
302303}
303304
304- func splitJavaCompositeTypes (name string ) []string {
305- return splitCompositeTypes (name , '(' , ')' )
305+ func splitJavaCompositeTypes (name string , typeName string ) []string {
306+ return splitCompositeTypes (name , typeName , '(' , ')' )
306307}
307308
308- func splitCompositeTypes (name string , typeOpen int32 , typeClose int32 ) []string {
309- if ! strings .Contains (name , string (typeOpen )) {
310- parts := strings .Split (name , "," )
309+ func unwrapCompositeTypeDefinition (name string , typeName string , typeOpen int32 ) string {
310+ return strings .TrimPrefix (name [:len (name )- 1 ], typeName + string (typeOpen ))
311+ }
312+
313+ func splitCompositeTypes (name string , typeName string , typeOpen int32 , typeClose int32 ) []string {
314+ def := unwrapCompositeTypeDefinition (name , typeName , typeOpen )
315+ if ! strings .Contains (def , string (typeOpen )) {
316+ parts := strings .Split (def , "," )
311317 for i := range parts {
312318 parts [i ] = strings .TrimSpace (parts [i ])
313319 }
@@ -316,7 +322,7 @@ func splitCompositeTypes(name string, typeOpen int32, typeClose int32) []string
316322 var parts []string
317323 lessCount := 0
318324 segment := ""
319- for _ , char := range name {
325+ for _ , char := range def {
320326 if char == ',' && lessCount == 0 {
321327 if segment != "" {
322328 parts = append (parts , strings .TrimSpace (segment ))
0 commit comments