Skip to content

UnmarshalListOfMaps is failed if list of custom struct is set into argument 'out' #2504

Closed
@tomatod

Description

@tomatod

Describe the bug

I'm sorry if I may misunderstand the usage of UnmarshalListOfMaps, but let me make this report.

I tried to use attributevalue.UnmarshalListOfMaps to convert Items of dynamodb.ExecuteStatementOutput to list of custom struct, but It was failed with the next error.

unmarshal failed, cannot unmarshal to non-pointer value, got []*<my custom struct>

Actually, I found the following message from api document, so I interpreted that we could utilize the function to convert the multiple items of DynamoDB's query result to []<custon struct> or []map[string]<any type>

UnmarshalListOfMaps is an alias for Unmarshal func which unmarshals a slice of maps of attribute values.
This is useful for when you need to unmarshal the Items from a Query API call.
The output value provided must be a non-nil pointer

Expected Behavior

UnmarshalListOfMaps can be used to convert []map[string]types.AttributeValue to []<custom struct>

Current Behavior

UnmarshalListOfMaps cannot be used to convert []map[string]types.AttributeValue to []<custom struct>.

Reproduction Steps

For example, the next minimum code gets failed.

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

  "fmt"
)

type Record struct {
  ID string
  Value string
}

func main() {
  items := []map[string]types.AttributeValue {
    // This is the first record
    map[string]types.AttributeValue {
      "ID":   &types.AttributeValueMemberS { Value: "00000000001" },
      "Value": &types.AttributeValueMemberS { Value: "2000" },
    },
    // This is the second record
    map[string]types.AttributeValue {
      "ID":   &types.AttributeValueMemberS { Value: "00000000002" },
      "Value": &types.AttributeValueMemberS { Value: "1000" },
    },
  }
  records := []*Record{}
  err := attributevalue.UnmarshalListOfMaps(items, records)
  fmt.Println(err) // nil is expected.
}

Output is the following.

unmarshal failed, cannot unmarshal to non-pointer value, got []*main.Record

And also for next example with []map[string]string, we get failed.

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

  "fmt"
)

func main() {
  items := []map[string]types.AttributeValue {
    map[string]types.AttributeValue {
      "ID":   &types.AttributeValueMemberS { Value: "00000000001" },
      "Value": &types.AttributeValueMemberS { Value: "2000" },
    },
    map[string]types.AttributeValue {
      "ID":   &types.AttributeValueMemberS { Value: "00000000002" },
      "Value": &types.AttributeValueMemberS { Value: "1000" },
    },
  }
  records := make([]map[string]string, 2)
  err := attributevalue.UnmarshalListOfMaps(items, records)
  fmt.Println(err)
}

Possible Solution

If my recognition is correct, I think it should use UnmarshalMap to each Items with instead of UnmarshalList here as behavior. But, It may be not simple code.

Additional Information/Context

No response

AWS Go SDK V2 Module Versions Used

    github.com/aws/aws-sdk-go-v2 v1.24.1
    github.com/aws/aws-sdk-go-v2/config v1.26.5
    github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.12.15
    github.com/aws/aws-sdk-go-v2/service/dynamodb v1.26.9
    github.com/aws/aws-sdk-go-v2/service/iotdataplane v1.20.6

Compiler and Version used

go version go1.22.0 linux/amd64

Operating System and version

Ubuntu 20.04.4 LTS

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugThis issue is a bug.needs-triageThis issue or PR still needs to be triaged.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions