@@ -4165,17 +4165,31 @@ func diffDynamoDbGSI(oldGsi, newGsi []interface{}, billingMode string) (ops []*d
41654165 newWriteCapacity , newReadCapacity := newMap ["write_capacity" ].(int ), newMap ["read_capacity" ].(int )
41664166 capacityChanged := (oldWriteCapacity != newWriteCapacity || oldReadCapacity != newReadCapacity )
41674167
4168+ // pluck non_key_attributes from oldAttributes and newAttributes as reflect.DeepEquals will compare
4169+ // ordinal of elements in its equality (which we actually don't care about)
4170+ nonKeyAttributesChanged := checkIfNonKeyAttributesChanged (oldMap , newMap )
4171+
41684172 oldAttributes , err := stripCapacityAttributes (oldMap )
41694173 if err != nil {
41704174 e = err
41714175 return
41724176 }
4177+ oldAttributes , err = stripNonKeyAttributes (oldAttributes )
4178+ if err != nil {
4179+ e = err
4180+ return
4181+ }
41734182 newAttributes , err := stripCapacityAttributes (newMap )
41744183 if err != nil {
41754184 e = err
41764185 return
41774186 }
4178- otherAttributesChanged := ! reflect .DeepEqual (oldAttributes , newAttributes )
4187+ newAttributes , err = stripNonKeyAttributes (newAttributes )
4188+ if err != nil {
4189+ e = err
4190+ return
4191+ }
4192+ otherAttributesChanged := nonKeyAttributesChanged || ! reflect .DeepEqual (oldAttributes , newAttributes )
41794193
41804194 if capacityChanged && ! otherAttributesChanged {
41814195 update := & dynamodb.GlobalSecondaryIndexUpdate {
@@ -4214,6 +4228,49 @@ func diffDynamoDbGSI(oldGsi, newGsi []interface{}, billingMode string) (ops []*d
42144228 return
42154229}
42164230
4231+ func stripNonKeyAttributes (in map [string ]interface {}) (map [string ]interface {}, error ) {
4232+ mapCopy , err := copystructure .Copy (in )
4233+ if err != nil {
4234+ return nil , err
4235+ }
4236+
4237+ m := mapCopy .(map [string ]interface {})
4238+
4239+ delete (m , "non_key_attributes" )
4240+
4241+ return m , nil
4242+ }
4243+
4244+ // checkIfNonKeyAttributesChanged returns true if non_key_attributes between old map and new map are different
4245+ func checkIfNonKeyAttributesChanged (oldMap , newMap map [string ]interface {}) bool {
4246+ oldNonKeyAttributes , oldNkaExists := oldMap ["non_key_attributes" ].([]string )
4247+ newNonKeyAttributes , newNkaExists := newMap ["non_key_attributes" ].([]string )
4248+ if oldNkaExists != newNkaExists {
4249+ return true
4250+ }
4251+
4252+ o := map [string ]bool {}
4253+ for _ , oldNonKeyAttribute := range oldNonKeyAttributes {
4254+ o [oldNonKeyAttribute ] = true
4255+ }
4256+ n := map [string ]bool {}
4257+ for _ , newNonKeyAttribute := range newNonKeyAttributes {
4258+ n [newNonKeyAttribute ] = true
4259+ }
4260+
4261+ // perform this check after populating map so we ignore duplicated fields in non_key_attributes
4262+ if len (o ) != len (n ) {
4263+ return true
4264+ }
4265+
4266+ for k , v := range n {
4267+ if oVal , oExists := o [k ]; ! oExists || v != oVal {
4268+ return true
4269+ }
4270+ }
4271+ return false
4272+ }
4273+
42174274func stripCapacityAttributes (in map [string ]interface {}) (map [string ]interface {}, error ) {
42184275 mapCopy , err := copystructure .Copy (in )
42194276 if err != nil {
@@ -4474,6 +4531,10 @@ func expandDynamoDbProjection(data map[string]interface{}) *dynamodb.Projection
44744531 projection .NonKeyAttributes = expandStringList (v )
44754532 }
44764533
4534+ if v , ok := data ["non_key_attributes" ].(* schema.Set ); ok && v .Len () > 0 {
4535+ projection .NonKeyAttributes = expandStringList (v .List ())
4536+ }
4537+
44774538 return projection
44784539}
44794540
0 commit comments