Variable loop wip

This commit is contained in:
Mike Farah 2023-02-23 16:30:18 +11:00
parent ae228c4b2a
commit 668e5600c3
4 changed files with 19 additions and 16 deletions

View File

@ -329,16 +329,7 @@ idPath=".a" originalPath=".myArray" otherPath=".newArray" yq eval-all '
``` ```
will output will output
```yaml ```yaml
myArray: myArray: []
- a: apple
b: appleB2
- a: kiwi
b: kiwiB
- a: banana
b: bananaB
c: bananaC
- a: dingo
c: dingoC
something: else something: else
``` ```

View File

@ -6,10 +6,6 @@ func pipeOperator(d *dataTreeNavigator, context Context, expressionNode *Express
return variableLoop(d, context, expressionNode) 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) lhs, err := d.GetMatchingNodes(context, expressionNode.LHS)
if err != nil { if err != nil {
return Context{}, err return Context{}, err

View File

@ -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 | ...`") 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) { func variableLoop(d *dataTreeNavigator, context Context, originalExp *ExpressionNode) (Context, error) {
log.Debug("variable loop!") 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 variableExp := originalExp.LHS
lhs, err := d.GetMatchingNodes(context.ReadOnlyClone(), variableExp.LHS) lhs, err := d.GetMatchingNodes(context.ReadOnlyClone(), variableExp.LHS)
if err != nil { if err != nil {
@ -56,6 +71,7 @@ func variableLoop(d *dataTreeNavigator, context Context, originalExp *Expression
newContext.SetVariable(variableName, variableValue) newContext.SetVariable(variableName, variableValue)
rhs, err := d.GetMatchingNodes(newContext, originalExp.RHS) rhs, err := d.GetMatchingNodes(newContext, originalExp.RHS)
log.Debug("PROCESSING VARIABLE DONE, got back: ", rhs.MatchingNodes.Len())
if err != nil { if err != nil {
return Context{}, err return Context{}, err
} }

View File

@ -39,9 +39,9 @@ var variableOperatorScenarios = []expressionScenario{
{ {
skipDoc: true, skipDoc: true,
document: `[1, 2]`, document: `[1, 2]`,
expression: `[.[] as $f | $f + 1]`, expression: `.[] | . as $f | select($f == 2)`,
expected: []string{ expected: []string{
"D0, P[], (!!seq)::- 2\n- 3\n", "D0, P[1], (!!int)::2\n",
}, },
}, },
{ {