Fix add op when there are not matches piped in, #2383, #2384

This commit is contained in:
Mike Farah 2025-06-12 14:25:05 +10:00
parent b15ce77cad
commit 88bfbec97b
3 changed files with 55 additions and 1 deletions

View File

@ -9,6 +9,7 @@ type ExpressionNode struct {
Operation *Operation
LHS *ExpressionNode
RHS *ExpressionNode
Parent *ExpressionNode
}
type ExpressionParserInterface interface {
@ -57,6 +58,7 @@ func (p *expressionParserImpl) createExpressionTree(postFixPath []*Operation) (*
}
remaining, rhs := stack[:len(stack)-1], stack[len(stack)-1]
newNode.RHS = rhs
rhs.Parent = &newNode
stack = remaining
case 2:
if len(stack) < 2 {
@ -64,7 +66,11 @@ func (p *expressionParserImpl) createExpressionTree(postFixPath []*Operation) (*
}
remaining, lhs, rhs := stack[:len(stack)-2], stack[len(stack)-2], stack[len(stack)-1]
newNode.LHS = lhs
lhs.Parent = &newNode
newNode.RHS = rhs
rhs.Parent = &newNode
stack = remaining
}
}

View File

@ -38,8 +38,11 @@ func toNodes(candidate *CandidateNode, lhs *CandidateNode) []*CandidateNode {
func addOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
log.Debugf("Add operator")
// if we don't have any matching nodes, but we were piped into (have a parent exp?) then we
// shouldn't calcWhenEmpt
calcWhenEmpty := expressionNode.Parent == nil
return crossFunction(d, context.ReadOnlyClone(), expressionNode, add, true)
return crossFunction(d, context.ReadOnlyClone(), expressionNode, add, calcWhenEmpty)
}
func add(_ *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {

View File

@ -5,6 +5,51 @@ import (
)
var addOperatorScenarios = []expressionScenario{
{
skipDoc: true,
expression: `"foo" + "bar"`,
expected: []string{
"D0, P[], (!!str)::foobar\n",
},
},
{
skipDoc: true,
expression: `[] | .[] | "foo" + .`,
expected: []string{},
},
{
skipDoc: true,
expression: `[] | .[] | . + "foo"`,
expected: []string{},
},
{
skipDoc: true,
expression: `select(.) | "foo" + "bar"`,
expected: []string{
"D0, P[], (!!str)::foobar\n", // jq does not do this :/ - but yq has for quite some time.
},
},
{
skipDoc: true,
document: "apples: 3",
expression: `.apples + 3`,
expected: []string{
"D0, P[apples], (!!int)::6\n",
},
},
{
skipDoc: true,
document: "apples: 3",
expression: `.bobo + 3`,
expected: []string{
"D0, P[], (!!int)::3\n",
},
},
{
skipDoc: true,
expression: `select(.) | "cat" + .`,
expected: []string{},
},
{
skipDoc: true,
document: `[{a: foo, b: bar}, {a: 1, b: 2}]`,