[GODRIVER-1305] Allow inline fields to be pointers of struct Created: 06/Sep/19  Updated: 28/Oct/23  Resolved: 11/Nov/19

Status: Closed
Project: Go Driver
Component/s: BSON, CRUD
Affects Version/s: 1.1.1
Fix Version/s: 1.2.0

Type: Improvement Priority: Major - P3
Reporter: Nguyen Phuong Assignee: Isabella Siu (Inactive)
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Instant of Stock cannot be written because a pointer of Quantity struct is used inside it.
type Quantity struct {
    InCarton float64 `json:"InCarton" bson:"InCarton"`
    InPallet float64 `json:"InPallet" bson:"InPallet"`
    InKg float64 `json:"InKg" bson:"InKg"`
    InCBM float64 `json:"InCBM" bson:"InCBM"`

type Stock struct {
    Batch `json:",inline" bson:",inline"`
    Quantity *Quantity `json:",inline" bson:",inline"`
    MovementHistory Movements `json:"MovementHistory" bson:"MovementHistory"`
    CostPerKg `json:"" bson:""`

Error message is described as below:

panic: cannot transform type *simcel.TransportOrderLine to a BSON Document: (struct simcel.Stock) inline fields must be either a struct or a map



 Comments   
Comment by Nguyen Phuong [ 30/Dec/19 ]

divjot.arora: I fetch the correct version and revision of mongo-driver. It is working well now. Thanks so much.

Comment by Divjot Arora (Inactive) [ 25/Dec/19 ]

phuong.nguyen@cel-consulting.com

Per output from the git show command, c50d02 is the commit corresponding to the v1.1.1 release. b414b89, which your dep output shows for the LATEST column, is the commit corresponding to the v1.1.0 release. https://golang.github.io/dep/docs/daily-dep.html should have any information you need to correctly update the package. I don't remember off hand, but something like dep ensure -update go.mongodb.org/mongo-driver might work.

Comment by Nguyen Phuong [ 23/Dec/19 ]

Hi divjot.arora,

I am using dep to manage dependencies. And here is the dep status of mongo-go driver:

PROJECT                                           CONSTRAINT      VERSION   REVISION     LATEST          PKGS        USED

go.mongodb.org/mongo-driver    ^1.2.0                     v1.2.0        c520d02       b414b89         28

Is the fix not included in revision c520d02 ?

Best Regards,

Nguyen Hoai Phuong

Comment by Divjot Arora (Inactive) [ 20/Dec/19 ]

Hi phuong.nguyen@cel-consulting.com,

I checked out the v1.2.0 tag and looked for that error, but it no longer exists. The error is now "inline fields must be a struct, a struct pointer, or a map". Also, I tried running bson.Marshal against a Parent instance per your type definitions and got a document {ParentID: 1, ChildID: 2}, which I believe is the expected result.

Can you provide the git commit hash of the driver that you're building against? That will help us determine what's going wrong.

 

– Divjot

Comment by Nguyen Phuong [ 20/Dec/19 ]

@Jeffrey Yemin: I tested this release version 1.2.0 and I found the issue still there while reading data from mongodb:

panic: (struct simcel.Parent) inline fields must be either a struct or a map [recovered]
panic: (struct simcel.Parent) inline fields must be either a struct or a map

 

type Child struct {
  ChildID int `json:"ChildID" bson:"ChildID"`    
}
 
type Parent struct {
  ParentID int `json:"ParentID" bson:"ParentID"`
  *Child   `json:",inline" bson:",inline"`
}

ParentID ChildID
1 1
1 2
1  

 

 

Comment by Githook User [ 11/Nov/19 ]

Author:

{'username': 'iwysiu', 'email': 'isabella.siu@10gen.com', 'name': 'iwysiu'}

Message: GODRIVER-1305 allow inline fields to be pointers to structs (#211)
Branch: master
https://github.com/mongodb/mongo-go-driver/commit/894900dd22227cf593b204c577c6c7164b373e0e

Comment by Divjot Arora (Inactive) [ 30/Oct/19 ]

I did some investigation into the globalsign/mgo behavior. Some key points that we should emulate (or document if we deviate):

  1. Inline is only allowed for pointers to structs, not maps.
  2. Setting an inline struct pointer to nil results in it being skipped while marshalling.
  3. Setting an inline pointer to the empty struct results in each struct field being marshalled as its 0 value.
Comment by Nguyen Phuong [ 14/Oct/19 ]

@Jeffrey Yemin: Thanks. It is really useful information.

Comment by Jeffrey Yemin [ 11/Oct/19 ]

aaron@aaha.co that's really useful information. Thanks for sharing it. As you can see, we have re-opened this ticket so we do plan to do it, though we don't yet have a scheduled fix version for it.

Comment by Aaron Harun [ 11/Oct/19 ]

Last year, mgo accepted a merge request allowing this. 

https://github.com/globalsign/mgo/pull/217

Our company implemented this MR for mgo, and one of the blockers to moving to mongo-go is that it is not supported.

Comment by Kristofer Brandow (Inactive) [ 12/Sep/19 ]

Hi lou.adrien@gmail.com,

We are following the same conventions as mgo in this case. The mgo/bson package does not allow pointers to structs to be marked inline. As I said above, it is possible to copy and modify the struct codec to implement your own version of it that allows inlining of pointers to structs.

--Kris

Comment by Fabre Lou-adrien [ 10/Sep/19 ]

@Kristofer I am not sure to understand why this should not be part of the core driver. Yes it raises a few question about edges cases values for these types, but this could be documented clearly, if you want avoid confusion, you could take the same convention as MGO.

Embedded pointer is an extremely common practice in go, for many reasons, not supporting it would mean that a huge part of the codebase structures of most project would not be usable with the driver out of the box. Would this not be enough to consider implementing it?

Regards,

Comment by Kristofer Brandow (Inactive) [ 09/Sep/19 ]

Hi phuong.nguyen@cel-consulting.com,

While we see the value in adding the ability to inline a pointer, the introduction of this behavior raised several questions. For example, what happens when the pointer is nil? Do we encode each of the values or do we encode nil? How does it interact with omitempty? Even if we defined these, we don't feel that it would be straight forward for most users and would likely cause confusion for users. For that reason, we've decided not to do this.

If you do need this functionality, please send a message to the mailing list where someone can help you implement a custom codec or the bson.Marshaler and bson.Unmarshaler interfaces for your types.

--Kris

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