aws / aws-sdk-go-v2

AWS SDK for the Go programming language.
https://aws.github.io/aws-sdk-go-v2/docs/
Apache License 2.0
2.58k stars 623 forks source link

attributevalue.MarshalMap() to AttributeValueMemberNULL field with double pointer #2726

Open kmacmcfarlane opened 1 month ago

kmacmcfarlane commented 1 month ago

Acknowledgements

Describe the bug

When working with dynamodb using attributevalue.MarshalMap() on a struct with omitempty on a field, I want to be able to return a types.AttributeValueMemberNULL in order to null out a field in dynamodb.

To achieve this, I want to use a double pointer on the field such that I can assign a nil pointer to my primative type and reference it with the double pointer. When encoding to JSON, for instance, this will encode the value null for that field in the output. The MarshalMap() appears to mistakenly think that the value double pointed to is nil, that it should not output anything when omitempty is set on the struct.

Expected Behavior

I would expect types.AttributeValueMemberNULL to be returned for the key in the result av map.

Current Behavior

The key for the struct field is omited from the map.

Reproduction Steps

package store

import (
    "github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue"
    "github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
    . "github.com/onsi/ginkgo/v2"
    . "github.com/onsi/gomega"
)

var _ = Describe("recreate", func() {

    It("set Foo to attributevalue NULL", func() {

        // given
        var nilVal *int
        s := struct {
            Foo **int `dynamodbav:"foo,omitempty"`
        }{
            Foo: &nilVal,
        }

        av, err := attributevalue.MarshalMap(s)
        Expect(err).ShouldNot(HaveOccurred())
        Expect(av["foo"]).Should(BeAssignableToTypeOf(types.AttributeValueMemberNULL{}))
    })
})

Possible Solution

Check if a value of a pointer is a non-nil pointer to another pointer that is nil, in that case, return a types.AttributeValueMemberNULL instead of omitting the field from the output.

Additional Information/Context

No response

AWS Go SDK V2 Module Versions Used

github.com/aws/aws-sdk-go-v2 v1.30.3 github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.14.10 github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression v1.7.32 github.com/aws/aws-sdk-go-v2/service/dynamodb v1.34.4

Compiler and Version used

go version go1.22.2 linux/amd64

Operating System and version

Fedora 39

kmacmcfarlane commented 1 month ago

Digging deeper, what I am looking for with a double pointer is a combination of omitempty and nullempty behaviors. If the outer pointer is nil I want the field omitted from the output, and if only the inner pointer is nil, I want a null attributevalue to be encoded.