Jyothsna Konisa created CASSANALYTICS-204:
---------------------------------------------

             Summary: CDC Avro schemas have invalid or colliding record names 
for UDTs and collections
                 Key: CASSANALYTICS-204
                 URL: https://issues.apache.org/jira/browse/CASSANALYTICS-204
             Project: Apache Cassandra Analytics
          Issue Type: Bug
            Reporter: Jyothsna Konisa


*Problem*                                                                       
                                                                                
                                           
                                                                                
                                                                                
                                           
The CDC Avro schema converter (CqlToAvroSchemaConverterImplementation) 
generates record names that are either invalid or not unique, for UDTs and for 
records nested inside collections.                 
                                                                                
                                                                                
                                           
#   1. Invalid names                                                            
                                                                                
                                           For lists and sets, the CQL type 
text is added to the record namespace, e.g.:                                    
                                                                                
        
    cdc_demo.task.results.list<frozen<task_result>>.record_udt                  
                                                                                
                                          "<" and ">" are not allowed in Avro 
names. Avro 1.12+ rejects such schemas when parsing them (SchemaParseException: 
Namespace part "list<frozen<task_result>>" is invalid). Since consumers must 
parse the writer schema before decoding, no message of an affected table can be 
read by consumers or tools using Avro 1.12+ (e.g. Kafka UI). Avro 1.11 and 
older do not check namespace parts, which is why the
  issue is not visible with every consumer. CDC itself uses Avro 1.11.4; 
upgrading to 1.12 could break generating these schemas.                         
                                                  *Affected: *UDTs or maps 
inside a list or set, e.g. list<frozen<udt>>, set<frozen<udt>>, 
list<frozen<map<text, text>>>.                                                  
                                  
                                                                                
                                                                                
                                           
#   2. Colliding names                                                          
                                                                                
                                             All UDT records are named 
record_udt, and all fields of a UDT (and the key and value of a map) share one 
namespace. So two different UDTs at the same level get the same full name, e.g. 
the fields of UDT person (home frozen<address>, mobile frozen<phone>) both 
become ...info.record_udt.record_udt.record_udt. When the schema is written as 
JSON (as registered in Schema Registry), Avro writes the second record as a 
reference to the first. The registered schema then describes the second field 
with the wrong fields, and consumers cannot decode it correctly.                
                        
*Affected: *a UDT with fields of different UDT types, or a map whose key and 
value are different UDTs.                                                       
                                              
                                                                                
                                                                                
                                           
*Fix *                                                                          
                                                                                
                                           
                                                                                
                                                                                
                                           
  Name each record after its position in the table, so every name is valid and 
unique:                                                                         
                                            
  - UDT records are named after the UDT, in the namespace of their position: 
ks.users.info.home.address (was 
ks.users.info.record_udt.record_udt.record_udt).                                
              
  - UDT fields add the field name to the namespace of their children.           
                                                                                
                                           
  - List and set elements use the collection's namespace; the CQL type is no 
longer part of the name (it is still available in the cqlType property).        
                                              
  - Records under a map key or value are namespaced by key/value when they 
contain a UDT, or when both key and value contain records.                      
                                                
  - Schemas without UDTs keep their current names (e.g. map entry records 
ks.t.m.array_map.array_map). 

||Column type||Record||Before||After||
|frozen<address>|UDT|ks.t.c.record_udt.record_udt|ks.t.c.address|
|list<frozen<address>>|element 
UDT|ks.t.c.list<frozen<address>>.record_udt.record_udt (invalid)|ks.t.c.address|
|list<frozen<map<text, text>>>|map entry|ks.t.c.list<frozen<map<text, 
text>>>.array_map.array_map (invalid)|ks.t.c.array_map.array_map|
|frozen<person> (home frozen<address>, mobile frozen<phone>)|home / 
mobile|ks.t.c.record_udt.record_udt.record_udt for both 
(collision)|ks.t.c.home.address / ks.t.c.mobile.phone|
|map<frozen<address>, frozen<phone>>|key / value 
UDT|ks.t.m.array_map.record_udt.record_udt for both 
(collision)|ks.t.m.array_map.key.address / ks.t.m.array_map.value.phone|
|map<text, text>|map entry|ks.t.m.array_map.array_map|unchanged|                
                                                                                
    
                                                                                
                                                                                
                                           
Impact                                                                          
                                                                                
                                         
                                                                                
                                                                                
                                           
- UDTs are still identified by the record_udt logical type, so readers in 
Cassandra Analytics are unaffected.                                             
                                               
 - The binary encoding of the data does not change, and the schema version UUID 
(derived from the CQL schema) does not change.                                  
                                          
 - Record names change only for UDTs and records nested in lists/sets. UDT 
columns could not be published before CASSANALYTICS-203, so no data depends on 
the old names. With Schema Registry, a subject  registered for a UDT table 
during earlier failed publish attempts may reject the new schema once 
(NAME_MISMATCH); deleting the subject or relaxing its compatibility resolves it.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to