From 51b64e6cf3db439eaee4978c392e088e695610c7 Mon Sep 17 00:00:00 2001 From: Mike Farah Date: Fri, 9 Sep 2022 12:28:38 +1000 Subject: [PATCH] Fixing relative merge bug #1333 --- pkg/yqlib/operator_multiply_test.go | 18 ++++++++++++++++++ pkg/yqlib/operators.go | 16 +++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/pkg/yqlib/operator_multiply_test.go b/pkg/yqlib/operator_multiply_test.go index 8a16a411..4c9a2060 100644 --- a/pkg/yqlib/operator_multiply_test.go +++ b/pkg/yqlib/operator_multiply_test.go @@ -561,6 +561,24 @@ var multiplyOperatorScenarios = []expressionScenario{ "D0, P[], (doc)::a: {cat: !horse 5}\nb: {cat: 5}\n", }, }, + { + skipDoc: true, + description: "Relative merge, new fields only", + document: "a: {a: original}\n", + expression: `.a *=n load("../../examples/thing.yml")`, + expected: []string{ + "D0, P[], (doc)::a: {a: original, b: cool.}\n", + }, + }, + { + skipDoc: true, + description: "Relative merge", + document: "a: {a: original}\n", + expression: `.a *= load("../../examples/thing.yml")`, + expected: []string{ + "D0, P[], (doc)::a: {a: apple is included, b: cool.}\n", + }, + }, } func TestMultiplyOperatorScenarios(t *testing.T) { diff --git a/pkg/yqlib/operators.go b/pkg/yqlib/operators.go index c4b79f7a..00f45d49 100644 --- a/pkg/yqlib/operators.go +++ b/pkg/yqlib/operators.go @@ -19,7 +19,21 @@ func compoundAssignFunction(d *dataTreeNavigator, context Context, expressionNod return Context{}, err } - assignmentOp := &Operation{OperationType: assignOpType, Preferences: expressionNode.Operation.Preferences} + // tricky logic when we are running *= with flags. + // we have an op like: .a *=nc .b + // which should roughly translate to .a =c .a *nc .b + // note that the 'n' flag only applies to the multiple op, not the assignment + // but the clobber flag applies to both! + + prefs := assignPreferences{} + switch typedPref := expressionNode.Operation.Preferences.(type) { + case assignPreferences: + prefs = typedPref + case multiplyPreferences: + prefs.ClobberCustomTags = typedPref.AssignPrefs.ClobberCustomTags + } + + assignmentOp := &Operation{OperationType: assignOpType, Preferences: prefs} for el := lhs.MatchingNodes.Front(); el != nil; el = el.Next() { candidate := el.Value.(*CandidateNode)