[GODRIVER-1110] Cannot handle nil pointer to struct with Marshaler or ValueMarshaler implemented Created: 05/Jun/19  Updated: 12/Jun/19  Resolved: 12/Jun/19

Status: Closed
Project: Go Driver
Component/s: BSON
Affects Version/s: 1.1.0
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Yao Wei Assignee: Emmanuel Eppinger (Inactive)
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Considering the following example:

type A struct {
	X *B
}
 
type B struct {
	Y string
}
 
func (B) MarshalBSON() ([]byte, error) {
	return bson.Marshal(bson.M{"foo": "bar"})
}

In that case it can marshal A{X: &B} but cannot marshal A{X: nil}

If *B (instead of B) has MarshalBSON implemented it can handle nil pointer. but has no way to represent null in BSON, because MarshalBSON is defaulted to EmbeddedDocument.
I don't know what should return if we implement MarshalBSONValue in *B. "return bsontype.Null, nil, nil" doesn't seem to be correct.



 Comments   
Comment by Emmanuel Eppinger (Inactive) [ 12/Jun/19 ]

If you want to be able to marshal both Bs and *Bs you can do both.

If you want to be able to marshal As you only would need to implement the one for *Bs.

Comment by Yao Wei [ 12/Jun/19 ]

Manny's suggestion works in case of the example, though it cannot marshal B struct (not a pointer to struct) in that implementation. Should I implement both of these below?

func (b *B) MarshalBSONValue() (bsontype.Type, []byte, error)
func (b B) MarshalBSON() ([]byte, error)

Comment by Emmanuel Eppinger (Inactive) [ 11/Jun/19 ]

You should implement MarshalBSONValue() with something similar to the following for *B

func (b *B) MarshalBSONValue() (bsontype.Type, []byte, error) {
    if b == nil {
        return bsontype.Null, nil, nil
    }
    
    bDoc, err := bson.Marshal(b)
    return bsontype.EmbeddedDocument, bDoc, err  
}

 

 

Generated at Thu Feb 08 08:35:42 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.