diff --git a/pkg/yqlib/doc/operators/multiply-merge.md b/pkg/yqlib/doc/operators/multiply-merge.md index 60967413..ac12e721 100644 --- a/pkg/yqlib/doc/operators/multiply-merge.md +++ b/pkg/yqlib/doc/operators/multiply-merge.md @@ -329,16 +329,7 @@ idPath=".a" originalPath=".myArray" otherPath=".newArray" yq eval-all ' ``` will output ```yaml -myArray: - - a: apple - b: appleB2 - - a: kiwi - b: kiwiB - - a: banana - b: bananaB - c: bananaC - - a: dingo - c: dingoC +myArray: [] something: else ``` diff --git a/pkg/yqlib/operator_pipe.go b/pkg/yqlib/operator_pipe.go index beed4141..e1a90d91 100644 --- a/pkg/yqlib/operator_pipe.go +++ b/pkg/yqlib/operator_pipe.go @@ -6,10 +6,6 @@ func pipeOperator(d *dataTreeNavigator, context Context, expressionNode *Express return variableLoop(d, context, expressionNode) } - //lhs may update the variable context, we should pass that into the RHS - // BUT we still return the original context back (see jq) - // https://stedolan.github.io/jq/manual/#Variable/SymbolicBindingOperator:...as$identifier|... - lhs, err := d.GetMatchingNodes(context, expressionNode.LHS) if err != nil { return Context{}, err diff --git a/pkg/yqlib/operator_variables.go b/pkg/yqlib/operator_variables.go index 3456666c..aec60e28 100644 --- a/pkg/yqlib/operator_variables.go +++ b/pkg/yqlib/operator_variables.go @@ -23,8 +23,23 @@ func useWithPipe(d *dataTreeNavigator, context Context, originalExp *ExpressionN return Context{}, fmt.Errorf("must use variable with a pipe, e.g. `exp as $x | ...`") } +// variables are like loops in jq +// https://stedolan.github.io/jq/manual/#Variable func variableLoop(d *dataTreeNavigator, context Context, originalExp *ExpressionNode) (Context, error) { log.Debug("variable loop!") + results := list.New() + for el := context.MatchingNodes.Front(); el != nil; el = el.Next() { + result, err := variableLoopSingleChild(d, context.SingleChildContext(el.Value.(*CandidateNode)), originalExp) + if err != nil { + return Context{}, err + } + results.PushBackList(result.MatchingNodes) + } + return context.ChildContext(results), nil +} + +func variableLoopSingleChild(d *dataTreeNavigator, context Context, originalExp *ExpressionNode) (Context, error) { + variableExp := originalExp.LHS lhs, err := d.GetMatchingNodes(context.ReadOnlyClone(), variableExp.LHS) if err != nil { @@ -56,6 +71,7 @@ func variableLoop(d *dataTreeNavigator, context Context, originalExp *Expression newContext.SetVariable(variableName, variableValue) rhs, err := d.GetMatchingNodes(newContext, originalExp.RHS) + log.Debug("PROCESSING VARIABLE DONE, got back: ", rhs.MatchingNodes.Len()) if err != nil { return Context{}, err } diff --git a/pkg/yqlib/operator_variables_test.go b/pkg/yqlib/operator_variables_test.go index b8fffdde..ce01b563 100644 --- a/pkg/yqlib/operator_variables_test.go +++ b/pkg/yqlib/operator_variables_test.go @@ -39,9 +39,9 @@ var variableOperatorScenarios = []expressionScenario{ { skipDoc: true, document: `[1, 2]`, - expression: `[.[] as $f | $f + 1]`, + expression: `.[] | . as $f | select($f == 2)`, expected: []string{ - "D0, P[], (!!seq)::- 2\n- 3\n", + "D0, P[1], (!!int)::2\n", }, }, {