aws-sdk-go-v2 icon indicating copy to clipboard operation
aws-sdk-go-v2 copied to clipboard

dynamodb/expression: name builder for list of lists: foo[10][5] returns: BuildOperand error: invalid parameter: NameBuilder

Open advdv opened this issue 2 years ago • 1 comments

Describe the bug

As far as I understand it is possible to model a list of lists in dynamodb. So it should be possible to build a name (as part of a condition for example), with something like the code below. Instead, it errors:

package generator_test

import (
	"testing"

	"github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression"
)

func TestNameBuilder(t *testing.T) {
	expr, err := expression.NewBuilder().WithCondition(expression.Name("foo[10][5]").AttributeExists()).Build()
	if err != nil {
		t.Fatalf("failed: %v", err) // BuildOperand error: invalid parameter: NameBuilder
	}
	_ = expr
}

Expected Behavior

It should allow building names for a list of lists

Current Behavior

It returns the following error:

BuildOperand error: invalid parameter: NameBuilder

Reproduction Steps

The code above can be pasted into a _test.go file to get the error.

Possible Solution

No response

Additional Information/Context

No response

AWS Go SDK V2 Module Versions Used

github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.10.19
github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression v1.4.46
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.19.2

Compiler and Version used

go version go1.20.2 darwin/arm64

Operating System and version

MacOS Ventura 13.1

advdv avatar Apr 01 '23 10:04 advdv

Hi @advanderveer ,

Sorry for the long wait.

I'm able to confirm that nested expressions are not supported. This was probably an oversight with how this feature was implemented.

As a workaround you can pass in the expression directly to the getItemInput:

package main

import (
	"context"
	"github.com/aws/aws-sdk-go-v2/aws"
	"log"

	"github.com/aws/aws-sdk-go-v2/config"
	"github.com/aws/aws-sdk-go-v2/service/dynamodb"
	"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
)

func main() {
	cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithClientLogMode(aws.LogRequestWithBody|aws.LogResponseWithBody))
	if err != nil {
		log.Fatalf("unable to load SDK config, %v", err)
	}

	client := dynamodb.NewFromConfig(cfg)

	params := &dynamodb.GetItemInput{
		TableName:            aws.String("nestedExpressionTable"),
		Key:                  map[string]types.AttributeValue{"PrimaryKey": &types.AttributeValueMemberS{Value: "SomeKey"}},
		ProjectionExpression: aws.String("foo[2][5]"),
	}

	_, err = client.GetItem(context.TODO(), params)
	if err != nil {
		log.Fatalf("failed to get item, %v", err)
	}
}

Will result in a valid response:

{"Item":{"foo":{"L":[{"L":[{"N":"96"}]}]}}}

I'll discuss this with the team for further investigation.

Thanks, Ran~

RanVaknin avatar Sep 20 '23 20:09 RanVaknin