From b18851b7489e2f0bb770f73923b438121ceedbe3 Mon Sep 17 00:00:00 2001 From: upstream Date: Fri, 4 Sep 2026 08:20:57 +0200 Subject: [PATCH] Upstream itchyny/gojq state of the touched files before f68bda411a --- cli/test.yaml | 85 ++------------------------------------------------- compiler.go | 27 ++++++++++------ func.go | 51 ++++++++++--------------------- 3 files changed, 35 insertions(+), 128 deletions(-) diff --git a/cli/test.yaml b/cli/test.yaml index 3b77647..584574b 100644 --- a/cli/test.yaml +++ b/cli/test.yaml @@ -2407,29 +2407,6 @@ "/a,b/c/d/e,f/" ",/ /a/,/b/,/ /c/,/ /d/,/ /e/,/f/,/ " -- name: split/1 function against empty string - args: - - -c - - '.[] as $t | .[] as $s | $s | split($t)' - input: '["abc", "a", "b", ""]' - expected: | - ["",""] - ["a"] - ["b"] - [] - ["","bc"] - ["",""] - ["b"] - [] - ["a","c"] - ["a"] - ["",""] - [] - ["a","b","c"] - ["a"] - ["b"] - [] - - name: join function args: - 'join(",")' @@ -3608,16 +3585,6 @@ expected: | 8 -- name: reduce with assignment of multiple paths in update - args: - - -c - - 'reduce (1,2) as $i (.; (.[0], .[.[0]]) = $i), - reduce (1,2) as $i (.; (.[0], .[.[0]]) |= $i)' - input: '[0,0,0]' - expected: | - [2,2,0] - [2,2,0] - - name: reduce with query in start args: - 'reduce range(5) as $x (range(3); . + $x)' @@ -5022,46 +4989,6 @@ expected: | {"a":[{},{"b":[1,2,3]}]} -- name: getpath function against string - args: - - -c - - '[getpath([{"start":1,"end":3}]), getpath([{"start":-2,"end":null}]), getpath([1]), getpath([])]' - input: '"abcde"' - expected: | - ["bc","de","b","abcde"] - -- name: getpath function against string in a container - args: - - -c - - 'getpath(["a",{"start":0,"end":2}]), getpath(["a",1])' - input: '{"a":"abc"}' - expected: | - "ab" - "b" - -- name: getpath function against string round trip with path function - args: - - -c - - '[getpath(path(.[1:3])), getpath(path(.[1]))]' - input: '"abcde"' - expected: | - ["bc","b"] - -- name: getpath function against string round trip in a container - args: - - -c - - '. as $d | [path(.a[0:2]), path(.b[1])] | map(. as $p | $d | getpath($p))' - input: '{"a":"abc","b":"xyz"}' - expected: | - ["ab","y"] - -- name: getpath function against string with object key - args: - - 'getpath(["k"])' - input: '"abc"' - error: | - getpath(["k"]) cannot be applied to "abc": expected an object but got: string ("abc") - - name: getpath function error args: - 'getpath(["a",1,"b","c"])' @@ -5094,9 +5021,9 @@ expected: | {"a":[{"b":5}]} {"a":[{"b":5}],"b":0} - "getpath([\"a\",0,\"b\"]) cannot be applied to {\"a\":0}: expected an array but got: number (0)" + "getpath([\"a\",0,\"b\"]) cannot be applied to: object ({\"a\":0})" {"a":[{"b":5}]} - "getpath([\"a\",0,\"b\"]) cannot be applied to {\"a\":[0,1]}: expected an object but got: number (0)" + "getpath([\"a\",0,\"b\"]) cannot be applied to: object ({\"a\":[0,1]})" "getpath([\"a\",0,\"b\"]) cannot be applied to {\"a\":{\"b\":1}}: expected an array but got: object ({\"b\":1})" {"a":[{"b":5}]} {"a":[{"b":5,"c":3}]} @@ -5502,14 +5429,6 @@ expected: | [1,3,6,5,5] -- name: update-assignment operator against object with overlapping paths - args: - - -c - - '(.a.b,.a,.a.p.z) |= {p: ., q: .}' - input: '{"a":{"b":1}}' - expected: | - {"a":{"p":{"b":{"p":1,"q":1},"z":{"p":null,"q":null}},"q":{"b":{"p":1,"q":1}}}} - - name: update-assignment operator with optional operator args: - -c diff --git a/compiler.go b/compiler.go index 050951b..d2d7cfe 100644 --- a/compiler.go +++ b/compiler.go @@ -132,13 +132,18 @@ func (c *compiler) compile(q *Query) error { } func (c *compiler) compileImport(i *Import) error { - path, alias := cmp.Or(i.ImportPath, i.IncludePath), i.ImportAlias + var path, alias string + var err error + if i.ImportPath != "" { + path, alias = i.ImportPath, i.ImportAlias + } else { + path = i.IncludePath + } if c.moduleLoader == nil { return fmt.Errorf("cannot load module: %q", path) } if strings.HasPrefix(alias, "$") { var vals any - var err error if moduleLoader, ok := c.moduleLoader.(interface { LoadJSONWithMeta(string, map[string]any) (any, error) }); ok { @@ -161,7 +166,6 @@ func (c *compiler) compileImport(i *Import) error { return nil } var q *Query - var err error if moduleLoader, ok := c.moduleLoader.(interface { LoadModuleWithMeta(string, map[string]any) (*Query, error) }); ok { @@ -1093,7 +1097,7 @@ func (c *compiler) compileModify() { &code{op: opcall, v: [3]any{funcAllocator, 0, "_allocator"}}, &code{op: opstore, v: a}, &code{op: opload, v: v}, - &code{op: opfork, v: len(c.codes) + 40}, // reduce [L1] + &code{op: opfork, v: len(c.codes) + 39}, // reduce [L1] &code{op: oppathbegin}, // path(p) &code{op: opload, v: p}, &code{op: opcallpc}, @@ -1102,13 +1106,12 @@ func (c *compiler) compileModify() { &code{op: opstore, v: p}, // as $p (.; &code{op: opforklabel, v: l}, // label $l | &code{op: opload, v: v}, // - &code{op: opfork, v: len(c.codes) + 37}, // [L2] + &code{op: opfork, v: len(c.codes) + 36}, // [L2] &code{op: oppop}, // (getpath($p) | &code{op: opload, v: a}, - &code{op: opload, v: a}, &code{op: opload, v: p}, &code{op: opload, v: v}, - &code{op: opcall, v: [3]any{funcGetpathWithAllocator, 2, "getpath"}}, + &code{op: opcall, v: [3]any{internalFuncs["getpath"].callback, 1, "getpath"}}, &code{op: opload, v: f}, // f) &code{op: opcallpc}, &code{op: opload, v: p}, // setpath($p; ...) @@ -1116,8 +1119,8 @@ func (c *compiler) compileModify() { &code{op: opcall, v: [3]any{funcSetpathWithAllocator, 3, "_setpath"}}, &code{op: opstore, v: v}, &code{op: opload, v: v}, // ., break $l - &code{op: opfork, v: len(c.codes) + 35}, // [L4] - &code{op: opjump, v: len(c.codes) + 39}, // [L3] + &code{op: opfork, v: len(c.codes) + 34}, // [L4] + &code{op: opjump, v: len(c.codes) + 38}, // [L3] &code{op: opload, v: l}, // [L4] &code{op: opcall, v: [3]any{funcBreak(""), 0, "_break"}}, &code{op: opload, v: p}, // append $p to $d [L2] @@ -1270,7 +1273,11 @@ func listModuleDeps(q *Query) []any { if v == nil { v = make(map[string]any) } - v["relpath"] = cmp.Or(i.ImportPath, i.IncludePath) + relpath := i.ImportPath + if relpath == "" { + relpath = i.IncludePath + } + v["relpath"] = relpath if i.ImportAlias != "" { v["as"] = strings.TrimPrefix(i.ImportAlias, "$") } diff --git a/func.go b/func.go index 35c99fd..34a02f5 100644 --- a/func.go +++ b/func.go @@ -14,6 +14,7 @@ import ( "reflect" "regexp" "slices" + "sort" "strconv" "strings" "sync" @@ -437,7 +438,9 @@ func add(xs iter.Seq[any]) any { case []any: switch w := v.(type) { case nil: - v = slices.Clone(x) + s := make([]any, len(x)) + copy(s, x) + v = s continue case []any: v = append(w, x...) @@ -766,13 +769,6 @@ func funcSplit(v, x any) any { if !ok { return &func0TypeError{"split", x} } - return splitString(s, t) -} - -func splitString(s, t string) []any { - if s == "" { - return []any{} - } ss := strings.Split(s, t) xs := make([]any, len(ss)) for i, s := range ss { @@ -1488,17 +1484,6 @@ func (a allocator) allocated(v any) bool { return ok } -// release forgets every allocated address when the value is one of them, so -// that a value handed to a query is copied on update again. -func (a allocator) release(v any) { - switch v.(type) { - case map[string]any, []any: - if a.allocated(v) { - clear(a) - } - } -} - func (a allocator) makeObject(l int) map[string]any { v := make(map[string]any, l) if a != nil { @@ -1525,15 +1510,6 @@ func funcSetpathWithAllocator(v any, args []any) any { return setpath(v, args[0], args[1], args[2].(allocator)) } -// Used in compiler#compileModify: the update function may store the value -// anywhere, so it must not be modified in place afterwards. Registered as -// getpath to keep tracking paths through the call. -func funcGetpathWithAllocator(v any, args []any) any { - w := funcGetpath(v, args[0]) - args[1].(allocator).release(w) - return w -} - func setpath(v, p, n any, a allocator) any { path, ok := p.([]any) if !ok { @@ -1611,8 +1587,6 @@ func update(v any, path []any, n any, a allocator) (any, error) { return nil, &expectedArrayError{v} } case map[string]any: - // A slice bound stays reachable through the path. - a.release(p) switch v := v.(type) { case nil: return updateArraySlice(nil, p, path[1:], n, a) @@ -1805,9 +1779,14 @@ func funcGetpath(v, p any) any { } u := v for _, x := range path { - v = funcIndex2(nil, v, x) - if err, ok := v.(error); ok { - return &func1WrapError{"getpath", u, p, err} + switch v.(type) { + case nil, []any, map[string]any: + v = funcIndex2(nil, v, x) + if err, ok := v.(error); ok { + return &func1WrapError{"getpath", u, p, err} + } + default: + return &func1TypeError{"getpath", u, p} } } return v @@ -1851,8 +1830,10 @@ func funcBsearch(v, t any) any { if !ok { return &func1TypeError{"bsearch", v, t} } - i, ok := slices.BinarySearchFunc(vs, t, Compare) - if ok { + i := sort.Search(len(vs), func(i int) bool { + return Compare(vs[i], t) >= 0 + }) + if i < len(vs) && Compare(vs[i], t) == 0 { return i } return -i - 1