Fixed variable operator to work like jq

This commit is contained in:
Mike Farah 2023-02-28 16:14:42 +11:00
parent 0cd15867d0
commit eb9181670e
9 changed files with 44 additions and 16 deletions

View File

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

View File

@ -16,7 +16,7 @@ var alternativeOperatorScenarios = []expressionScenario{
},
{
skipDoc: true,
expression: `(.b // "hello") as $x`,
expression: `(.b // "hello") as $x | .`,
document: `a: bridge`,
expected: []string{
"D0, P[], (doc)::a: bridge\n",

View File

@ -102,7 +102,7 @@ var booleanOperatorScenarios = []expressionScenario{
{
skipDoc: true,
document: `[{pet: cat}]`,
expression: `any_c(.name == "harry") as $c`,
expression: `any_c(.name == "harry") as $c | .`,
expected: []string{
"D0, P[], (doc)::[{pet: cat}]\n",
},
@ -110,9 +110,17 @@ var booleanOperatorScenarios = []expressionScenario{
{
skipDoc: true,
document: `[{pet: cat}]`,
expression: `all_c(.name == "harry") as $c`,
expression: `any_c(.name == "harry") as $c | $c`,
expected: []string{
"D0, P[], (doc)::[{pet: cat}]\n",
"D0, P[], (!!bool)::false\n",
},
},
{
skipDoc: true,
document: `[{pet: cat}]`,
expression: `all_c(.name == "harry") as $c | $c`,
expected: []string{
"D0, P[], (!!bool)::false\n",
},
},
{
@ -185,7 +193,7 @@ var booleanOperatorScenarios = []expressionScenario{
{
skipDoc: true,
document: `{}`,
expression: `(.a.b or .c) as $x`,
expression: `(.a.b or .c) as $x | .`,
expected: []string{
"D0, P[], (doc)::{}\n",
},
@ -193,7 +201,7 @@ var booleanOperatorScenarios = []expressionScenario{
{
skipDoc: true,
document: `{}`,
expression: `(.a.b and .c) as $x`,
expression: `(.a.b and .c) as $x | .`,
expected: []string{
"D0, P[], (doc)::{}\n",
},

View File

@ -47,7 +47,7 @@ var equalsOperatorScenarios = []expressionScenario{
{
skipDoc: true,
document: "{}",
expression: "(.a == .b) as $x",
expression: "(.a == .b) as $x | .",
expected: []string{
"D0, P[], (doc)::{}\n",
},
@ -63,7 +63,7 @@ var equalsOperatorScenarios = []expressionScenario{
{
skipDoc: true,
document: "{}",
expression: "(.a != .b) as $x",
expression: "(.a != .b) as $x | .",
expected: []string{
"D0, P[], (doc)::{}\n",
},

View File

@ -16,7 +16,7 @@ var hasOperatorScenarios = []expressionScenario{
{
skipDoc: true,
document: `a: hello`,
expression: `has(.b) as $c`,
expression: `has(.b) as $c | .`,
expected: []string{
"D0, P[], (doc)::a: hello\n",
},

View File

@ -8,7 +8,7 @@ var subtractOperatorScenarios = []expressionScenario{
{
skipDoc: true,
document: `{}`,
expression: "(.a - .b) as $x",
expression: "(.a - .b) as $x | .",
expected: []string{
"D0, P[], (doc)::{}\n",
},

View File

@ -151,7 +151,7 @@ var traversePathOperatorScenarios = []expressionScenario{
{
skipDoc: true,
document: `c: dog`,
expression: `.[.a.b] as $x`,
expression: `.[.a.b] as $x | .`,
expected: []string{
"D0, P[], (doc)::c: dog\n",
},

View File

@ -8,7 +8,7 @@ var unionOperatorScenarios = []expressionScenario{
{
skipDoc: true,
document: "{}",
expression: `(.a, .b.c) as $x`,
expression: `(.a, .b.c) as $x | .`,
expected: []string{
"D0, P[], (doc)::{}\n",
},

View File

@ -28,6 +28,17 @@ func useWithPipe(d *dataTreeNavigator, context Context, originalExp *ExpressionN
func variableLoop(d *dataTreeNavigator, context Context, originalExp *ExpressionNode) (Context, error) {
log.Debug("variable loop!")
results := list.New()
var evaluateAllTogether = true
for matchEl := context.MatchingNodes.Front(); matchEl != nil; matchEl = matchEl.Next() {
evaluateAllTogether = evaluateAllTogether && matchEl.Value.(*CandidateNode).EvaluateTogether
if !evaluateAllTogether {
break
}
}
if evaluateAllTogether {
return variableLoopSingleChild(d, context, originalExp)
}
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
result, err := variableLoopSingleChild(d, context.SingleChildContext(el.Value.(*CandidateNode)), originalExp)
if err != nil {
@ -56,17 +67,17 @@ func variableLoopSingleChild(d *dataTreeNavigator, context Context, originalExp
// now we loop over lhs, set variable to each result and calculate originalExp.Rhs
for el := lhs.MatchingNodes.Front(); el != nil; el = el.Next() {
log.Debug("PROCESSING VARIABLE: ", NodeToString(el.Value.(*CandidateNode)))
var variableValue = list.New()
if prefs.IsReference {
variableValue.PushBack(el.Value)
} else {
copy, err := el.Value.(*CandidateNode).Copy()
candidateCopy, err := el.Value.(*CandidateNode).Copy()
if err != nil {
return Context{}, err
}
variableValue.PushBack(copy)
variableValue.PushBack(candidateCopy)
}
log.Debug("PROCESSING VARIABLE: ", NodeToString(el.Value.(*CandidateNode)))
newContext := context.ChildContext(context.MatchingNodes)
newContext.SetVariable(variableName, variableValue)