[ 
https://issues.apache.org/jira/browse/CASSGO-115?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18069852#comment-18069852
 ] 

Bohdan Siryk commented on CASSGO-115:
-------------------------------------

The issue is that when *value* in an interface pointer _*interface{} **_ the 
code below initializes a map in the destination variable and never updates it. 
What happens:
1. Check if the dst var holds an interface pointer
2. If so, init a map (map A) and set its pointer to the dst var
3. Sets the pointer to the map A to the method variable value
4. Using type-switch check if the value holds *map[string]interface{}, be aware 
that switch := v now holds pointer to the map A
5. Inits a new map and sets it to the switch variable v

But, that *switch v* holds a pointer to the *local variable v* from the check 
before, so in the switch it overrides the value of the local variable, but not 
the destination - destination still holds a pointer to the previously 
initialized map
{code:java}
// Unmarshal unmarshals the byte slice into the value.
func (udt UDTTypeInfo) Unmarshal(data []byte, value interface{}) error {        
  // do this up here so we don't need to duplicate all of the map logic below   
  if iptr, ok := value.(*interface{}); ok && iptr != nil {              
    // holds map A              
    v := map[string]interface{}{}               
    // set dst pointer to the map A             
    *iptr = v           
    // reassign value to the map A              
    value = &v  
  }     
  // v holds a pointer to local var with map A  
  switch v := value.(type) {    
  case UDTUnmarshaler:
  ...
  case *map[string]interface{}:         
    if data == nil {                    
      *v = nil                  
      return nil                
    }
    // create a new map B               
    m := map[string]interface{}{}               
    // as the value is points to local var with map A, this actually overrides 
the local var with map B           
    // so map A is never updated, but destination is a map A            
    *v = m
    ...
} {code}

> MapScan does not preserve top-level UDT values (returns empty map) 
> -------------------------------------------------------------------
>
>                 Key: CASSGO-115
>                 URL: https://issues.apache.org/jira/browse/CASSGO-115
>             Project: Apache Cassandra Go driver
>          Issue Type: Bug
>          Components: Core
>            Reporter: Stanislav Bychkov
>            Priority: Normal
>             Fix For: 2.1.0
>
>
> When reading rows that contain a top-level UDT column, MapScan() does not 
> preserve the decoded UDT field values.
> For a top-level frozen<udt> column:
> * Scan(...) can decode the UDT correctly
> * MapScan(...) returns the row, but the UDT value is an empty 
> map[string]interface{}
> h4. Expected behavior
> MapScan should preserve top-level UDT contents consistently with Scan
> A non-null UDT column should decode into a populated map[string]interface{} 
> containing its field values
> h4. This is particularly problematic because:
> The column itself is present
> No error is raised
> The data is silently lost rather than missing or failing loudly



--
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