diff --git a/pkg/yqlib/candidate_node.go b/pkg/yqlib/candidate_node.go index 2f268f68..5156ac4b 100644 --- a/pkg/yqlib/candidate_node.go +++ b/pkg/yqlib/candidate_node.go @@ -239,14 +239,13 @@ func (n *CandidateNode) AddKeyValueChild(rawKey *CandidateNode, rawValue *Candid func (n *CandidateNode) AddChild(rawChild *CandidateNode) { value := rawChild.Copy() value.SetParent(n) - if value.Key != nil { - value.Key.SetParent(n) - } else { - index := len(n.Content) - keyNode := createScalarNode(index, fmt.Sprintf("%v", index)) - keyNode.SetParent(n) - value.Key = keyNode - } + value.IsMapKey = false + + index := len(n.Content) + keyNode := createScalarNode(index, fmt.Sprintf("%v", index)) + keyNode.SetParent(n) + value.Key = keyNode + n.Content = append(n.Content, value) } diff --git a/pkg/yqlib/operator_delete_test.go b/pkg/yqlib/operator_delete_test.go index cae7bc83..bc3375a0 100644 --- a/pkg/yqlib/operator_delete_test.go +++ b/pkg/yqlib/operator_delete_test.go @@ -119,6 +119,60 @@ var deleteOperatorScenarios = []expressionScenario{ "D0, P[], (!!map)::a: []\n", }, }, + { + skipDoc: true, + description: "Delete entry appended to an array", + document: `[1,2]`, + expression: `. += [3] | del(.[2])`, + expected: []string{ + "D0, P[], (!!seq)::[1, 2]\n", + }, + }, + { + skipDoc: true, + description: "Delete entry after sorting an array", + document: `[3,2,1]`, + expression: `sort | del(.[2])`, + expected: []string{ + "D0, P[], (!!seq)::[1, 2]\n", + }, + }, + { + skipDoc: true, + description: "Delete entry after reversing an array", + document: `[1,2,3]`, + expression: `reverse | del(.[2])`, + expected: []string{ + "D0, P[], (!!seq)::[3, 2]\n", + }, + }, + { + skipDoc: true, + description: "Delete entry after shuffling an array", + document: `[1,2,3]`, + expression: `shuffle | del(.[2])`, + expected: []string{ + "D0, P[], (!!seq)::[3, 1]\n", + }, + }, + { + skipDoc: true, + description: "Delete entry from keys array", + document: `{"a": 1, "b": 2, "c": 3}`, + expression: `keys | del(.[] | select(.=="b"))`, + expected: []string{ + "D0, P[], (!!seq)::- \"a\"\n- \"c\"\n", + }, + }, + { + skipDoc: true, + description: "Delete entry after flattening an array", + document: `[1,[2],[[3]]]`, + expression: `flatten | del(.[2])`, + expected: []string{ + "D0, P[], (!!seq)::[1, 2]\n", + }, + }, { skipDoc: true, document: `a: [10,x,10, 10, x, 10]`, diff --git a/pkg/yqlib/operator_flatten_test.go b/pkg/yqlib/operator_flatten_test.go index adf56d08..8db3c15f 100644 --- a/pkg/yqlib/operator_flatten_test.go +++ b/pkg/yqlib/operator_flatten_test.go @@ -21,8 +21,8 @@ var flattenOperatorScenarios = []expressionScenario{ expression: `flatten[]`, expected: []string{ "D0, P[0], (!!int)::1\n", - "D0, P[0], (!!int)::2\n", - "D0, P[0], (!!int)::3\n", + "D0, P[1], (!!int)::2\n", + "D0, P[2], (!!int)::3\n", }, }, { @@ -40,8 +40,8 @@ var flattenOperatorScenarios = []expressionScenario{ expression: `flatten(1)[]`, expected: []string{ "D0, P[0], (!!int)::1\n", - "D0, P[0], (!!int)::2\n", - "D0, P[0], (!!seq)::[3]\n", + "D0, P[1], (!!int)::2\n", + "D0, P[2], (!!seq)::[3]\n", }, }, { diff --git a/pkg/yqlib/operator_keys.go b/pkg/yqlib/operator_keys.go index e95afacf..bdcd1250 100644 --- a/pkg/yqlib/operator_keys.go +++ b/pkg/yqlib/operator_keys.go @@ -65,19 +65,20 @@ func getMapKeys(node *CandidateNode) *CandidateNode { for index := 0; index < len(node.Content); index = index + 2 { contents = append(contents, node.Content[index]) } - return &CandidateNode{Kind: SequenceNode, Tag: "!!seq", Content: contents} + + seq := &CandidateNode{Kind: SequenceNode, Tag: "!!seq"} + seq.AddChildren(contents) + return seq } func getIndices(node *CandidateNode) *CandidateNode { var contents = make([]*CandidateNode, len(node.Content)) for index := range node.Content { - contents[index] = &CandidateNode{ - Kind: ScalarNode, - Tag: "!!int", - Value: fmt.Sprintf("%v", index), - } + contents[index] = createScalarNode(index, fmt.Sprintf("%v", index)) } - return &CandidateNode{Kind: SequenceNode, Tag: "!!seq", Content: contents} + seq := &CandidateNode{Kind: SequenceNode, Tag: "!!seq"} + seq.AddChildren(contents) + return seq } diff --git a/pkg/yqlib/operator_keys_test.go b/pkg/yqlib/operator_keys_test.go index 15086c8e..b584661c 100644 --- a/pkg/yqlib/operator_keys_test.go +++ b/pkg/yqlib/operator_keys_test.go @@ -45,8 +45,8 @@ var keysOperatorScenarios = []expressionScenario{ document: `{dog: woof, cat: meow}`, expression: `keys[]`, expected: []string{ - "D0, P[dog], (!!str)::dog\n", - "D0, P[cat], (!!str)::cat\n", + "D0, P[0], (!!str)::dog\n", + "D0, P[1], (!!str)::cat\n", }, }, { diff --git a/pkg/yqlib/operator_reverse_test.go b/pkg/yqlib/operator_reverse_test.go index 0ea0d672..fc21f6e0 100644 --- a/pkg/yqlib/operator_reverse_test.go +++ b/pkg/yqlib/operator_reverse_test.go @@ -17,8 +17,8 @@ var reverseOperatorScenarios = []expressionScenario{ document: "[1, 2]", expression: `reverse[]`, expected: []string{ - "D0, P[1], (!!int)::2\n", - "D0, P[0], (!!int)::1\n", + "D0, P[0], (!!int)::2\n", + "D0, P[1], (!!int)::1\n", }, }, { diff --git a/pkg/yqlib/operator_shuffle.go b/pkg/yqlib/operator_shuffle.go index 9ccad23d..b1ff0516 100644 --- a/pkg/yqlib/operator_shuffle.go +++ b/pkg/yqlib/operator_shuffle.go @@ -26,7 +26,12 @@ func shuffleOperator(_ *dataTreeNavigator, context Context, _ *ExpressionNode) ( a := result.Content - myRand.Shuffle(len(a), func(i, j int) { a[i], a[j] = a[j], a[i] }) + myRand.Shuffle(len(a), func(i, j int) { + a[i], a[j] = a[j], a[i] + oldIndex := a[i].Key.Value + a[i].Key.Value = a[j].Key.Value + a[j].Key.Value = oldIndex + }) results.PushBack(result) } diff --git a/pkg/yqlib/operator_shuffle_test.go b/pkg/yqlib/operator_shuffle_test.go index 0c4e00ac..bad1f4d6 100644 --- a/pkg/yqlib/operator_shuffle_test.go +++ b/pkg/yqlib/operator_shuffle_test.go @@ -17,9 +17,9 @@ var shuffleOperatorScenarios = []expressionScenario{ document: "[1, 2, 3]", expression: `shuffle[]`, expected: []string{ - "D0, P[2], (!!int)::3\n", - "D0, P[0], (!!int)::1\n", - "D0, P[1], (!!int)::2\n", + "D0, P[0], (!!int)::3\n", + "D0, P[1], (!!int)::1\n", + "D0, P[2], (!!int)::2\n", }, }, diff --git a/pkg/yqlib/operator_sort_test.go b/pkg/yqlib/operator_sort_test.go index efb2a2d7..39ba2347 100644 --- a/pkg/yqlib/operator_sort_test.go +++ b/pkg/yqlib/operator_sort_test.go @@ -17,8 +17,8 @@ var sortByOperatorScenarios = []expressionScenario{ document: "[{a: banana},{a: apple}]", expression: `sort_by(.a)[]`, expected: []string{ - "D0, P[1], (!!map)::{a: apple}\n", - "D0, P[0], (!!map)::{a: banana}\n", + "D0, P[0], (!!map)::{a: apple}\n", + "D0, P[1], (!!map)::{a: banana}\n", }, }, { @@ -27,9 +27,9 @@ var sortByOperatorScenarios = []expressionScenario{ document: "[{a: banana},null,{a: apple}]", expression: `sort_by(.a)[]`, expected: []string{ - "D0, P[1], (!!null)::null\n", - "D0, P[2], (!!map)::{a: apple}\n", - "D0, P[0], (!!map)::{a: banana}\n", + "D0, P[0], (!!null)::null\n", + "D0, P[1], (!!map)::{a: apple}\n", + "D0, P[2], (!!map)::{a: banana}\n", }, }, { @@ -149,8 +149,8 @@ var sortByOperatorScenarios = []expressionScenario{ document: "[8,null]", expression: `sort[]`, expected: []string{ - "D0, P[1], (!!null)::null\n", - "D0, P[0], (!!int)::8\n", + "D0, P[0], (!!null)::null\n", + "D0, P[1], (!!int)::8\n", }, }, {