From 0ffee92175863c9882c745f1a836b272aa352778 Mon Sep 17 00:00:00 2001 From: Mike Farah Date: Sat, 19 Mar 2022 18:42:12 +1100 Subject: [PATCH] Fixed += with multiple matches #1145 --- pkg/yqlib/operator_add.go | 4 +--- pkg/yqlib/operator_add_test.go | 9 +++++++++ pkg/yqlib/operator_multiply_test.go | 9 +++++++++ pkg/yqlib/operators.go | 12 ++++++++---- 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/pkg/yqlib/operator_add.go b/pkg/yqlib/operator_add.go index db9cd298..4b10585e 100644 --- a/pkg/yqlib/operator_add.go +++ b/pkg/yqlib/operator_add.go @@ -161,15 +161,13 @@ func addSequences(target *CandidateNode, lhs *CandidateNode, rhs *CandidateNode) target.Node.Style = lhs.Node.Style } target.Node.Tag = lhs.Node.Tag - target.Node.Content = make([]*yaml.Node, len(lhs.Node.Content)) - copy(target.Node.Content, lhs.Node.Content) extraNodes, err := toNodes(rhs, lhs) if err != nil { return err } - target.Node.Content = append(target.Node.Content, extraNodes...) + target.Node.Content = append(deepCloneContent(lhs.Node.Content), extraNodes...) return nil } diff --git a/pkg/yqlib/operator_add_test.go b/pkg/yqlib/operator_add_test.go index 3f7206be..17d7969e 100644 --- a/pkg/yqlib/operator_add_test.go +++ b/pkg/yqlib/operator_add_test.go @@ -14,6 +14,15 @@ var addOperatorScenarios = []expressionScenario{ "D0, P[1 a], (!!int)::3\n", }, }, + { + skipDoc: true, + document: `[[c], [b]]`, + expression: `.[] | . += "a"`, + expected: []string{ + "D0, P[0], (!!seq)::[c, a]\n", + "D0, P[1], (!!seq)::[b, a]\n", + }, + }, { skipDoc: true, document: `{}`, diff --git a/pkg/yqlib/operator_multiply_test.go b/pkg/yqlib/operator_multiply_test.go index 0b7ab2de..8b4236de 100644 --- a/pkg/yqlib/operator_multiply_test.go +++ b/pkg/yqlib/operator_multiply_test.go @@ -93,6 +93,15 @@ var multiplyOperatorScenarios = []expressionScenario{ "D0, P[], (!!map)::sample:\n - &a\n - !!merge <<: *a\n", }, }, + { + skipDoc: true, + document: `[[c], [b]]`, + expression: `.[] | . *+ ["a"]`, + expected: []string{ + "D0, P[0], (!!seq)::[c, a]\n", + "D0, P[1], (!!seq)::[b, a]\n", + }, + }, { skipDoc: true, document: docWithHeader, diff --git a/pkg/yqlib/operators.go b/pkg/yqlib/operators.go index afddf0f4..6ca50254 100644 --- a/pkg/yqlib/operators.go +++ b/pkg/yqlib/operators.go @@ -19,14 +19,18 @@ func compoundAssignFunction(d *dataTreeNavigator, context Context, expressionNod } assignmentOp := &Operation{OperationType: assignOpType, Preferences: expressionNode.Operation.Preferences} - valueOp := &Operation{OperationType: valueOpType} for el := lhs.MatchingNodes.Front(); el != nil; el = el.Next() { candidate := el.Value.(*CandidateNode) - valueOp.CandidateNode = candidate - valueExpression := &ExpressionNode{Operation: valueOp} + clone, err := candidate.Copy() + if err != nil { + return Context{}, err + } + valueCopyExp := &ExpressionNode{Operation: &Operation{OperationType: valueOpType, CandidateNode: clone}} - assignmentOpNode := &ExpressionNode{Operation: assignmentOp, LHS: valueExpression, RHS: calculation(valueExpression, expressionNode.RHS)} + valueExpression := &ExpressionNode{Operation: &Operation{OperationType: valueOpType, CandidateNode: candidate}} + + assignmentOpNode := &ExpressionNode{Operation: assignmentOp, LHS: valueExpression, RHS: calculation(valueCopyExp, expressionNode.RHS)} _, err = d.GetMatchingNodes(context, assignmentOpNode) if err != nil {