Fixed merge globbing wildcards in keys #2564

This commit is contained in:
Mike Farah 2026-01-31 15:44:50 +11:00
parent bdeedbd275
commit 4bbffa9022
4 changed files with 28 additions and 3 deletions

View File

@ -451,6 +451,7 @@ func multiplyWithPrefs(op *operationType) yqAction {
prefs.AssignPrefs.ClobberCustomTags = true
}
prefs.TraversePrefs.DontFollowAlias = true
prefs.TraversePrefs.ExactKeyMatch = true
op := &Operation{OperationType: op, Value: multiplyOpType.Type, StringValue: options, Preferences: prefs}
return &token{TokenType: operationToken, Operation: op}, nil
}

View File

@ -168,7 +168,7 @@ func mergeObjects(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs
// only need to recurse the array if we are doing a deep merge
prefs := recursiveDescentPreferences{RecurseArray: preferences.DeepMergeArrays,
TraversePreferences: traversePreferences{DontFollowAlias: true, IncludeMapKeys: true}}
TraversePreferences: traversePreferences{DontFollowAlias: true, IncludeMapKeys: true, ExactKeyMatch: true}}
log.Debugf("merge - preferences.DeepMergeArrays %v", preferences.DeepMergeArrays)
log.Debugf("merge - preferences.AppendArrays %v", preferences.AppendArrays)
err := recursiveDecent(results, context.SingleChildContext(rhs), prefs)

View File

@ -86,7 +86,26 @@ c:
<<: *cat
`
var mergeWithGlobA = `
"**cat": things,
"meow**cat": stuff
`
var mergeWithGlobB = `
"**cat": newThings,
`
var multiplyOperatorScenarios = []expressionScenario{
{
description: "glob keys are treated as literals when merging",
skipDoc: true,
document: mergeWithGlobA,
document2: mergeWithGlobB,
expression: `select(fi == 0) * select(fi == 1)`,
expected: []string{
"D0, P[], (!!map)::\n\"**cat\": newThings,\n\"meow**cat\": stuff\n",
},
},
{
skipDoc: true,
document: mergeArrayWithAnchors,

View File

@ -14,6 +14,7 @@ type traversePreferences struct {
DontAutoCreate bool // by default, we automatically create entries on the fly.
DontIncludeMapValues bool
OptionalTraverse bool // e.g. .adf?
ExactKeyMatch bool // by default we let wild/glob patterns. Don't do that for merge though.
}
func splat(context Context, prefs traversePreferences) (Context, error) {
@ -216,7 +217,11 @@ func traverseArrayWithIndices(node *CandidateNode, indices []*CandidateNode, pre
return newMatches, nil
}
func keyMatches(key *CandidateNode, wantedKey string) bool {
func keyMatches(key *CandidateNode, wantedKey string, exactKeyMatch bool) bool {
if exactKeyMatch {
// this is used for merge
return key.Value == wantedKey
}
return matchKey(key.Value, wantedKey)
}
@ -303,7 +308,7 @@ func doTraverseMap(newMatches *orderedmap.OrderedMap, node *CandidateNode, wante
return err
}
}
} else if splat || keyMatches(key, wantedKey) {
} else if splat || keyMatches(key, wantedKey, prefs.ExactKeyMatch) {
log.Debug("MATCHED")
if prefs.IncludeMapKeys {
log.Debug("including key")