diff --git a/pkg/yqlib/doc/operators/multiply-merge.md b/pkg/yqlib/doc/operators/multiply-merge.md index 6db12660..60967413 100644 --- a/pkg/yqlib/doc/operators/multiply-merge.md +++ b/pkg/yqlib/doc/operators/multiply-merge.md @@ -499,3 +499,43 @@ b: !goat dog: woof ``` +## Merging a null with a map +Running +```bash +yq --null-input 'null * {"some": "thing"}' +``` +will output +```yaml +some: thing +``` + +## Merging a map with null +Running +```bash +yq --null-input '{"some": "thing"} * null' +``` +will output +```yaml +some: thing +``` + +## Merging an null with an array +Running +```bash +yq --null-input 'null * ["some"]' +``` +will output +```yaml +- some +``` + +## Merging an array with null +Running +```bash +yq --null-input '["some"] * null' +``` +will output +```yaml +- some +``` + diff --git a/pkg/yqlib/operator_multiply.go b/pkg/yqlib/operator_multiply.go index ac27ad1f..defca156 100644 --- a/pkg/yqlib/operator_multiply.go +++ b/pkg/yqlib/operator_multiply.go @@ -60,8 +60,14 @@ func multiply(preferences multiplyPreferences) func(d *dataTreeNavigator, contex log.Debugf("Multiplying LHS: %v", lhs.Node.Tag) log.Debugf("- RHS: %v", rhs.Node.Tag) - if lhs.Node.Kind == yaml.MappingNode && rhs.Node.Kind == yaml.MappingNode || - (lhs.Node.Kind == yaml.SequenceNode && rhs.Node.Kind == yaml.SequenceNode) { + if rhs.Node.Tag == "!!null" { + return lhs.Copy() + } + + if (lhs.Node.Kind == yaml.MappingNode && rhs.Node.Kind == yaml.MappingNode) || + (lhs.Node.Tag == "!!null" && rhs.Node.Kind == yaml.MappingNode) || + (lhs.Node.Kind == yaml.SequenceNode && rhs.Node.Kind == yaml.SequenceNode) || + (lhs.Node.Tag == "!!null" && rhs.Node.Kind == yaml.SequenceNode) { var newBlank = CandidateNode{} err := copier.CopyWithOption(&newBlank, lhs, copier.Option{IgnoreEmpty: true, DeepCopy: true}) if err != nil { diff --git a/pkg/yqlib/operator_multiply_test.go b/pkg/yqlib/operator_multiply_test.go index d775986c..c20278e6 100644 --- a/pkg/yqlib/operator_multiply_test.go +++ b/pkg/yqlib/operator_multiply_test.go @@ -579,6 +579,41 @@ var multiplyOperatorScenarios = []expressionScenario{ "D0, P[], (doc)::a: {a: apple is included, b: cool.}\n", }, }, + { + description: "Merging a null with a map", + expression: `null * {"some": "thing"}`, + expected: []string{ + "D0, P[], (!!map)::some: thing\n", + }, + }, + { + description: "Merging a map with null", + expression: `{"some": "thing"} * null`, + expected: []string{ + "D0, P[], (!!map)::some: thing\n", + }, + }, + { + description: "Merging an null with an array", + expression: `null * ["some"]`, + expected: []string{ + "D0, P[], (!!seq)::- some\n", + }, + }, + { + description: "Merging an array with null", + expression: `["some"] * null`, + expected: []string{ + "D0, P[], (!!seq)::- some\n", + }, + }, + { + skipDoc: true, + expression: `null * null`, + expected: []string{ + "D0, P[], (!!null)::null\n", + }, + }, } func TestMultiplyOperatorScenarios(t *testing.T) {