@@ -164,30 +164,30 @@ func getCassandraBaseType(name string) Type {
164164 }
165165}
166166
167+ // Parses short CQL type representation to internal data structures.
168+ // Mapping of long Java-style type definition into short format is performed in
169+ // apacheToCassandraType function.
167170func getCassandraType (name string , protoVer byte , logger StdLogger ) TypeInfo {
168171 if strings .HasPrefix (name , "frozen<" ) {
169172 return getCassandraType (strings .TrimPrefix (name [:len (name )- 1 ], "frozen<" ), protoVer , logger )
170173 } else if strings .HasPrefix (name , "set<" ) {
171174 return CollectionType {
172- NativeType : NativeType { typ : TypeSet , proto : protoVer } ,
175+ NativeType : NewNativeType ( protoVer , TypeSet ) ,
173176 Elem : getCassandraType (strings .TrimPrefix (name [:len (name )- 1 ], "set<" ), protoVer , logger ),
174177 }
175178 } else if strings .HasPrefix (name , "list<" ) {
176179 return CollectionType {
177- NativeType : NativeType { typ : TypeList , proto : protoVer } ,
180+ NativeType : NewNativeType ( protoVer , TypeList ) ,
178181 Elem : getCassandraType (strings .TrimPrefix (name [:len (name )- 1 ], "list<" ), protoVer , logger ),
179182 }
180183 } else if strings .HasPrefix (name , "map<" ) {
181184 names := splitCompositeTypes (strings .TrimPrefix (name [:len (name )- 1 ], "map<" ))
182185 if len (names ) != 2 {
183186 logger .Printf ("Error parsing map type, it has %d subelements, expecting 2\n " , len (names ))
184- return NativeType {
185- proto : protoVer ,
186- typ : TypeCustom ,
187- }
187+ return NewNativeType (protoVer , TypeCustom )
188188 }
189189 return CollectionType {
190- NativeType : NativeType { typ : TypeMap , proto : protoVer } ,
190+ NativeType : NewNativeType ( protoVer , TypeMap ) ,
191191 Key : getCassandraType (names [0 ], protoVer , logger ),
192192 Elem : getCassandraType (names [1 ], protoVer , logger ),
193193 }
@@ -200,11 +200,29 @@ func getCassandraType(name string, protoVer byte, logger StdLogger) TypeInfo {
200200 }
201201
202202 return TupleTypeInfo {
203- NativeType : NativeType { typ : TypeTuple , proto : protoVer } ,
203+ NativeType : NewNativeType ( protoVer , TypeTuple ) ,
204204 Elems : types ,
205205 }
206- } else if strings .HasPrefix (name , "udt<" ) {
207- names := splitCompositeTypes (strings .TrimPrefix (name [:len (name )- 1 ], "udt<" ))
206+ } else if strings .HasPrefix (name , "vector<" ) {
207+ names := splitCompositeTypes (strings .TrimPrefix (name [:len (name )- 1 ], "vector<" ))
208+ subType := getCassandraType (strings .TrimSpace (names [0 ]), protoVer , logger )
209+ dim , _ := strconv .Atoi (strings .TrimSpace (names [1 ]))
210+
211+ return VectorType {
212+ NativeType : NewCustomType (protoVer , TypeCustom , VECTOR_TYPE ),
213+ SubType : subType ,
214+ Dimensions : dim ,
215+ }
216+ } else if strings .Index (name , "<" ) == - 1 {
217+ // basic type
218+ return NativeType {
219+ proto : protoVer ,
220+ typ : getCassandraBaseType (name ),
221+ }
222+ } else {
223+ // udt
224+ idx := strings .Index (name , "<" )
225+ names := splitCompositeTypes (name [idx + 1 : len (name )- 1 ])
208226 fields := make ([]UDTField , len (names )- 2 )
209227
210228 for i := 2 ; i < len (names ); i ++ {
@@ -218,30 +236,11 @@ func getCassandraType(name string, protoVer byte, logger StdLogger) TypeInfo {
218236
219237 udtName , _ := hex .DecodeString (names [1 ])
220238 return UDTTypeInfo {
221- NativeType : NativeType { typ : TypeUDT , proto : protoVer } ,
239+ NativeType : NewNativeType ( protoVer , TypeUDT ) ,
222240 KeySpace : names [0 ],
223241 Name : string (udtName ),
224242 Elements : fields ,
225243 }
226- } else if strings .HasPrefix (name , "vector<" ) {
227- names := splitCompositeTypes (strings .TrimPrefix (name [:len (name )- 1 ], "vector<" ))
228- subType := getCassandraType (strings .TrimSpace (names [0 ]), protoVer , logger )
229- dim , _ := strconv .Atoi (strings .TrimSpace (names [1 ]))
230-
231- return VectorType {
232- NativeType : NativeType {
233- proto : protoVer ,
234- typ : TypeCustom ,
235- custom : VECTOR_TYPE ,
236- },
237- SubType : subType ,
238- Dimensions : dim ,
239- }
240- } else {
241- return NativeType {
242- proto : protoVer ,
243- typ : getCassandraBaseType (name ),
244- }
245244 }
246245}
247246
@@ -273,35 +272,34 @@ func splitCompositeTypes(name string) []string {
273272 return parts
274273}
275274
275+ // Convert long Java style type definition into the short CQL type names.
276276func apacheToCassandraType (t string ) string {
277277 t = strings .Replace (t , "(" , "<" , - 1 )
278278 t = strings .Replace (t , ")" , ">" , - 1 )
279279 types := strings .FieldsFunc (t , func (r rune ) bool {
280280 return r == '<' || r == '>' || r == ','
281281 })
282- skip := 0
283- for _ , class := range types {
284- class = strings .TrimSpace (class )
285- if ! isDigitsOnly (class ) {
286- // vector types include dimension (digits) as second type parameter
287- // UDT fields are represented in format {field id}:{class}, example 66697273745f6e616d65:org.apache.cassandra.db.marshal.UTF8Type
288- if skip > 0 {
289- skip -= 1
290- continue
291- }
292- idx := strings .Index (class , ":" )
293- class = class [idx + 1 :]
294- act := getApacheCassandraType (class )
295- val := act .String ()
296- switch act {
297- case TypeUDT :
298- val = "udt"
299- skip = 2 // skip next two parameters (keyspace and type ID), do not attempt to resolve their type
300- case TypeCustom :
282+ for i := 0 ; i < len (types ); i ++ {
283+ class := strings .TrimSpace (types [i ])
284+ // UDT fields are represented in format {field id}:{class}, example 66697273745f6e616d65:org.apache.cassandra.db.marshal.UTF8Type
285+ // Do not override hex encoded field names
286+ idx := strings .Index (class , ":" )
287+ class = class [idx + 1 :]
288+ act := getApacheCassandraType (class )
289+ val := act .String ()
290+ switch act {
291+ case TypeUDT :
292+ i += 2 // skip next two parameters (keyspace and type ID), do not attempt to resolve their type
293+ case TypeCustom :
294+ if isDigitsOnly (class ) {
295+ // vector types include dimension (digits) as second type parameter
296+ // getApacheCassandraType() returns "custom" by default, but we need to leave digits intact
297+ val = class
298+ } else {
301299 val = getApacheCassandraCustomSubType (class )
302300 }
303- t = strings .Replace (t , class , val , - 1 )
304301 }
302+ t = strings .Replace (t , class , val , - 1 )
305303 }
306304 // This is done so it exactly matches what Cassandra returns
307305 return strings .Replace (t , "," , ", " , - 1 )
@@ -373,6 +371,8 @@ func getApacheCassandraType(class string) Type {
373371 }
374372}
375373
374+ // Dedicated function parsing known special subtypes of CQL custom type.
375+ // Currently, only vectors are implemented as special custom subtype.
376376func getApacheCassandraCustomSubType (class string ) string {
377377 switch strings .TrimPrefix (class , apacheCassandraTypePrefix ) {
378378 case "VectorType" :
0 commit comments