From e195c92906b68f9c9437f66dde11ab6a01cbea3d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 May 2026 05:57:31 +0000 Subject: [PATCH] vendor(deps): bump github.com/itchyny/gojq from 0.12.17 to 0.12.19 Bumps [github.com/itchyny/gojq](https://github.com/itchyny/gojq) from 0.12.17 to 0.12.19. - [Release notes](https://github.com/itchyny/gojq/releases) - [Changelog](https://github.com/itchyny/gojq/blob/main/CHANGELOG.md) - [Commits](https://github.com/itchyny/gojq/compare/v0.12.17...v0.12.19) --- updated-dependencies: - dependency-name: github.com/itchyny/gojq dependency-version: 0.12.19 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 4 +- go.sum | 12 +- vendor/github.com/itchyny/gojq/CHANGELOG.md | 29 + vendor/github.com/itchyny/gojq/Dockerfile | 2 +- vendor/github.com/itchyny/gojq/LICENSE | 2 +- vendor/github.com/itchyny/gojq/Makefile | 7 +- vendor/github.com/itchyny/gojq/README.md | 14 +- vendor/github.com/itchyny/gojq/builtin.go | 121 ++-- vendor/github.com/itchyny/gojq/builtin.jq | 45 +- vendor/github.com/itchyny/gojq/compare.go | 50 +- vendor/github.com/itchyny/gojq/compiler.go | 92 ++- vendor/github.com/itchyny/gojq/encoder.go | 15 +- vendor/github.com/itchyny/gojq/env.go | 1 + vendor/github.com/itchyny/gojq/error.go | 17 +- vendor/github.com/itchyny/gojq/execute.go | 12 +- vendor/github.com/itchyny/gojq/func.go | 407 +++++++------- vendor/github.com/itchyny/gojq/go.dev.mod | 6 +- vendor/github.com/itchyny/gojq/go.dev.sum | 8 +- vendor/github.com/itchyny/gojq/iter.go | 8 +- vendor/github.com/itchyny/gojq/lexer.go | 2 +- vendor/github.com/itchyny/gojq/normalize.go | 84 --- vendor/github.com/itchyny/gojq/operator.go | 122 ++-- vendor/github.com/itchyny/gojq/option.go | 2 +- vendor/github.com/itchyny/gojq/parser.go | 523 +++++++++--------- vendor/github.com/itchyny/gojq/parser.go.y | 6 +- vendor/github.com/itchyny/gojq/preview.go | 6 +- vendor/github.com/itchyny/gojq/query.go | 248 +-------- vendor/github.com/itchyny/gojq/type.go | 6 +- .../itchyny/timefmt-go/CHANGELOG.md | 11 + vendor/github.com/itchyny/timefmt-go/LICENSE | 2 +- .../github.com/itchyny/timefmt-go/format.go | 313 +++++------ vendor/github.com/itchyny/timefmt-go/parse.go | 186 ++++--- vendor/modules.txt | 8 +- 33 files changed, 1052 insertions(+), 1319 deletions(-) delete mode 100644 vendor/github.com/itchyny/gojq/normalize.go diff --git a/go.mod b/go.mod index df97b961..bf18e35c 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.24.0 require ( github.com/cenkalti/backoff v2.2.1+incompatible github.com/google/go-github/v59 v59.0.0 - github.com/itchyny/gojq v0.12.17 + github.com/itchyny/gojq v0.12.19 github.com/pelletier/go-toml v1.9.5 github.com/spf13/pflag v1.0.10 github.com/stretchr/testify v1.11.1 @@ -20,7 +20,7 @@ require ( require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/google/go-querystring v1.1.0 // indirect - github.com/itchyny/timefmt-go v0.1.6 // indirect + github.com/itchyny/timefmt-go v0.1.8 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect diff --git a/go.sum b/go.sum index 0d1d06cc..f553be25 100644 --- a/go.sum +++ b/go.sum @@ -6,17 +6,17 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/go-github/v59 v59.0.0 h1:7h6bgpF5as0YQLLkEiVqpgtJqjimMYhBkD4jT5aN3VA= github.com/google/go-github/v59 v59.0.0/go.mod h1:rJU4R0rQHFVFDOkqGWxfLNo6vEk4dv40oDjhV/gH6wM= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/itchyny/gojq v0.12.17 h1:8av8eGduDb5+rvEdaOO+zQUjA04MS0m3Ps8HiD+fceg= -github.com/itchyny/gojq v0.12.17/go.mod h1:WBrEMkgAfAGO1LUcGOckBl5O726KPp+OlkKug0I/FEY= -github.com/itchyny/timefmt-go v0.1.6 h1:ia3s54iciXDdzWzwaVKXZPbiXzxxnv1SPGFfM/myJ5Q= -github.com/itchyny/timefmt-go v0.1.6/go.mod h1:RRDZYC5s9ErkjQvTvvU7keJjxUYzIISJGxm9/mAERQg= +github.com/itchyny/gojq v0.12.19 h1:ttXA0XCLEMoaLOz5lSeFOZ6u6Q3QxmG46vfgI4O0DEs= +github.com/itchyny/gojq v0.12.19/go.mod h1:5galtVPDywX8SPSOrqjGxkBeDhSxEW1gSxoy7tn1iZY= +github.com/itchyny/timefmt-go v0.1.8 h1:1YEo1JvfXeAHKdjelbYr/uCuhkybaHCeTkH8Bo791OI= +github.com/itchyny/timefmt-go v0.1.8/go.mod h1:5E46Q+zj7vbTgWY8o5YkMeYb4I6GeWLFnetPy5oBrAI= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= diff --git a/vendor/github.com/itchyny/gojq/CHANGELOG.md b/vendor/github.com/itchyny/gojq/CHANGELOG.md index a10c4858..04399180 100644 --- a/vendor/github.com/itchyny/gojq/CHANGELOG.md +++ b/vendor/github.com/itchyny/gojq/CHANGELOG.md @@ -1,4 +1,33 @@ # Changelog +## [v0.12.19](https://github.com/itchyny/gojq/compare/v0.12.18..v0.12.19) (2026-04-01) +* fix `gsub` and `sub` when the replacement emits multiple values +* fix `fmax`, `fmin`, `modf` functions against NaN and infinities +* fix `join/1` to use `add/0` implementation and handle null separator +* fix `del` and `delpaths` on null to emit null +* fix arithmetic operations on the minimum integer +* fix `significand` function against subnormal numbers +* fix handling of `--` in cli flag parsing for jq compatibility +* fix `flatten/1` to emit error when the depth is NaN +* fix array slice update to validate index types +* fix string repetition boundary check to match jq behavior +* implement `splits/2` using `match/2` for better jq compatibility +* implement `to_entries` and `from_entries` in jq for simplicity +* improve performance of regexp functions by caching compiled regexps + +## [v0.12.18](https://github.com/itchyny/gojq/compare/v0.12.17..v0.12.18) (2025-12-02) +* implement `trimstr/1`, `toboolean/0` function +* fix `last/1` to be included in `builtins/0` +* fix `--indent 0` to preserve newlines +* fix string repetition to emit error when the result is too large +* increase the array index limit to 536870912 (`2^29`) +* stop numeric normalization for concurrent execution (see 1ace748d08df) +* support binding expressions with binary operators (`1 + 2 as $x | -$x`) +* improve `gojq.NewIter` to be a generic function +* improve logic for getting file contents on JSON parse error +* improve JSON parsing to preserve the precision of floating-point numbers +* improve YAML parsing performance and preserve the precision of large integers +* improve performance and reduce memory allocation of long-running queries + ## [v0.12.17](https://github.com/itchyny/gojq/compare/v0.12.16..v0.12.17) (2024-12-01) * implement `add/1`, `skip/2` functions * implement `--library-path` option as the alias of `-L` option diff --git a/vendor/github.com/itchyny/gojq/Dockerfile b/vendor/github.com/itchyny/gojq/Dockerfile index 96a14e99..4b469f49 100644 --- a/vendor/github.com/itchyny/gojq/Dockerfile +++ b/vendor/github.com/itchyny/gojq/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.23 AS builder +FROM golang:1.26 AS builder WORKDIR /app COPY go.* ./ diff --git a/vendor/github.com/itchyny/gojq/LICENSE b/vendor/github.com/itchyny/gojq/LICENSE index fe590040..6b4faf3b 100644 --- a/vendor/github.com/itchyny/gojq/LICENSE +++ b/vendor/github.com/itchyny/gojq/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2019-2024 itchyny +Copyright (c) 2019-2026 itchyny Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/github.com/itchyny/gojq/Makefile b/vendor/github.com/itchyny/gojq/Makefile index 15ace7d7..c92c0dbd 100644 --- a/vendor/github.com/itchyny/gojq/Makefile +++ b/vendor/github.com/itchyny/gojq/Makefile @@ -75,7 +75,7 @@ lint: $(GOBIN)/staticcheck staticcheck -checks all -tags gojq_debug ./... $(GOBIN)/staticcheck: - go install honnef.co/go/tools/cmd/staticcheck@latest + go install honnef.co/go/tools/cmd/staticcheck@v0.6.1 .PHONY: check-tools check-tools: @@ -89,9 +89,8 @@ clean: .PHONY: update update: export GOPROXY=direct update: - go get -u ./... && go mod tidy - go mod edit -modfile=go.dev.mod -droprequire=github.com/itchyny/{astgen,timefmt}-go - go get -u -modfile=go.dev.mod github.com/itchyny/{astgen,timefmt}-go && go generate + go get -u ./... && go get github.com/itchyny/go-yaml@gojq && go mod tidy + rm go.dev.sum && go get -u -modfile=go.dev.mod github.com/itchyny/{astgen,timefmt}-go && go generate .PHONY: bump bump: $(GOBIN)/gobump diff --git a/vendor/github.com/itchyny/gojq/README.md b/vendor/github.com/itchyny/gojq/README.md index 7b34f93c..6f6aa161 100644 --- a/vendor/github.com/itchyny/gojq/README.md +++ b/vendor/github.com/itchyny/gojq/README.md @@ -56,6 +56,11 @@ gojq: invalid json: brew install gojq ``` +### mise +```sh +mise use -g gojq@latest +``` + ### Zero Install ```sh 0install add gojq https://apps.0install.net/utils/gojq.xml @@ -74,12 +79,11 @@ docker run -i --rm ghcr.io/itchyny/gojq ## Difference to jq - gojq is purely implemented with Go language and is completely portable. jq depends on the C standard library so the availability of math functions depends on the library. jq also depends on the regular expression library and it makes build scripts complex. -- gojq implements nice error messages for invalid query and JSON input. The error message of jq is sometimes difficult to tell where to fix the query. - gojq does not keep the order of object keys. I understand this might cause problems for some scripts but basically, we should not rely on the order of object keys. Due to this limitation, gojq does not have `keys_unsorted` function and `--sort-keys` (`-S`) option. I would implement when ordered map is implemented in the standard library of Go but I'm less motivated. - gojq supports arbitrary-precision integer calculation while jq does not; jq loses the precision of large integers when calculation is involved. Note that even with gojq, all mathematical functions, including `floor` and `round`, convert integers to floating-point numbers; only addition, subtraction, multiplication, modulo, and division operators (when divisible) keep the integer precision. To calculate floor division of integers without losing the precision, use `def idivide($n): (. - . % $n) / $n;`. To round down floating-point numbers to integers, use `def ifloor: floor | tostring | tonumber;`, but note that this function does not work with large floating-point numbers and also loses the precision of large integers. -- gojq behaves differently than jq in some features, hoping that jq will fix the behaviors in the future. gojq consistently counts by characters (not by bytes) in `index`, `rindex`, and `indices` functions; `"12345" | .[index("3"):]` results in `"345"` ([jq#1430](https://github.com/jqlang/jq/issues/1430), [jq#1624](https://github.com/jqlang/jq/issues/1624)). gojq supports string indexing; `"abcde"[2]` ([jq#1520](https://github.com/jqlang/jq/issues/1520)). gojq fixes handling files with no newline characters at the end ([jq#2374](https://github.com/jqlang/jq/issues/2374)). gojq consistently truncates down floating-point number indices both in indexing (`[0] | .[0.5]` results in `0`), and slicing (`[0,1,2] | .[0.5:1.5]` results in `[0]`). gojq parses unary operators with higher precedence than variable binding (`[-1 as $x | 1,$x]` results in `[1,-1]` not `[-1,-1]`) ([jq#3053](https://github.com/jqlang/jq/pull/3053)). gojq fixes `@base64d` to allow binary string as the decoded string ([jq#1931](https://github.com/jqlang/jq/issues/1931)). gojq improves time formatting and parsing; deals with `%f` in `strftime` and `strptime` ([jq#1409](https://github.com/jqlang/jq/issues/1409)), parses timezone offsets with `fromdate` and `fromdateiso8601` ([jq#1053](https://github.com/jqlang/jq/issues/1053)), supports timezone name/offset with `%Z`/`%z` in `strptime` ([jq#929](https://github.com/jqlang/jq/issues/929), [jq#2195](https://github.com/jqlang/jq/issues/2195)), and looks up correct timezone during daylight saving time on formatting with `%Z` ([jq#1912](https://github.com/jqlang/jq/issues/1912)). gojq supports nanoseconds in date and time functions. -- gojq does not support some functions intentionally; `get_jq_origin`, `get_prog_origin`, `get_search_list` (unstable, not listed in jq document), `input_line_number`, `$__loc__` (performance issue). gojq does not support some flags; `--ascii-output, -a` (performance issue), `--seq` (not used commonly), `--sort-keys, -S` (sorts by default because `map[string]any` does not keep the order), `--unbuffered` (unbuffered by default). gojq does not parse JSON extensions supported by jq; `NaN`, `Infinity`, and `[000]`. gojq normalizes floating-point numbers to fit to double-precision floating-point numbers. gojq does not support some regular expression metacharacters, backreferences, look-around assertions, and some flags (regular expression engine differences). gojq does not support BOM (`encoding/json` does not support this). gojq disallows using keywords for function names (`def true: .; true` is a confusing query), and module name prefixes in function declarations (using module prefixes like `def m::f: .;` is undocumented). -- gojq supports reading from YAML input (`--yaml-input`) while jq does not. gojq also supports YAML output (`--yaml-output`). gojq supports `@urid` format string ([jq#798](https://github.com/jqlang/jq/issues/798), [jq#2261](https://github.com/jqlang/jq/issues/2261)). +- gojq behaves differently than jq in some features, expecting jq to fix its behavior in the future. gojq supports string indexing; `"abcde"[2]` ([jq#1520](https://github.com/jqlang/jq/issues/1520)). gojq fixes handling files with no newline characters at the end ([jq#2374](https://github.com/jqlang/jq/issues/2374)). gojq fixes `@base64d` to allow binary string as the decoded string ([jq#1931](https://github.com/jqlang/jq/issues/1931)). gojq improves time formatting and parsing; deals with `%f` in `strftime` and `strptime` ([jq#1409](https://github.com/jqlang/jq/issues/1409)), parses timezone offsets with `fromdate` and `fromdateiso8601` ([jq#1053](https://github.com/jqlang/jq/issues/1053)), supports timezone name/offset with `%Z`/`%z` in `strptime` ([jq#929](https://github.com/jqlang/jq/issues/929), [jq#2195](https://github.com/jqlang/jq/issues/2195)). gojq supports nanoseconds in date and time functions. +- gojq does not support some functions intentionally; `get_jq_origin`, `get_prog_origin`, `get_search_list` (unstable, not listed in jq document), `input_line_number`, `$__loc__` (performance issue). gojq does not support some flags; `--ascii-output, -a` (performance issue), `--seq` (not used commonly), `--sort-keys, -S` (sorts by default because `map[string]any` does not keep the order), `--unbuffered` (unbuffered by default). gojq does not parse JSON extensions supported by jq; `NaN`, `Infinity`, and `[000]`. gojq does not support some regular expression metacharacters, backreferences, look-around assertions, and some flags (regular expression engine differences). gojq does not support BOM (`encoding/json` does not support this). gojq disallows using keywords for function names (`def true: .; true` is a confusing query), and module name prefixes in function declarations (using module prefixes like `def m::f: .;` is undocumented). +- gojq supports reading from YAML input (`--yaml-input`) while jq does not. gojq also supports YAML output (`--yaml-output`). ### Color configuration The gojq command automatically disables coloring output when the output is not a tty. @@ -130,7 +134,7 @@ func main() { - Use [`gojq.ParseError`](https://pkg.go.dev/github.com/itchyny/gojq#ParseError) to get the error position and token of the parsing error. - Secondly, get the result iterator - using [`query.Run`](https://pkg.go.dev/github.com/itchyny/gojq#Query.Run) or [`query.RunWithContext`](https://pkg.go.dev/github.com/itchyny/gojq#Query.RunWithContext) - - or alternatively, compile the query using [`gojq.Compile`](https://pkg.go.dev/github.com/itchyny/gojq#Compile) and then [`code.Run`](https://pkg.go.dev/github.com/itchyny/gojq#Code.Run) or [`code.RunWithContext`](https://pkg.go.dev/github.com/itchyny/gojq#Code.RunWithContext). You can reuse the `*Code` against multiple inputs to avoid compilation of the same query. But for arguments of `code.Run`, do not give values sharing same data between multiple calls. + - or alternatively, compile the query using [`gojq.Compile`](https://pkg.go.dev/github.com/itchyny/gojq#Compile) and then [`code.Run`](https://pkg.go.dev/github.com/itchyny/gojq#Code.Run) or [`code.RunWithContext`](https://pkg.go.dev/github.com/itchyny/gojq#Code.RunWithContext). You can reuse the `*Code` against multiple inputs to avoid compilation of the same query. - In either case, you cannot use custom type values as the query input. The type should be `[]any` for an array and `map[string]any` for a map (just like decoded to an `any` using the [encoding/json](https://golang.org/pkg/encoding/json/) package). You can't use `[]int` or `map[string]string`, for example. If you want to query your custom struct, marshal to JSON, unmarshal to `any` and use it as the query input. - Thirdly, iterate through the results using [`iter.Next() (any, bool)`](https://pkg.go.dev/github.com/itchyny/gojq#Iter). The iterator can emit an error so make sure to handle it. The method returns `true` with results, and `false` when the iterator terminates. - The return type is not `(any, error)` because the iterator may emit multiple errors. The `jq` and `gojq` commands stop the iteration on the first error, but the library user can choose to stop the iteration on errors, or to continue until it terminates. diff --git a/vendor/github.com/itchyny/gojq/builtin.go b/vendor/github.com/itchyny/gojq/builtin.go index 8ae4666c..c518fe8f 100644 --- a/vendor/github.com/itchyny/gojq/builtin.go +++ b/vendor/github.com/itchyny/gojq/builtin.go @@ -4,67 +4,70 @@ package gojq func init() { builtinFuncDefs = map[string][]*FuncDef{ - "IN": {{Name: "IN", Args: []string{"s"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "any", Args: []*Query{{Left: &Query{Func: "s"}, Op: OpEq, Right: &Query{Func: "."}}, {Func: "."}}}}}}, {Name: "IN", Args: []string{"src", "s"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "any", Args: []*Query{{Left: &Query{Func: "src"}, Op: OpEq, Right: &Query{Func: "s"}}, {Func: "."}}}}}}}, - "INDEX": {{Name: "INDEX", Args: []string{"stream", "idx_expr"}, Body: &Query{Term: &Term{Type: TermTypeReduce, Reduce: &Reduce{Query: &Query{Func: "stream"}, Pattern: &Pattern{Name: "$row"}, Start: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{}}}, Update: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Left: &Query{Func: "$row"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "idx_expr"}, Op: OpPipe, Right: &Query{Func: "tostring"}}}}}}, Op: OpAssign, Right: &Query{Func: "$row"}}}}}}, {Name: "INDEX", Args: []string{"idx_expr"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "INDEX", Args: []*Query{{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}}}}, {Func: "idx_expr"}}}}}}}, - "JOIN": {{Name: "JOIN", Args: []string{"$idx", "idx_expr"}, Body: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$idx"}, SuffixList: []*Suffix{{Index: &Index{Start: &Query{Func: "idx_expr"}}}}}}}}}}}}}}}, {Name: "JOIN", Args: []string{"$idx", "stream", "idx_expr"}, Body: &Query{Left: &Query{Func: "stream"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$idx"}, SuffixList: []*Suffix{{Index: &Index{Start: &Query{Func: "idx_expr"}}}}}}}}}}}}, {Name: "JOIN", Args: []string{"$idx", "stream", "idx_expr", "join_expr"}, Body: &Query{Left: &Query{Func: "stream"}, Op: OpPipe, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$idx"}, SuffixList: []*Suffix{{Index: &Index{Start: &Query{Func: "idx_expr"}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "join_expr"}}}}}, + "IN": {{Name: "IN", Args: []string{"s"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "any", Args: []*Query{{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "s"}}}, Right: &Query{Term: &Term{Type: TermTypeIdentity}}, Op: OpEq}, {Term: &Term{Type: TermTypeIdentity}}}}}}}, {Name: "IN", Args: []string{"src", "s"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "any", Args: []*Query{{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "src"}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "s"}}}, Op: OpEq}, {Term: &Term{Type: TermTypeIdentity}}}}}}}}, + "INDEX": {{Name: "INDEX", Args: []string{"stream", "idx_expr"}, Body: &Query{Term: &Term{Type: TermTypeReduce, Reduce: &Reduce{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "stream"}}}, Pattern: &Pattern{Name: "$row"}, Start: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{}}}, Update: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$row"}}}, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "idx_expr"}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "tostring"}}}, Op: OpPipe}, Op: OpPipe}}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$row"}}}, Op: OpAssign}}}}}, {Name: "INDEX", Args: []string{"idx_expr"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "INDEX", Args: []*Query{{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}}}}, {Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "idx_expr"}}}}}}}}}, + "JOIN": {{Name: "JOIN", Args: []string{"$idx", "idx_expr"}, Body: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}}}}, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$idx"}, SuffixList: []*Suffix{{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "idx_expr"}}}}}}}}, Op: OpComma}}}}, Op: OpPipe}}}}}, {Name: "JOIN", Args: []string{"$idx", "stream", "idx_expr"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "stream"}}}, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$idx"}, SuffixList: []*Suffix{{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "idx_expr"}}}}}}}}, Op: OpComma}}}}, Op: OpPipe}}, {Name: "JOIN", Args: []string{"$idx", "stream", "idx_expr", "join_expr"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "stream"}}}, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$idx"}, SuffixList: []*Suffix{{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "idx_expr"}}}}}}}}, Op: OpComma}}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "join_expr"}}}, Op: OpPipe}, Op: OpPipe}}}, "_assign": {}, + "_last": {}, "_modify": {}, - "add": {{Name: "add", Args: []string{"f"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "f"}}}}, Op: OpPipe, Right: &Query{Func: "add"}}}}, - "all": {{Name: "all", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "all", Args: []*Query{{Func: "."}}}}}}, {Name: "all", Args: []string{"y"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "all", Args: []*Query{{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}}}}, {Func: "y"}}}}}}, {Name: "all", Args: []string{"g", "y"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "isempty", Args: []*Query{{Left: &Query{Func: "g"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "y"}, Op: OpPipe, Right: &Query{Func: "not"}}}}}}}}}}}}}, - "any": {{Name: "any", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "any", Args: []*Query{{Func: "."}}}}}}, {Name: "any", Args: []string{"y"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "any", Args: []*Query{{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}}}}, {Func: "y"}}}}}}, {Name: "any", Args: []string{"g", "y"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "isempty", Args: []*Query{{Left: &Query{Func: "g"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Func: "y"}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "not"}}}}, - "arrays": {{Name: "arrays", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "array"}}}}}}}}}}, - "booleans": {{Name: "booleans", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "boolean"}}}}}}}}}}, - "capture": {{Name: "capture", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "capture", Args: []*Query{{Func: "$re"}, {Func: "null"}}}}}}, {Name: "capture", Args: []string{"$re", "$flags"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "match", Args: []*Query{{Func: "$re"}, {Func: "$flags"}}}}}, Op: OpPipe, Right: &Query{Func: "_capture"}}}}, - "combinations": {{Name: "combinations", Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "length"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{}}}, Else: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, SuffixList: []*Suffix{{Iter: true}, {Bind: &Bind{Patterns: []*Pattern{{Name: "$x"}}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "$x"}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}, IsSlice: true}}}, Op: OpPipe, Right: &Query{Func: "combinations"}}}}}}}}}}}}}}, {Name: "combinations", Args: []string{"n"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "limit", Args: []*Query{{Func: "n"}, {Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "repeat", Args: []*Query{{Func: "."}}}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "combinations"}}}}, - "del": {{Name: "del", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "delpaths", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{{Func: "f"}}}}}}}}}}}}}}, - "finites": {{Name: "finites", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Func: "isfinite"}}}}}}}, - "first": {{Name: "first", Body: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}}, {Name: "first", Args: []string{"g"}, Body: &Query{Term: &Term{Type: TermTypeLabel, Label: &Label{Ident: "$out", Body: &Query{Left: &Query{Func: "g"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeBreak, Break: "$out"}}}}}}}}}, - "fromdate": {{Name: "fromdate", Body: &Query{Func: "fromdateiso8601"}}}, - "fromdateiso8601": {{Name: "fromdateiso8601", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "strptime", Args: []*Query{{Term: &Term{Type: TermTypeString, Str: &String{Str: "%Y-%m-%dT%H:%M:%S%z"}}}}}}}, Op: OpPipe, Right: &Query{Func: "mktime"}}}}, - "fromstream": {{Name: "fromstream", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeForeach, Foreach: &Foreach{Query: &Query{Func: "f"}, Pattern: &Pattern{Name: "$pv"}, Start: &Query{Func: "null"}, Update: &Query{Left: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "e"}}}, Then: &Query{Func: "null"}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$pv"}, SuffixList: []*Suffix{{Bind: &Bind{Patterns: []*Pattern{{Array: []*Pattern{{Name: "$p"}, {Name: "$v"}}}}, Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "$pv"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "length"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "2"}}}}, Then: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "v"}}}}}}, Op: OpAdd, Right: &Query{Func: "$p"}}, {Func: "$v"}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "e"}}}}}}, {Left: &Query{Func: "$p"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "length"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}}}}}, Else: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "e"}}}}}}, {Left: &Query{Func: "$p"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "length"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}}}}}}}}}}}, Extract: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "e"}}}, Then: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "v"}}}, Else: &Query{Func: "empty"}}}}}}}}}, - "group_by": {{Name: "group_by", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_group_by", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "f"}}}}}}}}}}}}}}, - "gsub": {{Name: "gsub", Args: []string{"$re", "str"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "sub", Args: []*Query{{Func: "$re"}, {Func: "str"}, {Term: &Term{Type: TermTypeString, Str: &String{Str: "g"}}}}}}}}, {Name: "gsub", Args: []string{"$re", "str", "$flags"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "sub", Args: []*Query{{Func: "$re"}, {Func: "str"}, {Left: &Query{Func: "$flags"}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "g"}}}}}}}}}}, - "in": {{Name: "in", Args: []string{"xs"}, Body: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Bind: &Bind{Patterns: []*Pattern{{Name: "$x"}}, Body: &Query{Left: &Query{Func: "xs"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "has", Args: []*Query{{Func: "$x"}}}}}}}}}}}}}, - "inputs": {{Name: "inputs", Body: &Query{Term: &Term{Type: TermTypeTry, Try: &Try{Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "repeat", Args: []*Query{{Func: "input"}}}}}, Catch: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "."}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "break"}}}}, Then: &Query{Func: "empty"}, Else: &Query{Func: "error"}}}}}}}}}, - "inside": {{Name: "inside", Args: []string{"xs"}, Body: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Bind: &Bind{Patterns: []*Pattern{{Name: "$x"}}, Body: &Query{Left: &Query{Func: "xs"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "contains", Args: []*Query{{Func: "$x"}}}}}}}}}}}}}, - "isempty": {{Name: "isempty", Args: []string{"g"}, Body: &Query{Term: &Term{Type: TermTypeLabel, Label: &Label{Ident: "$out", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Func: "g"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "false"}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeBreak, Break: "$out"}}}}}}, Op: OpComma, Right: &Query{Func: "true"}}}}}}}, - "iterables": {{Name: "iterables", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "type"}, Op: OpPipe, Right: &Query{Left: &Query{Left: &Query{Func: "."}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "array"}}}}, Op: OpOr, Right: &Query{Left: &Query{Func: "."}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "object"}}}}}}}}}}}}, - "last": {{Name: "last", Body: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeUnary, Unary: &Unary{Op: OpSub, Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}}}, - "limit": {{Name: "limit", Args: []string{"$n", "g"}, Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "$n"}, Op: OpGt, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Term: &Term{Type: TermTypeLabel, Label: &Label{Ident: "$out", Body: &Query{Term: &Term{Type: TermTypeForeach, Foreach: &Foreach{Query: &Query{Func: "g"}, Pattern: &Pattern{Name: "$item"}, Start: &Query{Func: "$n"}, Update: &Query{Left: &Query{Func: "."}, Op: OpSub, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}, Extract: &Query{Left: &Query{Func: "$item"}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "."}, Op: OpLe, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Term: &Term{Type: TermTypeBreak, Break: "$out"}}, Else: &Query{Func: "empty"}}}}}}}}}}}, Elif: []*IfElif{{Cond: &Query{Left: &Query{Func: "$n"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Func: "empty"}}}, Else: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "error", Args: []*Query{{Term: &Term{Type: TermTypeString, Str: &String{Str: "limit doesn't support negative count"}}}}}}}}}}}}, - "map": {{Name: "map", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}}}}, Op: OpPipe, Right: &Query{Func: "f"}}}}}}}, - "map_values": {{Name: "map_values", Args: []string{"f"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}}}}, Op: OpModify, Right: &Query{Func: "f"}}}}, - "match": {{Name: "match", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "match", Args: []*Query{{Func: "$re"}, {Func: "null"}}}}}}, {Name: "match", Args: []string{"$re", "$flags"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_match", Args: []*Query{{Func: "$re"}, {Func: "$flags"}, {Func: "false"}}}, SuffixList: []*Suffix{{Iter: true}}}}}}, - "max_by": {{Name: "max_by", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_max_by", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "f"}}}}}}}}}}}}}}, - "min_by": {{Name: "min_by", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_min_by", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "f"}}}}}}}}}}}}}}, - "normals": {{Name: "normals", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Func: "isnormal"}}}}}}}, - "not": {{Name: "not", Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Func: "."}, Then: &Query{Func: "false"}, Else: &Query{Func: "true"}}}}}}, - "nth": {{Name: "nth", Args: []string{"$n"}, Body: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Func: "$n"}}}}}, {Name: "nth", Args: []string{"$n", "g"}, Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "$n"}, Op: OpGe, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "first", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "skip", Args: []*Query{{Func: "$n"}, {Func: "g"}}}}}}}}}, Else: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "error", Args: []*Query{{Term: &Term{Type: TermTypeString, Str: &String{Str: "nth doesn't support negative index"}}}}}}}}}}}}, - "nulls": {{Name: "nulls", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "."}, Op: OpEq, Right: &Query{Func: "null"}}}}}}}}, - "numbers": {{Name: "numbers", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "number"}}}}}}}}}}, - "objects": {{Name: "objects", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "object"}}}}}}}}}}, - "paths": {{Name: "paths", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{{Func: ".."}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "."}, Op: OpNe, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{}}}}}}}}}}, {Name: "paths", Args: []string{"f"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{{Left: &Query{Func: ".."}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Func: "f"}}}}}}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "."}, Op: OpNe, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{}}}}}}}}}}}, - "pick": {{Name: "pick", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Bind: &Bind{Patterns: []*Pattern{{Name: "$v"}}, Body: &Query{Term: &Term{Type: TermTypeReduce, Reduce: &Reduce{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{{Func: "f"}}}}}, Pattern: &Pattern{Name: "$p"}, Start: &Query{Func: "null"}, Update: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{{Func: "$p"}, {Left: &Query{Func: "$v"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "getpath", Args: []*Query{{Func: "$p"}}}}}}}}}}}}}}}}}}}}, - "range": {{Name: "range", Args: []string{"$end"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_range", Args: []*Query{{Term: &Term{Type: TermTypeNumber, Number: "0"}}, {Func: "$end"}, {Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}, {Name: "range", Args: []string{"$start", "$end"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_range", Args: []*Query{{Func: "$start"}, {Func: "$end"}, {Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}, {Name: "range", Args: []string{"$start", "$end", "$step"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_range", Args: []*Query{{Func: "$start"}, {Func: "$end"}, {Func: "$step"}}}}}}}, - "recurse": {{Name: "recurse", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "recurse", Args: []*Query{{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}, {Optional: true}}}}}}}}}, {Name: "recurse", Args: []string{"f"}, Body: &Query{FuncDefs: []*FuncDef{{Name: "r", Body: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Func: "f"}, Op: OpPipe, Right: &Query{Func: "r"}}}}}}}, Func: "r"}}, {Name: "recurse", Args: []string{"f", "cond"}, Body: &Query{FuncDefs: []*FuncDef{{Name: "r", Body: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Func: "f"}, Op: OpPipe, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Func: "cond"}}}}}, Op: OpPipe, Right: &Query{Func: "r"}}}}}}}}, Func: "r"}}}, - "repeat": {{Name: "repeat", Args: []string{"f"}, Body: &Query{FuncDefs: []*FuncDef{{Name: "_repeat", Body: &Query{Left: &Query{Func: "f"}, Op: OpComma, Right: &Query{Func: "_repeat"}}}}, Func: "_repeat"}}}, - "scalars": {{Name: "scalars", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "type"}, Op: OpPipe, Right: &Query{Left: &Query{Left: &Query{Func: "."}, Op: OpNe, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "array"}}}}, Op: OpAnd, Right: &Query{Left: &Query{Func: "."}, Op: OpNe, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "object"}}}}}}}}}}}}, - "scan": {{Name: "scan", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "scan", Args: []*Query{{Func: "$re"}, {Func: "null"}}}}}}, {Name: "scan", Args: []string{"$re", "$flags"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "match", Args: []*Query{{Func: "$re"}, {Left: &Query{Func: "$flags"}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "g"}}}}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "captures"}}}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{}}}}, Then: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "string"}}}, Else: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "captures"}, SuffixList: []*Suffix{{Iter: true}, {Index: &Index{Name: "string"}}}}}}}}}}}}}}, - "select": {{Name: "select", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Func: "f"}, Then: &Query{Func: "."}, Else: &Query{Func: "empty"}}}}}}, - "skip": {{Name: "skip", Args: []string{"$n", "g"}, Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "$n"}, Op: OpGt, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Term: &Term{Type: TermTypeForeach, Foreach: &Foreach{Query: &Query{Func: "g"}, Pattern: &Pattern{Name: "$item"}, Start: &Query{Func: "$n"}, Update: &Query{Left: &Query{Func: "."}, Op: OpSub, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}, Extract: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "."}, Op: OpLt, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Func: "$item"}, Else: &Query{Func: "empty"}}}}}}}, Elif: []*IfElif{{Cond: &Query{Left: &Query{Func: "$n"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Func: "g"}}}, Else: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "error", Args: []*Query{{Term: &Term{Type: TermTypeString, Str: &String{Str: "skip doesn't support negative count"}}}}}}}}}}}}, - "sort_by": {{Name: "sort_by", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_sort_by", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "f"}}}}}}}}}}}}}}, - "splits": {{Name: "splits", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "splits", Args: []*Query{{Func: "$re"}, {Func: "null"}}}}}}, {Name: "splits", Args: []string{"$re", "$flags"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "split", Args: []*Query{{Func: "$re"}, {Func: "$flags"}}}, SuffixList: []*Suffix{{Iter: true}}}}}}, - "strings": {{Name: "strings", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "string"}}}}}}}}}}, - "sub": {{Name: "sub", Args: []string{"$re", "str"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "sub", Args: []*Query{{Func: "$re"}, {Func: "str"}, {Func: "null"}}}}}}, {Name: "sub", Args: []string{"$re", "str", "$flags"}, Body: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Bind: &Bind{Patterns: []*Pattern{{Name: "$str"}}, Body: &Query{FuncDefs: []*FuncDef{{Name: "_sub", Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "matches"}}}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{}}}}, Then: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$str"}, SuffixList: []*Suffix{{Index: &Index{End: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "offset"}}}, IsSlice: true}}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "string"}}}}, Else: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "matches"}, SuffixList: []*Suffix{{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeUnary, Unary: &Unary{Op: OpSub, Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}, {Bind: &Bind{Patterns: []*Pattern{{Name: "$r"}}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{KeyVals: []*ObjectKeyVal{{Key: "string", Val: &Query{Left: &Query{Left: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Func: "$r"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "_capture"}, Op: OpPipe, Right: &Query{Func: "str"}}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$str"}, SuffixList: []*Suffix{{Index: &Index{Start: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$r"}, SuffixList: []*Suffix{{Index: &Index{Name: "offset"}}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$r"}, SuffixList: []*Suffix{{Index: &Index{Name: "length"}}}}}}, End: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "offset"}}}, IsSlice: true}}}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "string"}}}}}, {Key: "offset", Val: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$r"}, SuffixList: []*Suffix{{Index: &Index{Name: "offset"}}}}}}, {Key: "matches", Val: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "matches"}, SuffixList: []*Suffix{{Index: &Index{End: &Query{Term: &Term{Type: TermTypeUnary, Unary: &Unary{Op: OpSub, Term: &Term{Type: TermTypeNumber, Number: "1"}}}}, IsSlice: true}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "_sub"}}}}}}}}}}}}, Left: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{KeyVals: []*ObjectKeyVal{{Key: "string", Val: &Query{Term: &Term{Type: TermTypeString, Str: &String{}}}}, {Key: "matches", Val: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "match", Args: []*Query{{Func: "$re"}, {Func: "$flags"}}}}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "_sub"}}}}}}}}}, - "test": {{Name: "test", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "test", Args: []*Query{{Func: "$re"}, {Func: "null"}}}}}}, {Name: "test", Args: []string{"$re", "$flags"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_match", Args: []*Query{{Func: "$re"}, {Func: "$flags"}, {Func: "true"}}}}}}}, - "todate": {{Name: "todate", Body: &Query{Func: "todateiso8601"}}}, + "add": {{Name: "add", Args: []string{"f"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "f"}}}}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "add"}}}, Op: OpPipe}}}, + "all": {{Name: "all", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "all", Args: []*Query{{Term: &Term{Type: TermTypeIdentity}}}}}}}, {Name: "all", Args: []string{"y"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "all", Args: []*Query{{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}}}}, {Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "y"}}}}}}}}, {Name: "all", Args: []string{"g", "y"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "isempty", Args: []*Query{{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "g"}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "y"}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "not"}}}, Op: OpPipe}}}}}, Op: OpPipe}}}}}}}, + "any": {{Name: "any", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "any", Args: []*Query{{Term: &Term{Type: TermTypeIdentity}}}}}}}, {Name: "any", Args: []string{"y"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "any", Args: []*Query{{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}}}}, {Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "y"}}}}}}}}, {Name: "any", Args: []string{"g", "y"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "isempty", Args: []*Query{{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "g"}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "y"}}}}}}}, Op: OpPipe}}}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "not"}}}, Op: OpPipe}}}, + "arrays": {{Name: "arrays", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "type"}}}, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "array"}}}, Op: OpEq}}}}}}}, + "booleans": {{Name: "booleans", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "type"}}}, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "boolean"}}}, Op: OpEq}}}}}}}, + "capture": {{Name: "capture", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "capture", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$re"}}}, {Term: &Term{Type: TermTypeNull}}}}}}}, {Name: "capture", Args: []string{"$re", "$flags"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "match", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$re"}}}, {Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$flags"}}}}}}}, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "captures"}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_captures"}}}, Op: OpPipe}, Op: OpPipe}}}, + "combinations": {{Name: "combinations", Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "length"}}}, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}, Op: OpEq}, Then: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{}}}, Else: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, SuffixList: []*Suffix{{Iter: true}}}}, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$x"}}}}}}, Right: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}, IsSlice: true}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "combinations"}}}, Op: OpPipe}}}, Op: OpAdd}, Patterns: []*Pattern{{Name: "$x"}}, Op: OpPipe}}}}}, {Name: "combinations", Args: []string{"n"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "limit", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "n"}}}, {Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "repeat", Args: []*Query{{Term: &Term{Type: TermTypeIdentity}}}}}}}}}}}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "combinations"}}}, Op: OpPipe}}}, + "del": {{Name: "del", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "delpaths", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "f"}}}}}}}}}}}}}}}}, + "finites": {{Name: "finites", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "isfinite"}}}}}}}}}, + "first": {{Name: "first", Body: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}}, {Name: "first", Args: []string{"g"}, Body: &Query{Term: &Term{Type: TermTypeLabel, Label: &Label{Ident: "$out", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "g"}}}, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity}}, Right: &Query{Term: &Term{Type: TermTypeBreak, Break: "$out"}}, Op: OpComma}, Op: OpPipe}}}}}}, + "from_entries": {{Name: "from_entries", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{{Term: &Term{Type: TermTypeObject, Object: &Object{KeyVals: []*ObjectKeyVal{{KeyQuery: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "key"}}}, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "Key"}}}, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "name"}}}, Right: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "Name"}}}, Op: OpAlt}, Op: OpAlt}, Op: OpAlt}, Val: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "has", Args: []*Query{{Term: &Term{Type: TermTypeString, Str: &String{Str: "value"}}}}}}}, Then: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "value"}}}, Else: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "Value"}}}}}}}}}}}}}}}, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "add"}}}, Right: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{}}}, Op: OpAlt}, Op: OpPipe}}}, + "fromdate": {{Name: "fromdate", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "fromdateiso8601"}}}}}, + "fromdateiso8601": {{Name: "fromdateiso8601", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "strptime", Args: []*Query{{Term: &Term{Type: TermTypeString, Str: &String{Str: "%Y-%m-%dT%H:%M:%S%z"}}}}}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "mktime"}}}, Op: OpPipe}}}, + "fromstream": {{Name: "fromstream", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeForeach, Foreach: &Foreach{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "f"}}}, Pattern: &Pattern{Name: "$pv"}, Start: &Query{Term: &Term{Type: TermTypeNull}}, Update: &Query{Left: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "e"}}}, Then: &Query{Term: &Term{Type: TermTypeNull}}}}}, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$pv"}}}, Right: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$pv"}}}, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "length"}}}, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "2"}}, Op: OpEq}, Op: OpPipe}, Then: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "v"}}}}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$p"}}}, Op: OpAdd}, {Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$v"}}}}}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "e"}}}}}}, {Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$p"}}}, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "length"}}}, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}, Op: OpEq}, Op: OpPipe}}}}}, Op: OpPipe}, Else: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "e"}}}}}}, {Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$p"}}}, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "length"}}}, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}, Op: OpEq}, Op: OpPipe}}}}}}}}, Patterns: []*Pattern{{Array: []*Pattern{{Name: "$p"}, {Name: "$v"}}}}, Op: OpPipe}, Op: OpPipe}, Extract: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "e"}}}, Then: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "v"}}}, Else: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "empty"}}}}}}}}}}}, + "group_by": {{Name: "group_by", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_group_by", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "f"}}}}}}}}}}}}}}}}, + "gsub": {{Name: "gsub", Args: []string{"$re", "str"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "sub", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$re"}}}, {Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "str"}}}, {Term: &Term{Type: TermTypeString, Str: &String{Str: "g"}}}}}}}}, {Name: "gsub", Args: []string{"$re", "str", "$flags"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "sub", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$re"}}}, {Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "str"}}}, {Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$flags"}}}, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "g"}}}, Op: OpAdd}}}}}}}, + "in": {{Name: "in", Args: []string{"xs"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity}}, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "xs"}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "has", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$x"}}}}}}}, Op: OpPipe}, Patterns: []*Pattern{{Name: "$x"}}, Op: OpPipe}}}, + "inputs": {{Name: "inputs", Body: &Query{Term: &Term{Type: TermTypeTry, Try: &Try{Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "repeat", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "input"}}}}}}}, Catch: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity}}, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "break"}}}, Op: OpEq}, Then: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "empty"}}}, Else: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "error"}}}}}}}}}}}, + "isempty": {{Name: "isempty", Args: []string{"g"}, Body: &Query{Term: &Term{Type: TermTypeLabel, Label: &Label{Ident: "$out", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "g"}}}, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFalse}}, Right: &Query{Term: &Term{Type: TermTypeBreak, Break: "$out"}}, Op: OpComma}, Op: OpPipe}}}, Right: &Query{Term: &Term{Type: TermTypeTrue}}, Op: OpComma}}}}}}, + "iterables": {{Name: "iterables", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "type"}}}, Right: &Query{Left: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity}}, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "array"}}}, Op: OpEq}, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity}}, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "object"}}}, Op: OpEq}, Op: OpOr}, Op: OpPipe}}}}}}}, + "last": {{Name: "last", Body: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeUnary, Unary: &Unary{Op: OpSub, Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}}, {Name: "last", Args: []string{"g"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_last", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "g"}}}}}}}}}, + "limit": {{Name: "limit", Args: []string{"$n", "g"}, Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$n"}}}, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}, Op: OpGt}, Then: &Query{Term: &Term{Type: TermTypeLabel, Label: &Label{Ident: "$out", Body: &Query{Term: &Term{Type: TermTypeForeach, Foreach: &Foreach{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "g"}}}, Pattern: &Pattern{Name: "$item"}, Start: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$n"}}}, Update: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity}}, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}, Op: OpSub}, Extract: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$item"}}}, Right: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity}}, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}, Op: OpLe}, Then: &Query{Term: &Term{Type: TermTypeBreak, Break: "$out"}}, Else: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "empty"}}}}}}, Op: OpComma}}}}}}}, Elif: []*IfElif{{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$n"}}}, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}, Op: OpEq}, Then: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "empty"}}}}}, Else: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "error", Args: []*Query{{Term: &Term{Type: TermTypeString, Str: &String{Str: "limit doesn't support negative count"}}}}}}}}}}}}, + "map": {{Name: "map", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "f"}}}, Op: OpPipe}}}}}}, + "map_values": {{Name: "map_values", Args: []string{"f"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "f"}}}, Op: OpModify}}}, + "match": {{Name: "match", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "match", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$re"}}}, {Term: &Term{Type: TermTypeNull}}}}}}}, {Name: "match", Args: []string{"$re", "$flags"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_match", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$re"}}}, {Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$flags"}}}, {Term: &Term{Type: TermTypeFalse}}}}, SuffixList: []*Suffix{{Iter: true}}}}}}, + "max_by": {{Name: "max_by", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_max_by", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "f"}}}}}}}}}}}}}}}}, + "min_by": {{Name: "min_by", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_min_by", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "f"}}}}}}}}}}}}}}}}, + "normals": {{Name: "normals", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "isnormal"}}}}}}}}}, + "not": {{Name: "not", Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Term: &Term{Type: TermTypeIdentity}}, Then: &Query{Term: &Term{Type: TermTypeFalse}}, Else: &Query{Term: &Term{Type: TermTypeTrue}}}}}}}, + "nth": {{Name: "nth", Args: []string{"$n"}, Body: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$n"}}}}}}}, {Name: "nth", Args: []string{"$n", "g"}, Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$n"}}}, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}, Op: OpGe}, Then: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "first", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "skip", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$n"}}}, {Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "g"}}}}}}}}}}}, Else: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "error", Args: []*Query{{Term: &Term{Type: TermTypeString, Str: &String{Str: "nth doesn't support negative index"}}}}}}}}}}}}, + "nulls": {{Name: "nulls", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Term: &Term{Type: TermTypeIdentity}}, Right: &Query{Term: &Term{Type: TermTypeNull}}, Op: OpEq}}}}}}}, + "numbers": {{Name: "numbers", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "type"}}}, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "number"}}}, Op: OpEq}}}}}}}, + "objects": {{Name: "objects", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "type"}}}, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "object"}}}, Op: OpEq}}}}}}}, + "paths": {{Name: "paths", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{{Term: &Term{Type: TermTypeRecurse}}}}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Term: &Term{Type: TermTypeIdentity}}, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{}}}, Op: OpNe}}}}}, Op: OpPipe}}, {Name: "paths", Args: []string{"f"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{{Left: &Query{Term: &Term{Type: TermTypeRecurse}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "f"}}}}}}}, Op: OpPipe}}}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Term: &Term{Type: TermTypeIdentity}}, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{}}}, Op: OpNe}}}}}, Op: OpPipe}}}, + "pick": {{Name: "pick", Args: []string{"f"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity}}, Right: &Query{Term: &Term{Type: TermTypeReduce, Reduce: &Reduce{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "f"}}}}}}}, Pattern: &Pattern{Name: "$p"}, Start: &Query{Term: &Term{Type: TermTypeNull}}, Update: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$p"}}}, {Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$v"}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "getpath", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$p"}}}}}}}, Op: OpPipe}}}}}}}}, Patterns: []*Pattern{{Name: "$v"}}, Op: OpPipe}}}, + "range": {{Name: "range", Args: []string{"$end"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_range", Args: []*Query{{Term: &Term{Type: TermTypeNumber, Number: "0"}}, {Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$end"}}}, {Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}, {Name: "range", Args: []string{"$start", "$end"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_range", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$start"}}}, {Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$end"}}}, {Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}, {Name: "range", Args: []string{"$start", "$end", "$step"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_range", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$start"}}}, {Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$end"}}}, {Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$step"}}}}}}}}}, + "recurse": {{Name: "recurse", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "recurse", Args: []*Query{{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}, {Optional: true}}}}}}}}}, {Name: "recurse", Args: []string{"f"}, Body: &Query{FuncDefs: []*FuncDef{{Name: "r", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity}}, Right: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "f"}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "r"}}}, Op: OpPipe}}}, Op: OpComma}}}, Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "r"}}}}, {Name: "recurse", Args: []string{"f", "cond"}, Body: &Query{FuncDefs: []*FuncDef{{Name: "r", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity}}, Right: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "f"}}}, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "cond"}}}}}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "r"}}}, Op: OpPipe}, Op: OpPipe}}}, Op: OpComma}}}, Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "r"}}}}}, + "repeat": {{Name: "repeat", Args: []string{"f"}, Body: &Query{FuncDefs: []*FuncDef{{Name: "_repeat", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "f"}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_repeat"}}}, Op: OpComma}}}, Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_repeat"}}}}}, + "scalars": {{Name: "scalars", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "type"}}}, Right: &Query{Left: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity}}, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "array"}}}, Op: OpNe}, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity}}, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "object"}}}, Op: OpNe}, Op: OpAnd}, Op: OpPipe}}}}}}}, + "scan": {{Name: "scan", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "scan", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$re"}}}, {Term: &Term{Type: TermTypeNull}}}}}}}, {Name: "scan", Args: []string{"$re", "$flags"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "match", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$re"}}}, {Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$flags"}}}, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "g"}}}, Op: OpAdd}}}}}, Right: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "captures"}}}, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{}}}, Op: OpEq}, Then: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "string"}}}, Else: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "captures"}, SuffixList: []*Suffix{{Iter: true}, {Index: &Index{Name: "string"}}}}}}}}}}}, Op: OpPipe}}}, + "select": {{Name: "select", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "f"}}}, Then: &Query{Term: &Term{Type: TermTypeIdentity}}, Else: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "empty"}}}}}}}}, + "skip": {{Name: "skip", Args: []string{"$n", "g"}, Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$n"}}}, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}, Op: OpGt}, Then: &Query{Term: &Term{Type: TermTypeForeach, Foreach: &Foreach{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "g"}}}, Pattern: &Pattern{Name: "$item"}, Start: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$n"}}}, Update: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity}}, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}, Op: OpSub}, Extract: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity}}, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}, Op: OpLt}, Then: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$item"}}}, Else: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "empty"}}}}}}}}}, Elif: []*IfElif{{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$n"}}}, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}, Op: OpEq}, Then: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "g"}}}}}, Else: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "error", Args: []*Query{{Term: &Term{Type: TermTypeString, Str: &String{Str: "skip doesn't support negative count"}}}}}}}}}}}}, + "sort_by": {{Name: "sort_by", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_sort_by", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "f"}}}}}}}}}}}}}}}}, + "split": {{Name: "split", Args: []string{"$re", "$flags"}, Body: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "splits", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$re"}}}, {Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$flags"}}}}}}}}}}}}, + "splits": {{Name: "splits", Args: []string{"$re", "$flags"}, Body: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeForeach, Foreach: &Foreach{Query: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "match", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$re"}}}, {Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$flags"}}}, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "g"}}}, Op: OpAdd}}}}}, Right: &Query{Term: &Term{Type: TermTypeNull}}, Op: OpComma}}}, Pattern: &Pattern{Object: []*PatternObject{{Key: "$offset"}, {Key: "$length"}}}, Start: &Query{Term: &Term{Type: TermTypeNull}}, Update: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{KeyVals: []*ObjectKeyVal{{Key: "start", Val: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "next"}}}}, {Key: "end", Val: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$offset"}}}}, {Key: "next", Val: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$offset"}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$length"}}}, Op: OpAdd}}}}}}}}}}}}}, {Name: "splits", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "splits", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$re"}}}, {Term: &Term{Type: TermTypeNull}}}}}}}}, + "strings": {{Name: "strings", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "type"}}}, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "string"}}}, Op: OpEq}}}}}}}, + "sub": {{Name: "sub", Args: []string{"$re", "str"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "sub", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$re"}}}, {Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "str"}}}, {Term: &Term{Type: TermTypeNull}}}}}}}, {Name: "sub", Args: []string{"$re", "str", "$flags"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeReduce, Reduce: &Reduce{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "match", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$re"}}}, {Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$flags"}}}}}}}, Pattern: &Pattern{Object: []*PatternObject{{Key: "$offset"}, {Key: "$length"}, {Key: "$captures"}}}, Start: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{KeyVals: []*ObjectKeyVal{{Key: "s", Val: &Query{Term: &Term{Type: TermTypeIdentity}}}, {Key: "r", Val: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{}}}}}}}}, Update: &Query{Left: &Query{Term: &Term{Type: TermTypeReduce, Reduce: &Reduce{Query: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$captures"}}}, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_captures"}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "str"}}}, Op: OpPipe}, Op: OpPipe}}}, Pattern: &Pattern{Name: "$s"}, Start: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "i"}}}, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}, Op: OpAssign}, Update: &Query{Left: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "r"}, SuffixList: []*Suffix{{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "i"}}}}}}}}, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "s"}, SuffixList: []*Suffix{{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "next"}}}, End: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$offset"}}}, IsSlice: true}}}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$s"}}}, Op: OpAdd}, Op: OpUpdateAdd}, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "i"}}}, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}, Op: OpUpdateAdd}, Op: OpPipe}}}}, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "next"}}}, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$offset"}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$length"}}}, Op: OpAdd}, Op: OpAssign}, Op: OpPipe}}}}, Right: &Query{Left: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "r"}, SuffixList: []*Suffix{{Iter: true}}}}, Right: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "s"}, SuffixList: []*Suffix{{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "next"}}}, IsSlice: true}}}}}, Op: OpAdd}, Right: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "s"}}}, Op: OpAlt}, Op: OpPipe}}}, + "test": {{Name: "test", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "test", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$re"}}}, {Term: &Term{Type: TermTypeNull}}}}}}}, {Name: "test", Args: []string{"$re", "$flags"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_match", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$re"}}}, {Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$flags"}}}, {Term: &Term{Type: TermTypeTrue}}}}}}}}, + "to_entries": {{Name: "to_entries", Body: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "keys"}, SuffixList: []*Suffix{{Iter: true}}}}, Right: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{KeyVals: []*ObjectKeyVal{{Key: "key", Val: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$k"}}}}, {Key: "value", Val: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$k"}}}}}}}}}}}, Patterns: []*Pattern{{Name: "$k"}}, Op: OpPipe}}}}}}, + "todate": {{Name: "todate", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "todateiso8601"}}}}}, "todateiso8601": {{Name: "todateiso8601", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "strftime", Args: []*Query{{Term: &Term{Type: TermTypeString, Str: &String{Str: "%Y-%m-%dT%H:%M:%SZ"}}}}}}}}}, - "tostream": {{Name: "tostream", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{{FuncDefs: []*FuncDef{{Name: "r", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}, {Optional: true}}}}, Op: OpPipe, Right: &Query{Func: "r"}}}}, Op: OpComma, Right: &Query{Func: "."}}}}, Func: "r"}}}, SuffixList: []*Suffix{{Bind: &Bind{Patterns: []*Pattern{{Name: "$p"}}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "getpath", Args: []*Query{{Func: "$p"}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeReduce, Reduce: &Reduce{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}, {Optional: true}}}}}}}}, Pattern: &Pattern{Name: "$q"}, Start: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Func: "$p"}, Op: OpComma, Right: &Query{Func: "."}}}}}, Update: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Func: "$p"}, Op: OpAdd, Right: &Query{Func: "$q"}}}}}}}}}}}}}}}}, - "truncate_stream": {{Name: "truncate_stream", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Bind: &Bind{Patterns: []*Pattern{{Name: "$n"}}, Body: &Query{Left: &Query{Func: "null"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "f"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}, Op: OpPipe, Right: &Query{Left: &Query{Func: "length"}, Op: OpGt, Right: &Query{Func: "$n"}}}, Then: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}, Op: OpModify, Right: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Func: "$n"}, IsSlice: true}}}}, Else: &Query{Func: "empty"}}}}}}}}}}}}}, - "unique_by": {{Name: "unique_by", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_unique_by", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "f"}}}}}}}}}}}}}}, - "until": {{Name: "until", Args: []string{"cond", "next"}, Body: &Query{FuncDefs: []*FuncDef{{Name: "_until", Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Func: "cond"}, Then: &Query{Func: "."}, Else: &Query{Left: &Query{Func: "next"}, Op: OpPipe, Right: &Query{Func: "_until"}}}}}}}, Func: "_until"}}}, - "values": {{Name: "values", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "."}, Op: OpNe, Right: &Query{Func: "null"}}}}}}}}, - "walk": {{Name: "walk", Args: []string{"f"}, Body: &Query{FuncDefs: []*FuncDef{{Name: "_walk", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "array"}}}}, Then: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{{Func: "_walk"}}}}}, Elif: []*IfElif{{Cond: &Query{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "object"}}}}, Then: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map_values", Args: []*Query{{Func: "_walk"}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "f"}}}}, Func: "_walk"}}}, - "while": {{Name: "while", Args: []string{"cond", "update"}, Body: &Query{FuncDefs: []*FuncDef{{Name: "_while", Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Func: "cond"}, Then: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Func: "update"}, Op: OpPipe, Right: &Query{Func: "_while"}}}}}, Else: &Query{Func: "empty"}}}}}}, Func: "_while"}}}, - "with_entries": {{Name: "with_entries", Args: []string{"f"}, Body: &Query{Left: &Query{Func: "to_entries"}, Op: OpPipe, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{{Func: "f"}}}}}, Op: OpPipe, Right: &Query{Func: "from_entries"}}}}}, + "tostream": {{Name: "tostream", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{{FuncDefs: []*FuncDef{{Name: "r", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}, {Optional: true}}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "r"}}}, Op: OpPipe}}}, Right: &Query{Term: &Term{Type: TermTypeIdentity}}, Op: OpComma}}}, Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "r"}}}}}}}, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "getpath", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$p"}}}}}}}, Right: &Query{Term: &Term{Type: TermTypeReduce, Reduce: &Reduce{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}, {Optional: true}}}}}}}}, Pattern: &Pattern{Name: "$q"}, Start: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$p"}}}, Right: &Query{Term: &Term{Type: TermTypeIdentity}}, Op: OpComma}}}}, Update: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$p"}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$q"}}}, Op: OpAdd}}}}}}}, Op: OpPipe}, Patterns: []*Pattern{{Name: "$p"}}, Op: OpPipe}}}, + "truncate_stream": {{Name: "truncate_stream", Args: []string{"f"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity}}, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeNull}}, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "f"}}}, Right: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "length"}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$n"}}}, Op: OpGt}, Op: OpPipe}, Then: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}, Right: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$n"}}}, IsSlice: true}}}, Op: OpModify}, Else: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "empty"}}}}}}, Op: OpPipe}, Op: OpPipe}, Patterns: []*Pattern{{Name: "$n"}}, Op: OpPipe}}}, + "unique_by": {{Name: "unique_by", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_unique_by", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "f"}}}}}}}}}}}}}}}}, + "until": {{Name: "until", Args: []string{"cond", "next"}, Body: &Query{FuncDefs: []*FuncDef{{Name: "_until", Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "cond"}}}, Then: &Query{Term: &Term{Type: TermTypeIdentity}}, Else: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "next"}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_until"}}}, Op: OpPipe}}}}}}, Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_until"}}}}}, + "values": {{Name: "values", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Term: &Term{Type: TermTypeIdentity}}, Right: &Query{Term: &Term{Type: TermTypeNull}}, Op: OpNe}}}}}}}, + "walk": {{Name: "walk", Args: []string{"f"}, Body: &Query{FuncDefs: []*FuncDef{{Name: "_walk", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "type"}}}, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "array"}}}, Op: OpEq}, Then: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_walk"}}}}}}}, Elif: []*IfElif{{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "type"}}}, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "object"}}}, Op: OpEq}, Then: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map_values", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_walk"}}}}}}}}}}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "f"}}}, Op: OpPipe}}}, Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_walk"}}}}}, + "while": {{Name: "while", Args: []string{"cond", "update"}, Body: &Query{FuncDefs: []*FuncDef{{Name: "_while", Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "cond"}}}, Then: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity}}, Right: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "update"}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_while"}}}, Op: OpPipe}}}, Op: OpComma}, Else: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "empty"}}}}}}}}, Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_while"}}}}}, + "with_entries": {{Name: "with_entries", Args: []string{"f"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "to_entries"}}}, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "f"}}}}}}}, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "from_entries"}}}, Op: OpPipe}, Op: OpPipe}}}, } } diff --git a/vendor/github.com/itchyny/gojq/builtin.jq b/vendor/github.com/itchyny/gojq/builtin.jq index 987e4192..5feb25cc 100644 --- a/vendor/github.com/itchyny/gojq/builtin.jq +++ b/vendor/github.com/itchyny/gojq/builtin.jq @@ -1,12 +1,19 @@ -def not: if . then false else true end; -def in(xs): . as $x | xs | has($x); def map(f): [.[] | f]; -def with_entries(f): to_entries | map(f) | from_entries; +def add(f): [f] | add; +def map_values(f): .[] |= f; +def in(xs): . as $x | xs | has($x); +def not: if . then false else true end; def select(f): if f then . else empty end; + def recurse: recurse(.[]?); def recurse(f): def r: ., (f | r); r; def recurse(f; cond): def r: ., (f | select(cond) | r); r; +def to_entries: [keys[] as $k | {key: $k, value: .[$k]}]; +def from_entries: map({ (.key // .Key // .name // .Name): + if has("value") then .value else .Value end }) | add // {}; +def with_entries(f): to_entries | map(f) | from_entries; + def while(cond; update): def _while: if cond then ., (update | _while) else empty end; _while; @@ -20,7 +27,6 @@ def range($end): _range(0; $end; 1); def range($start; $end): _range($start; $end; 1); def range($start; $end; $step): _range($start; $end; $step); -def add(f): [f] | add; def min_by(f): _min_by(map([f])); def max_by(f): _max_by(map([f])); def sort_by(f): _sort_by(map([f])); @@ -39,7 +45,6 @@ def nulls: select(. == null); def values: select(. != null); def scalars: select(type | . != "array" and . != "object"); -def inside(xs): . as $x | xs | contains($x); def combinations: if length == 0 then [] @@ -47,6 +52,7 @@ def combinations: .[0][] as $x | [$x] + (.[1:] | combinations) end; def combinations(n): [limit(n; repeat(.))] | combinations; + def walk(f): def _walk: if type == "array" then @@ -59,6 +65,7 @@ def walk(f): def first: .[0]; def first(g): label $out | g | ., break $out; def last: .[-1]; +def last(g): _last(g); def isempty(g): label $out | (g | false, break $out), true; def all: all(.); def all(y): all(.[]; y); @@ -66,6 +73,7 @@ def all(g; y): isempty(g | select(y | not)); def any: any(.); def any(y): any(.[]; y); def any(g; y): isempty(g | select(y)) | not; + def limit($n; g): if $n > 0 then label $out | @@ -120,7 +128,6 @@ def tostream: getpath($p) | reduce path(.[]?) as $q ([$p, .]; [$p + $q]); -def map_values(f): .[] |= f; def del(f): delpaths([path(f)]); def paths: path(..) | select(. != []); def paths(f): path(.. | select(f)) | select(. != []); @@ -137,7 +144,7 @@ def match($re; $flags): _match($re; $flags; false)[]; def test($re): test($re; null); def test($re; $flags): _match($re; $flags; true); def capture($re): capture($re; null); -def capture($re; $flags): match($re; $flags) | _capture; +def capture($re; $flags): match($re; $flags) | .captures | _captures; def scan($re): scan($re; null); def scan($re; $flags): match($re; $flags + "g") | @@ -146,24 +153,18 @@ def scan($re; $flags): else [.captures[].string] end; +def splits($re; $flags): + .[foreach (match($re; $flags + "g"), null) as {$offset, $length} + (null; {start: .next, end: $offset, next: $offset + $length})]; def splits($re): splits($re; null); -def splits($re; $flags): split($re; $flags)[]; +def split($re; $flags): [splits($re; $flags)]; def sub($re; str): sub($re; str; null); def sub($re; str; $flags): - . as $str | - def _sub: - if .matches == [] then - $str[:.offset] + .string - else - .matches[-1] as $r | - { - string: ($r | _capture | str) + $str[$r.offset+$r.length:.offset] + .string, - offset: $r.offset, - matches: .matches[:-1], - } | - _sub - end; - { string: "", matches: [match($re; $flags)] } | _sub; + reduce match($re; $flags) as {$offset, $length, $captures} + ({s: ., r: []}; + reduce ($captures | _captures | str) as $s + (.i = 0; .r[.i] += .s[.next:$offset] + $s | .i += 1) | + .next = $offset + $length) | .r[] + .s[.next:] // .s; def gsub($re; str): sub($re; str; "g"); def gsub($re; str; $flags): sub($re; str; $flags + "g"); diff --git a/vendor/github.com/itchyny/gojq/compare.go b/vendor/github.com/itchyny/gojq/compare.go index 9791e9dc..d6239927 100644 --- a/vendor/github.com/itchyny/gojq/compare.go +++ b/vendor/github.com/itchyny/gojq/compare.go @@ -1,6 +1,8 @@ package gojq import ( + "cmp" + "encoding/json" "math" "math/big" ) @@ -10,10 +12,10 @@ import ( // This comparison is used by built-in operators and functions. func Compare(l, r any) int { return binopTypeSwitch(l, r, - compareInt, - func(l, r float64) any { + cmp.Compare, + func(l, r float64) int { switch { - case l < r || math.IsNaN(l): + case lt(l, r): return -1 case l == r: return 0 @@ -21,28 +23,17 @@ func Compare(l, r any) int { return 1 } }, - func(l, r *big.Int) any { - return l.Cmp(r) - }, - func(l, r string) any { - switch { - case l < r: - return -1 - case l == r: - return 0 - default: - return 1 - } - }, - func(l, r []any) any { - for i, n := 0, min(len(l), len(r)); i < n; i++ { + (*big.Int).Cmp, + cmp.Compare, + func(l, r []any) int { + for i := range min(len(l), len(r)) { if cmp := Compare(l[i], r[i]); cmp != 0 { return cmp } } - return compareInt(len(l), len(r)) + return cmp.Compare(len(l), len(r)) }, - func(l, r map[string]any) any { + func(l, r map[string]any) int { lk, rk := funcKeys(l), funcKeys(r) if cmp := Compare(lk, rk); cmp != 0 { return cmp @@ -54,21 +45,14 @@ func Compare(l, r any) int { } return 0 }, - func(l, r any) any { - return compareInt(typeIndex(l), typeIndex(r)) + func(l, r any) int { + return cmp.Compare(typeIndex(l), typeIndex(r)) }, - ).(int) + ) } -func compareInt(l, r int) any { - switch { - case l < r: - return -1 - case l == r: - return 0 - default: - return 1 - } +func lt(l, r float64) bool { + return l < r || math.IsNaN(l) } func typeIndex(v any) int { @@ -80,7 +64,7 @@ func typeIndex(v any) int { return 1 } return 2 - case int, float64, *big.Int: + case int, float64, *big.Int, json.Number: return 3 case string: return 4 diff --git a/vendor/github.com/itchyny/gojq/compiler.go b/vendor/github.com/itchyny/gojq/compiler.go index cea452e3..a86ea7aa 100644 --- a/vendor/github.com/itchyny/gojq/compiler.go +++ b/vendor/github.com/itchyny/gojq/compiler.go @@ -7,6 +7,7 @@ import ( "sort" "strconv" "strings" + "sync" ) type compiler struct { @@ -20,6 +21,7 @@ type compiler struct { builtinScope *scopeinfo scopes []*scopeinfo scopecnt int + regexpCache sync.Map } // Code is a compiled jq query. @@ -34,7 +36,6 @@ type Code struct { // a result iterator. // // It is safe to call this method in goroutines, to reuse a compiled [*Code]. -// But for arguments, do not give values sharing same data between goroutines. func (c *Code) Run(v any, values ...any) Iter { return c.RunWithContext(context.Background(), v, values...) } @@ -46,10 +47,7 @@ func (c *Code) RunWithContext(ctx context.Context, v any, values ...any) Iter { } else if len(values) < len(c.variables) { return NewIter(&expectedVariableError{c.variables[len(values)]}) } - for i, v := range values { - values[i] = normalizeNumbers(v) - } - return newEnv(ctx).execute(c, normalizeNumbers(v), values...) + return newEnv(ctx).execute(c, v, values...) } type scopeinfo struct { @@ -160,7 +158,6 @@ func (c *compiler) compileImport(i *Import) error { } else { return fmt.Errorf("module not found: %q", path) } - vals = normalizeNumbers(vals) c.append(&code{op: oppush, v: vals}) c.append(&code{op: opstore, v: c.pushVariable(alias)}) c.append(&code{op: oppush, v: vals}) @@ -379,28 +376,16 @@ func (c *compiler) compileQuery(e *Query) error { return err } } - if e.Func != "" { - switch e.Func { - case ".": - return c.compileTerm(&Term{Type: TermTypeIdentity}) - case "..": - return c.compileTerm(&Term{Type: TermTypeRecurse}) - case "null": - return c.compileTerm(&Term{Type: TermTypeNull}) - case "true": - return c.compileTerm(&Term{Type: TermTypeTrue}) - case "false": - return c.compileTerm(&Term{Type: TermTypeFalse}) - default: - return c.compileFunc(&Func{Name: e.Func}) - } - } else if e.Term != nil { + if e.Term != nil { return c.compileTerm(e.Term) } switch e.Op { case Operator(0): return errors.New(`missing query (try ".")`) case OpPipe: + if len(e.Patterns) > 0 { + return c.compileBind(e.Left, e.Right, e.Patterns) + } if err := c.compileQuery(e.Left); err != nil { return err } @@ -529,7 +514,7 @@ func (c *compiler) compileQueryUpdate(l, r *Query, op Operator) error { Name: op.getFunc(), Args: []*Query{ {Term: &Term{Type: TermTypeIdentity}}, - {Func: name}, + {Term: &Term{Type: TermTypeFunc, Func: &Func{Name: name}}}, }, }, }}, @@ -539,19 +524,19 @@ func (c *compiler) compileQueryUpdate(l, r *Query, op Operator) error { } } -func (c *compiler) compileBind(e *Term, b *Bind) error { +func (c *compiler) compileBind(l, r *Query, patterns []*Pattern) error { defer c.newScopeDepth()() c.append(&code{op: opdup}) c.append(&code{op: opexpbegin}) - if err := c.compileTerm(e); err != nil { + if err := c.compileQuery(l); err != nil { return err } var pc int var vs [][2]int - for i, p := range b.Patterns { + for i, p := range patterns { var pcc int var err error - if i < len(b.Patterns)-1 { + if i < len(patterns)-1 { defer c.lazy(func() *code { return &code{op: opforkalt, v: pcc} })() @@ -565,22 +550,22 @@ func (c *compiler) compileBind(e *Term, b *Bind) error { if vs, err = c.compilePattern(vs[:0], p); err != nil { return err } - if i < len(b.Patterns)-1 { + if i < len(patterns)-1 { defer c.lazy(func() *code { return &code{op: opjump, v: pc} })() pcc = len(c.codes) } } - if len(b.Patterns) > 1 { + if len(patterns) > 1 { pc = len(c.codes) } - if len(b.Patterns) == 1 && c.codes[len(c.codes)-2].op == opexpbegin { + if len(patterns) == 1 && c.codes[len(c.codes)-2].op == opexpbegin { c.codes[len(c.codes)-2].op = opnop } else { c.append(&code{op: opexpend}) } - return c.compileQuery(b.Body) + return c.compileQuery(r) } func (c *compiler) compilePattern(vs [][2]int, p *Pattern) ([][2]int, error) { @@ -953,7 +938,7 @@ func (c *compiler) compileFunc(e *Func) error { c.compileAssign() case "_modify": c.compileModify() - case "last": + case "_last": c.compileLast() } } @@ -1013,6 +998,13 @@ func (c *compiler) compileFunc(e *Func) error { c.append(&code{op: opbacktrack}) setfork() return nil + case "_match": + return c.compileCallInternal( + [3]any{c.funcMatch, len(e.Args), e.Name}, + e.Args, + true, + -1, + ) default: return c.compileCall(e.Name, e.Args) } @@ -1145,7 +1137,7 @@ func (c *compiler) compileModify() { // Appends the compiled code for the `last/1` function to // maximize performance avoiding unnecessary boxing. func (c *compiler) compileLast() { - defer c.appendBuiltin("last", 1)() + defer c.appendBuiltin("_last", 1)() scope := c.newScope() v, g, x := [2]int{scope.id, 0}, [2]int{scope.id, 1}, [2]int{scope.id, 2} c.appends( @@ -1218,7 +1210,7 @@ func (c *compiler) funcInput(any, []any) any { if !ok { return errors.New("break") } - return normalizeNumbers(v) + return v } func (c *compiler) funcModulemeta(v any, _ []any) any { @@ -1296,6 +1288,10 @@ func listModuleDeps(q *Query) []any { return deps } +func (c *compiler) funcMatch(v any, args []any) any { + return funcMatch(v, args[0], args[1], args[2], &c.regexpCache) +} + func (c *compiler) compileObject(e *Object) error { c.appendCodeInfo(e) if len(e.KeyVals) == 0 { @@ -1317,7 +1313,7 @@ func (c *compiler) compileObject(e *Object) error { if pc+l*3+1 != len(c.codes) { return nil } - for i := 0; i < l; i++ { + for i := range l { if c.codes[pc+i*3].op != oppush || c.codes[pc+i*3+1].op != opload || c.codes[pc+i*3+2].op != opconst { @@ -1325,7 +1321,7 @@ func (c *compiler) compileObject(e *Object) error { } } w := make(map[string]any, l) - for i := 0; i < l; i++ { + for i := range l { w[c.codes[pc+i*3].v.(string)] = c.codes[pc+i*3+2].v } c.codes[pc-1] = &code{op: opconst, v: w} @@ -1417,7 +1413,7 @@ func (c *compiler) compileArray(e *Array) error { return nil } l := (len(c.codes) - pc - 3) / 3 - for i := 0; i < l; i++ { + for i := range l { if c.codes[pc+i].op != opfork || c.codes[pc+i*2+l].op != opconst || (i < l-1 && c.codes[pc+i*2+l+1].op != opjump) { @@ -1425,7 +1421,7 @@ func (c *compiler) compileArray(e *Array) error { } } v := make([]any, l) - for i := 0; i < l; i++ { + for i := range l { v[i] = c.codes[pc+i*2+l].v } c.codes[pc-2] = &code{op: opconst, v: v} @@ -1536,8 +1532,6 @@ func (c *compiler) compileTermSuffix(e *Term, s *Suffix) error { } } return c.compileTry(&Try{Body: &Query{Term: e}}) - } else if s.Bind != nil { - return c.compileBind(e, s.Bind) } else { return fmt.Errorf("invalid suffix: %s", s) } @@ -1656,33 +1650,33 @@ func (c *compiler) optimizeTailRec() { var pcs []int scopes := map[int]bool{} L: - for i, l := 0, len(c.codes); i < l; i++ { - switch c.codes[i].op { + for i, code := range c.codes { + switch code.op { case opscope: pcs = append(pcs, i) - if v := c.codes[i].v.([3]int); v[2] == 0 { + if v := code.v.([3]int); v[2] == 0 { scopes[i] = v[1] == 0 } case opcall: var canjump bool - if j, ok := c.codes[i].v.(int); !ok || + if j, ok := code.v.(int); !ok || len(pcs) == 0 || pcs[len(pcs)-1] != j { break } else if canjump, ok = scopes[j]; !ok { break } - for j := i + 1; j < l; { + for j := i + 1; j < len(c.codes); { switch c.codes[j].op { case opjump: j = c.codes[j].v.(int) case opret: if canjump { - c.codes[i].op = opjump - c.codes[i].v = pcs[len(pcs)-1] + 1 + code.op = opjump + code.v = pcs[len(pcs)-1] + 1 } else { - c.codes[i].op = opcallrec + code.op = opcallrec } - continue L + fallthrough default: continue L } diff --git a/vendor/github.com/itchyny/gojq/encoder.go b/vendor/github.com/itchyny/gojq/encoder.go index 518904d7..cc44c95b 100644 --- a/vendor/github.com/itchyny/gojq/encoder.go +++ b/vendor/github.com/itchyny/gojq/encoder.go @@ -2,6 +2,7 @@ package gojq import ( "bytes" + "encoding/json" "fmt" "io" "math" @@ -15,12 +16,12 @@ import ( // Marshal returns the jq-flavored JSON encoding of v. // // This method accepts only limited types (nil, bool, int, float64, *big.Int, -// string, []any, and map[string]any) because these are the possible types a -// gojq iterator can emit. This method marshals NaN to null, truncates -// infinities to (+|-) math.MaxFloat64, uses \b and \f in strings, and does not -// escape '<', '>', '&', '\u2028', and '\u2029'. These behaviors are based on -// the marshaler of jq command, and different from json.Marshal in the Go -// standard library. Note that the result is not safe to embed in HTML. +// json.Number, string, []any, and map[string]any) because these are the +// possible types a gojq iterator can emit. This method marshals NaN to null, +// truncates infinities to (+|-) math.MaxFloat64, uses \b and \f in strings, +// and does not escape '<', '>', '&', '\u2028', and '\u2029'. These behaviors +// are based on the marshaler of jq command, and different from json.Marshal in +// the Go standard library. Note that the result is not safe to embed in HTML. func Marshal(v any) ([]byte, error) { var b bytes.Buffer (&encoder{w: &b}).encode(v) @@ -62,6 +63,8 @@ func (e *encoder) encode(v any) { e.encodeFloat64(v) case *big.Int: e.w.Write(v.Append(e.buf[:0], 10)) + case json.Number: + e.w.WriteString(v.String()) case string: e.encodeString(v) case []any: diff --git a/vendor/github.com/itchyny/gojq/env.go b/vendor/github.com/itchyny/gojq/env.go index bf058eda..3ba44ad1 100644 --- a/vendor/github.com/itchyny/gojq/env.go +++ b/vendor/github.com/itchyny/gojq/env.go @@ -44,5 +44,6 @@ type fork struct { scopelimit int pathindex int pathlimit int + offset int expdepth int } diff --git a/vendor/github.com/itchyny/gojq/error.go b/vendor/github.com/itchyny/gojq/error.go index 18b06b1c..213086ff 100644 --- a/vendor/github.com/itchyny/gojq/error.go +++ b/vendor/github.com/itchyny/gojq/error.go @@ -51,6 +51,15 @@ func (err *arrayIndexTooLargeError) Error() string { return "array index too large: " + Preview(err.v) } +type repeatStringTooLargeError struct { + s string + n float64 +} + +func (err *repeatStringTooLargeError) Error() string { + return "repeat string result too large: " + Preview(err.s) + " * " + Preview(err.n) +} + type objectKeyNotStringError struct { v any } @@ -212,14 +221,6 @@ func (err *flattenDepthError) Error() string { return "flatten depth should not be negative: " + Preview(err.v) } -type joinTypeError struct { - v any -} - -func (err *joinTypeError) Error() string { - return "join cannot be applied to an array including: " + typeErrorPreview(err.v) -} - type timeArrayError struct{} func (*timeArrayError) Error() string { diff --git a/vendor/github.com/itchyny/gojq/execute.go b/vendor/github.com/itchyny/gojq/execute.go index 344d8a3c..3b7eab2b 100644 --- a/vendor/github.com/itchyny/gojq/execute.go +++ b/vendor/github.com/itchyny/gojq/execute.go @@ -59,7 +59,7 @@ loop: } n := code.v.(int) m := make(map[string]any, n) - for i := 0; i < n; i++ { + for range n { v, k := env.pop(), env.pop() s, ok := k.(string) if !ok { @@ -180,7 +180,7 @@ loop: case [3]any: argcnt := v[1].(int) x, args := env.pop(), env.args[:argcnt] - for i := 0; i < argcnt; i++ { + for i := range argcnt { args[i] = env.pop() } w := v[0].(func(any, []any) any)(x, args) @@ -238,8 +238,7 @@ loop: callpc, saveindex = env.popscope() } } else { - saveindex, _ = env.scopes.save() - env.scopes.index = index + saveindex = env.scopes.index } if outerindex = index; outerindex >= 0 { if s := env.scopes.data[outerindex].value; s.id == xs[0] { @@ -377,7 +376,7 @@ func (env *env) popscope() (int, int) { } func (env *env) pushfork(pc int) { - f := fork{pc: pc, expdepth: env.expdepth} + f := fork{pc: pc, offset: env.offset, expdepth: env.expdepth} f.stackindex, f.stacklimit = env.stack.save() f.scopeindex, f.scopelimit = env.scopes.save() f.pathindex, f.pathlimit = env.paths.save() @@ -388,7 +387,8 @@ func (env *env) pushfork(pc int) { func (env *env) popfork() int { f := env.forks[len(env.forks)-1] env.debugForks(f.pc, "<<<") - env.forks, env.expdepth = env.forks[:len(env.forks)-1], f.expdepth + env.forks, env.offset, env.expdepth = + env.forks[:len(env.forks)-1], f.offset, f.expdepth env.stack.restore(f.stackindex, f.stacklimit) env.scopes.restore(f.scopeindex, f.scopelimit) env.paths.restore(f.pathindex, f.pathlimit) diff --git a/vendor/github.com/itchyny/gojq/func.go b/vendor/github.com/itchyny/gojq/func.go index dcfaa5d5..7014fbc9 100644 --- a/vendor/github.com/itchyny/gojq/func.go +++ b/vendor/github.com/itchyny/gojq/func.go @@ -6,14 +6,18 @@ import ( "errors" "fmt" "io" + "iter" + "maps" "math" "math/big" "net/url" "reflect" "regexp" + "slices" "sort" "strconv" "strings" + "sync" "time" "unicode" "unicode/utf8" @@ -57,14 +61,14 @@ func init() { "utf8bytelength": argFunc0(funcUtf8ByteLength), "keys": argFunc0(funcKeys), "has": argFunc1(funcHas), - "to_entries": argFunc0(funcToEntries), - "from_entries": argFunc0(funcFromEntries), "add": argFunc0(funcAdd), + "toboolean": argFunc0(funcToBoolean), "tonumber": argFunc0(funcToNumber), "tostring": argFunc0(funcToString), "type": argFunc0(funcType), "reverse": argFunc0(funcReverse), "contains": argFunc1(funcContains), + "inside": argFunc1(funcInside), "indices": argFunc1(funcIndices), "index": argFunc1(funcIndex), "rindex": argFunc1(funcRindex), @@ -72,12 +76,14 @@ func init() { "endswith": argFunc1(funcEndsWith), "ltrimstr": argFunc1(funcLtrimstr), "rtrimstr": argFunc1(funcRtrimstr), + "trimstr": argFunc1(funcTrimstr), "ltrim": argFunc0(funcLtrim), "rtrim": argFunc0(funcRtrim), "trim": argFunc0(funcTrim), "explode": argFunc0(funcExplode), "implode": argFunc0(funcImplode), - "split": {argcount1 | argcount2, false, funcSplit}, + "split": argFunc1(funcSplit), + "join": argFunc1(funcJoin), "ascii_downcase": argFunc0(funcASCIIDowncase), "ascii_upcase": argFunc0(funcASCIIUpcase), "tojson": argFunc0(funcToJSON), @@ -118,7 +124,6 @@ func init() { "_group_by": argFunc1(funcGroupBy), "unique": argFunc0(funcUnique), "_unique_by": argFunc1(funcUniqueBy), - "join": argFunc1(funcJoin), "sin": mathFunc("sin", math.Sin), "cos": mathFunc("cos", math.Cos), "tan": mathFunc("tan", math.Tan), @@ -165,8 +170,8 @@ func init() { "copysign": mathFunc2("copysign", math.Copysign), "drem": mathFunc2("drem", funcDrem), "fdim": mathFunc2("fdim", math.Dim), - "fmax": mathFunc2("fmax", math.Max), - "fmin": mathFunc2("fmin", math.Min), + "fmax": mathFunc2("fmax", funcFmax), + "fmin": mathFunc2("fmin", funcFmin), "fmod": mathFunc2("fmod", math.Mod), "hypot": mathFunc2("hypot", math.Hypot), "jn": mathFunc2("jn", funcJn), @@ -197,8 +202,8 @@ func init() { "strflocaltime": argFunc1(funcStrflocaltime), "strptime": argFunc1(funcStrptime), "now": argFunc0(funcNow), - "_match": argFunc3(funcMatch), - "_capture": argFunc0(funcCapture), + "_match": argFunc3(nil), + "_captures": argFunc0(funcCaptures), "error": {argcount0 | argcount1, false, funcError}, "halt": argFunc0(funcHalt), "halt_error": {argcount0 | argcount1, false, funcHaltError}, @@ -285,7 +290,7 @@ func funcAbs(v any) any { if v >= 0 { return v } - return -v + return negate(v) case float64: return math.Abs(v) case *big.Int: @@ -293,6 +298,11 @@ func funcAbs(v any) any { return v } return new(big.Int).Abs(v) + case json.Number: + if !strings.HasPrefix(v.String(), "-") { + return v + } + return v[1:] default: return &func0TypeError{"abs", v} } @@ -306,7 +316,7 @@ func funcLength(v any) any { if v >= 0 { return v } - return -v + return negate(v) case float64: return math.Abs(v) case *big.Int: @@ -314,6 +324,11 @@ func funcLength(v any) any { return v } return new(big.Int).Abs(v) + case json.Number: + if !strings.HasPrefix(v.String(), "-") { + return v + } + return v[1:] case string: return len([]rune(v)) case []any: @@ -395,70 +410,17 @@ func funcHas(v, x any) any { return &func1TypeError{"has", v, x} } -func funcToEntries(v any) any { - switch v := v.(type) { - case []any: - w := make([]any, len(v)) - for i, x := range v { - w[i] = map[string]any{"key": i, "value": x} - } - return w - case map[string]any: - w := make([]any, len(v)) - for i, k := range keys(v) { - w[i] = map[string]any{"key": k, "value": v[k]} - } - return w - default: - return &func0TypeError{"to_entries", v} - } -} - -func funcFromEntries(v any) any { - vs, ok := v.([]any) - if !ok { - return &func0TypeError{"from_entries", v} - } - w := make(map[string]any, len(vs)) - for _, v := range vs { - switch v := v.(type) { - case map[string]any: - var ( - key string - value any - ok bool - ) - for _, k := range [4]string{"key", "Key", "name", "Name"} { - if k := v[k]; k != nil && k != false { - if key, ok = k.(string); !ok { - return &func0WrapError{"from_entries", vs, &objectKeyNotStringError{k}} - } - break - } - } - if !ok { - return &func0WrapError{"from_entries", vs, &objectKeyNotStringError{nil}} - } - for _, k := range [2]string{"value", "Value"} { - if value, ok = v[k]; ok { - break - } - } - w[key] = value - default: - return &func0TypeError{"from_entries", v} - } - } - return w -} - func funcAdd(v any) any { vs, ok := values(v) if !ok { return &func0TypeError{"add", v} } - v = nil - for _, x := range vs { + return add(slices.Values(vs)) +} + +func add(xs iter.Seq[any]) any { + var v any + for x := range xs { switch x := x.(type) { case nil: continue @@ -487,16 +449,10 @@ func funcAdd(v any) any { case map[string]any: switch w := v.(type) { case nil: - m := make(map[string]any, len(x)) - for k, e := range x { - m[k] = e - } - v = m + v = maps.Clone(x) continue case map[string]any: - for k, e := range x { - w[k] = e - } + maps.Copy(w, x) continue } } @@ -514,9 +470,27 @@ func funcAdd(v any) any { return v } +func funcToBoolean(v any) any { + switch v := v.(type) { + case bool: + return v + case string: + switch v { + case "true": + return true + case "false": + return false + default: + return &func0WrapError{"toboolean", v, errors.New("invalid boolean")} + } + default: + return &func0TypeError{"toboolean", v} + } +} + func funcToNumber(v any) any { switch v := v.(type) { - case int, float64, *big.Int: + case int, float64, *big.Int, json.Number: return v case string: if !newLexer(v).validNumber() { @@ -529,7 +503,7 @@ func funcToNumber(v any) any { } func toNumber(v string) any { - return normalizeNumber(json.Number(v)) + return parseNumber(json.Number(v)) } func funcToString(v any) any { @@ -593,6 +567,10 @@ func funcContains(v, x any) any { ) } +func funcInside(v, x any) any { + return funcContains(x, v) +} + func funcIndices(v, x any) any { return indexFunc("indices", v, x, indices) } @@ -602,7 +580,7 @@ func indices(vs, xs []any) any { if len(xs) == 0 { return rs } - for i := 0; i <= len(vs)-len(xs); i++ { + for i := range len(vs) - len(xs) + 1 { if Compare(vs[i:i+len(xs)], xs) == 0 { rs = append(rs, i) } @@ -615,7 +593,7 @@ func funcIndex(v, x any) any { if len(xs) == 0 { return nil } - for i := 0; i <= len(vs)-len(xs); i++ { + for i := range len(vs) - len(xs) + 1 { if Compare(vs[i:i+len(xs)], xs) == 0 { return i } @@ -707,6 +685,18 @@ func funcRtrimstr(v, x any) any { return strings.TrimSuffix(s, t) } +func funcTrimstr(v, x any) any { + s, ok := v.(string) + if !ok { + return &func1TypeError{"trimstr", v, x} + } + t, ok := x.(string) + if !ok { + return &func1TypeError{"trimstr", v, x} + } + return strings.TrimSuffix(strings.TrimPrefix(s, t), t) +} + func funcLtrim(v any) any { s, ok := v.(string) if !ok { @@ -770,33 +760,16 @@ func funcImplode(v any) any { return sb.String() } -func funcSplit(v any, args []any) any { +func funcSplit(v, x any) any { s, ok := v.(string) if !ok { return &func0TypeError{"split", v} } - x, ok := args[0].(string) + t, ok := x.(string) if !ok { return &func0TypeError{"split", x} } - var ss []string - if len(args) == 1 { - ss = strings.Split(s, x) - } else { - var flags string - if args[1] != nil { - v, ok := args[1].(string) - if !ok { - return &func0TypeError{"split", args[1]} - } - flags = v - } - r, err := compileRegexp(x, flags) - if err != nil { - return err - } - ss = r.Split(s, -1) - } + ss := strings.Split(s, t) xs := make([]any, len(ss)) for i, s := range ss { xs[i] = s @@ -804,6 +777,34 @@ func funcSplit(v any, args []any) any { return xs } +func funcJoin(v, x any) any { + vs, ok := values(v) + if !ok { + return &func1TypeError{"join", v, x} + } + if len(vs) == 0 { + return "" + } + return add(func(yield func(any) bool) { + for i, v := range vs { + s := x + if i == 0 { + s = "" + } + if !yield(s) { + return + } + switch w := v.(type) { + case bool, int, float64, *big.Int, json.Number: + v = jsonMarshal(w) + } + if !yield(v) { + return + } + } + }) +} + func funcASCIIDowncase(v any) any { s, ok := v.(string) if !ok { @@ -848,7 +849,7 @@ func funcFromJSON(v any) any { if _, err := dec.Token(); err != io.EOF { return &func0TypeError{"fromjson", v} } - return normalizeNumbers(w) + return w } func funcFormat(v, x any) any { @@ -997,7 +998,7 @@ func funcIndex2(_, v, x any) any { default: return &expectedObjectError{v} } - case int, float64, *big.Int: + case int, float64, *big.Int, json.Number: i, _ := toInt(x) switch v := v.(type) { case nil: @@ -1087,7 +1088,7 @@ func slice(vs []any, e, s any) any { } } if e != nil { - if i, ok := toInt(e); ok { + if i, ok := toIntCeil(e); ok { end = clampIndex(i, start, len(vs)) } else { return &arrayIndexNotNumberError{e} @@ -1109,7 +1110,7 @@ func sliceString(v string, e, s any) any { } } if e != nil { - if i, ok := toInt(e); ok { + if i, ok := toIntCeil(e); ok { end = clampIndex(i, start, l) } else { return &stringIndexNotNumberError{e} @@ -1140,16 +1141,16 @@ func sliceString(v string, e, s any) any { return v[start:end] } -func clampIndex(i, min, max int) int { +func clampIndex(i, minimum, maximum int) int { if i < 0 { - i += max + i += maximum } - if i < min { - return min - } else if i < max { + if i < minimum { + return minimum + } else if i < maximum { return i } else { - return max + return maximum } } @@ -1166,7 +1167,7 @@ func funcFlatten(v any, args []any) any { if !ok { return &func0TypeError{"flatten", args[0]} } - if depth < 0 { + if lt(depth, 0) { return &flattenDepthError{depth} } } @@ -1200,7 +1201,7 @@ func (iter *rangeIter) Next() (any, bool) { func funcRange(_ any, xs []any) any { for _, x := range xs { switch x.(type) { - case int, float64, *big.Int: + case int, float64, *big.Int, json.Number: default: return &func0TypeError{"range", x} } @@ -1356,44 +1357,9 @@ func uniqueBy(name string, v, x any) any { return rs } -func funcJoin(v, x any) any { - vs, ok := values(v) - if !ok { - return &func1TypeError{"join", v, x} - } - if len(vs) == 0 { - return "" - } - sep, ok := x.(string) - if len(vs) > 1 && !ok { - return &func1TypeError{"join", v, x} - } - ss := make([]string, len(vs)) - for i, v := range vs { - switch v := v.(type) { - case nil: - case string: - ss[i] = v - case bool: - if v { - ss[i] = "true" - } else { - ss[i] = "false" - } - case int, float64, *big.Int: - ss[i] = jsonMarshal(v) - default: - return &joinTypeError{v} - } - } - return strings.Join(ss, sep) -} - func funcSignificand(v float64) float64 { - if math.IsNaN(v) || math.IsInf(v, 0) || v == 0.0 { - return v - } - return math.Float64frombits((math.Float64bits(v) & 0x800fffffffffffff) | 0x3ff0000000000000) + frac, _ := math.Frexp(v) + return frac * 2 } func funcExp10(v float64) float64 { @@ -1414,6 +1380,9 @@ func funcModf(v any) any { if !ok { return &func0TypeError{"modf", v} } + if math.IsInf(x, 0) { + return []any{math.Copysign(0, x), x} + } i, f := math.Modf(x) return []any{f, i} } @@ -1431,6 +1400,26 @@ func funcDrem(l, r float64) float64 { return x } +func funcFmax(l, r float64) float64 { + if math.IsNaN(l) { + return r + } + if math.IsNaN(r) { + return l + } + return max(l, r) +} + +func funcFmin(l, r float64) float64 { + if math.IsNaN(l) { + return r + } + if math.IsNaN(r) { + return l + } + return min(l, r) +} + func funcJn(l, r float64) float64 { return math.Jn(int(l), r) } @@ -1474,7 +1463,7 @@ func funcIsnan(v any) any { func funcIsnormal(v any) any { if v, ok := toFloat(v); ok { - e := math.Float64bits(v) & 0x7ff0000000000000 >> 52 + e := (math.Float64bits(v) & 0x7ff0000000000000) >> 52 return 0 < e && e < 0x7ff } return false @@ -1585,7 +1574,7 @@ func update(v any, path []any, n any, a allocator) (any, error) { default: return nil, &expectedObjectError{v} } - case int, float64, *big.Int: + case int, float64, *big.Int, json.Number: i, _ := toInt(p) switch v := v.(type) { case nil: @@ -1621,6 +1610,9 @@ func update(v any, path []any, n any, a allocator) (any, error) { func updateObject(v map[string]any, k string, path []any, n any, a allocator) (any, error) { x, ok := v[k] if !ok && n == struct{}{} { + if v == nil { + return nil, nil + } return v, nil } u, err := update(x, path, n, a) @@ -1632,9 +1624,7 @@ func updateObject(v map[string]any, k string, path []any, n any, a allocator) (a return v, nil } w := a.makeObject(len(v) + 1) - for k, v := range v { - w[k] = v - } + maps.Copy(w, v) w[k] = u return w, nil } @@ -1643,6 +1633,9 @@ func updateArrayIndex(v []any, i int, path []any, n any, a allocator) (any, erro var x any if j := clampIndex(i, -1, len(v)); j < 0 { if n == struct{}{} { + if v == nil { + return nil, nil + } return v, nil } return nil, &arrayIndexNegativeError{i} @@ -1651,9 +1644,12 @@ func updateArrayIndex(v []any, i int, path []any, n any, a allocator) (any, erro x = v[i] } else { if n == struct{}{} { + if v == nil { + return nil, nil + } return v, nil } - if i >= 0x8000000 { + if i >= 0x20000000 { return nil, &arrayIndexTooLargeError{i} } } @@ -1691,15 +1687,26 @@ func updateArraySlice(v []any, m map[string]any, path []any, n any, a allocator) return nil, &expectedStartEndError{m} } var start, end int - if i, ok := toInt(s); ok { - start = clampIndex(i, 0, len(v)) + if s != nil { + if i, ok := toInt(s); ok { + start = clampIndex(i, 0, len(v)) + } else { + return nil, &arrayIndexNotNumberError{s} + } } - if i, ok := toInt(e); ok { - end = clampIndex(i, start, len(v)) + if e != nil { + if i, ok := toIntCeil(e); ok { + end = clampIndex(i, start, len(v)) + } else { + return nil, &arrayIndexNotNumberError{e} + } } else { end = len(v) } if start == end && n == struct{}{} { + if v == nil { + return nil, nil + } return v, nil } u, err := update(v[start:end], path, n, a) @@ -1927,8 +1934,7 @@ func funcStrptime(v, x any) any { if err != nil { return &func1WrapError{"strptime", v, x, err} } - var u time.Time - if t == u { + if t.Equal(time.Time{}) { return &func1TypeError{"strptime", v, x} } return epochToArray(timeToEpoch(t), time.UTC) @@ -1966,18 +1972,20 @@ func funcNow(any) any { return timeToEpoch(time.Now()) } -func funcMatch(v, re, fs, testing any) any { - name := "match" +func funcMatch(v, re, fs, testing any, cache *sync.Map) any { + var name string if testing == true { name = "test" + } else { + name = "match" } var flags string if fs != nil { - v, ok := fs.(string) + var ok bool + flags, ok = fs.(string) if !ok { return &func2TypeError{name, v, re, fs} } - flags = v } s, ok := v.(string) if !ok { @@ -1987,22 +1995,20 @@ func funcMatch(v, re, fs, testing any) any { if !ok { return &func2TypeError{name, v, re, fs} } - r, err := compileRegexp(restr, flags) + r, err := compileRegexp(restr, flags, cache) if err != nil { return err } - var xs [][]int - if strings.ContainsRune(flags, 'g') && testing != true { - xs = r.FindAllStringSubmatchIndex(s, -1) + if testing == true { + return r.MatchString(s) + } + var n int + if strings.ContainsRune(flags, 'g') { + n = -1 } else { - got := r.FindStringSubmatchIndex(s) - if testing == true { - return got != nil - } - if got != nil { - xs = [][]int{got} - } + n = 1 } + xs := r.FindAllStringSubmatchIndex(s, n) res, names := make([]any, len(xs)), r.SubexpNames() for i, x := range xs { captures := make([]any, (len(x)-2)/2) @@ -2037,13 +2043,16 @@ func funcMatch(v, re, fs, testing any) any { return res } -func compileRegexp(re, flags string) (*regexp.Regexp, error) { +func compileRegexp(re, flags string, cache *sync.Map) (*regexp.Regexp, error) { + key := [2]string{re, flags} + if r, ok := cache.Load(key); ok { + return r.(*regexp.Regexp), nil + } if strings.IndexFunc(flags, func(r rune) bool { return r != 'g' && r != 'i' && r != 'm' }) >= 0 { return nil, fmt.Errorf("unsupported regular expression flag: %q", flags) } - re = strings.ReplaceAll(re, "(?<", "(?P<") if strings.ContainsRune(flags, 'i') { re = "(?i)" + re } @@ -2054,15 +2063,11 @@ func compileRegexp(re, flags string) (*regexp.Regexp, error) { if err != nil { return nil, fmt.Errorf("invalid regular expression %q: %s", re, err) } + cache.Store(key, r) return r, nil } -func funcCapture(v any) any { - vs, ok := v.(map[string]any) - if !ok { - return &expectedObjectError{v} - } - v = vs["captures"] +func funcCaptures(v any) any { captures, ok := v.([]any) if !ok { return &expectedArrayError{v} @@ -2116,13 +2121,22 @@ func toInt(x any) (int, bool) { return math.MaxInt, true } return math.MinInt, true + case json.Number: + return toInt(parseNumber(x)) default: return 0, false } } +func toIntCeil(x any) (int, bool) { + if f, ok := x.(float64); ok { + x = math.Ceil(f) + } + return toInt(x) +} + func floatToInt(x float64) int { - if math.MinInt <= x && x <= math.MaxInt { + if math.MinInt <= x && x < math.MaxInt { return int(x) } if x > 0 { @@ -2139,6 +2153,9 @@ func toFloat(x any) (float64, bool) { return x, true case *big.Int: return bigToFloat(x), true + case json.Number: + v, err := x.Float64() + return v, err == nil default: return 0.0, false } @@ -2153,3 +2170,21 @@ func bigToFloat(x *big.Int) float64 { } return math.Inf(x.Sign()) } + +func parseNumber(v json.Number) any { + if i, err := v.Int64(); err == nil && math.MinInt <= i && i <= math.MaxInt { + return int(i) + } + if strings.ContainsAny(v.String(), ".eE") { + if f, err := v.Float64(); err == nil { + return f + } + } + if bi, ok := new(big.Int).SetString(v.String(), 10); ok { + return bi + } + if strings.HasPrefix(v.String(), "-") { + return math.Inf(-1) + } + return math.Inf(1) +} diff --git a/vendor/github.com/itchyny/gojq/go.dev.mod b/vendor/github.com/itchyny/gojq/go.dev.mod index bdc69df6..dc9f4cc5 100644 --- a/vendor/github.com/itchyny/gojq/go.dev.mod +++ b/vendor/github.com/itchyny/gojq/go.dev.mod @@ -1,8 +1,8 @@ module github.com/itchyny/gojq -go 1.21 +go 1.24.0 require ( - github.com/itchyny/astgen-go v0.0.0-20231113225122-e1c22b9aaf7b // indirect - github.com/itchyny/timefmt-go v0.1.6 // indirect + github.com/itchyny/astgen-go v0.0.0-20250520171007-4331c963041e // indirect + github.com/itchyny/timefmt-go v0.1.8 // indirect ) diff --git a/vendor/github.com/itchyny/gojq/go.dev.sum b/vendor/github.com/itchyny/gojq/go.dev.sum index e8691b82..873ec047 100644 --- a/vendor/github.com/itchyny/gojq/go.dev.sum +++ b/vendor/github.com/itchyny/gojq/go.dev.sum @@ -1,4 +1,4 @@ -github.com/itchyny/astgen-go v0.0.0-20231113225122-e1c22b9aaf7b h1:72fDU7wad+r3iQObaxhlXVIpAIMRUIUMrNa3go1vb8s= -github.com/itchyny/astgen-go v0.0.0-20231113225122-e1c22b9aaf7b/go.mod h1:Zp6xzEWVc2pQ/ObfLD6t/M6gDegsJWKdGKJSiT7qlu0= -github.com/itchyny/timefmt-go v0.1.6 h1:ia3s54iciXDdzWzwaVKXZPbiXzxxnv1SPGFfM/myJ5Q= -github.com/itchyny/timefmt-go v0.1.6/go.mod h1:RRDZYC5s9ErkjQvTvvU7keJjxUYzIISJGxm9/mAERQg= +github.com/itchyny/astgen-go v0.0.0-20250520171007-4331c963041e h1:Pu7Ev38D+75aWdsHzULyVZfMP3WrgIHNUaAUH81CTqE= +github.com/itchyny/astgen-go v0.0.0-20250520171007-4331c963041e/go.mod h1:8EXgnGrgW1p0qVnOF1A/4ORQEUAi8TvxQdIR+zJfKxM= +github.com/itchyny/timefmt-go v0.1.8 h1:1YEo1JvfXeAHKdjelbYr/uCuhkybaHCeTkH8Bo791OI= +github.com/itchyny/timefmt-go v0.1.8/go.mod h1:5E46Q+zj7vbTgWY8o5YkMeYb4I6GeWLFnetPy5oBrAI= diff --git a/vendor/github.com/itchyny/gojq/iter.go b/vendor/github.com/itchyny/gojq/iter.go index d0bed960..fb8a8ffe 100644 --- a/vendor/github.com/itchyny/gojq/iter.go +++ b/vendor/github.com/itchyny/gojq/iter.go @@ -6,14 +6,14 @@ type Iter interface { } // NewIter creates a new [Iter] from values. -func NewIter(values ...any) Iter { +func NewIter[T any](values ...T) Iter { switch len(values) { case 0: return emptyIter{} case 1: return &unitIter{value: values[0]} default: - iter := sliceIter(values) + iter := sliceIter[T](values) return &iter } } @@ -37,9 +37,9 @@ func (iter *unitIter) Next() (any, bool) { return iter.value, true } -type sliceIter []any +type sliceIter[T any] []T -func (iter *sliceIter) Next() (any, bool) { +func (iter *sliceIter[T]) Next() (any, bool) { if len(*iter) == 0 { return nil, false } diff --git a/vendor/github.com/itchyny/gojq/lexer.go b/vendor/github.com/itchyny/gojq/lexer.go index 0c2efd12..82aeef31 100644 --- a/vendor/github.com/itchyny/gojq/lexer.go +++ b/vendor/github.com/itchyny/gojq/lexer.go @@ -507,7 +507,7 @@ func quoteAndEscape(src string, quote bool, controls int) []byte { buf[len(buf)-1] = '"' j++ } - for i := 0; i < len(src); i++ { + for i := range len(src) { if ch := src[i]; ch < ' ' { const hex = "0123456789abcdef" copy(buf[j:], `\u00`) diff --git a/vendor/github.com/itchyny/gojq/normalize.go b/vendor/github.com/itchyny/gojq/normalize.go deleted file mode 100644 index 2bfcd215..00000000 --- a/vendor/github.com/itchyny/gojq/normalize.go +++ /dev/null @@ -1,84 +0,0 @@ -package gojq - -import ( - "encoding/json" - "math" - "math/big" - "strings" -) - -func normalizeNumber(v json.Number) any { - if i, err := v.Int64(); err == nil && math.MinInt <= i && i <= math.MaxInt { - return int(i) - } - if strings.ContainsAny(v.String(), ".eE") { - if f, err := v.Float64(); err == nil { - return f - } - } - if bi, ok := new(big.Int).SetString(v.String(), 10); ok { - return bi - } - if strings.HasPrefix(v.String(), "-") { - return math.Inf(-1) - } - return math.Inf(1) -} - -func normalizeNumbers(v any) any { - switch v := v.(type) { - case json.Number: - return normalizeNumber(v) - case *big.Int: - if v.IsInt64() { - if i := v.Int64(); math.MinInt <= i && i <= math.MaxInt { - return int(i) - } - } - return v - case int64: - if math.MinInt <= v && v <= math.MaxInt { - return int(v) - } - return big.NewInt(v) - case int32: - return int(v) - case int16: - return int(v) - case int8: - return int(v) - case uint: - if v <= math.MaxInt { - return int(v) - } - return new(big.Int).SetUint64(uint64(v)) - case uint64: - if v <= math.MaxInt { - return int(v) - } - return new(big.Int).SetUint64(v) - case uint32: - if uint64(v) <= math.MaxInt { - return int(v) - } - return new(big.Int).SetUint64(uint64(v)) - case uint16: - return int(v) - case uint8: - return int(v) - case float32: - return float64(v) - case []any: - for i, x := range v { - v[i] = normalizeNumbers(x) - } - return v - case map[string]any: - for k, x := range v { - v[k] = normalizeNumbers(x) - } - return v - default: - return v - } -} diff --git a/vendor/github.com/itchyny/gojq/operator.go b/vendor/github.com/itchyny/gojq/operator.go index 64b74b78..b1bf6670 100644 --- a/vendor/github.com/itchyny/gojq/operator.go +++ b/vendor/github.com/itchyny/gojq/operator.go @@ -1,6 +1,8 @@ package gojq import ( + "encoding/json" + "maps" "math" "math/big" "strings" @@ -154,19 +156,15 @@ func (op Operator) GoString() (str string) { func (op Operator) getFunc() string { switch op { - case OpPipe: - panic("unreachable") - case OpComma: - panic("unreachable") - case OpAdd: + case OpAdd, OpUpdateAdd: return "_add" - case OpSub: + case OpSub, OpUpdateSub: return "_subtract" - case OpMul: + case OpMul, OpUpdateMul: return "_multiply" - case OpDiv: + case OpDiv, OpUpdateDiv: return "_divide" - case OpMod: + case OpMod, OpUpdateMod: return "_modulo" case OpEq: return "_equal" @@ -180,26 +178,10 @@ func (op Operator) getFunc() string { return "_greatereq" case OpLe: return "_lesseq" - case OpAnd: - panic("unreachable") - case OpOr: - panic("unreachable") - case OpAlt: - panic("unreachable") case OpAssign: return "_assign" case OpModify: return "_modify" - case OpUpdateAdd: - return "_add" - case OpUpdateSub: - return "_subtract" - case OpUpdateMul: - return "_multiply" - case OpUpdateDiv: - return "_divide" - case OpUpdateMod: - return "_modulo" case OpUpdateAlt: return "_alternative" default: @@ -207,15 +189,21 @@ func (op Operator) getFunc() string { } } -func binopTypeSwitch( +func binopTypeSwitch[T any]( l, r any, - callbackInts func(_, _ int) any, - callbackFloats func(_, _ float64) any, - callbackBigInts func(_, _ *big.Int) any, - callbackStrings func(_, _ string) any, - callbackArrays func(_, _ []any) any, - callbackMaps func(_, _ map[string]any) any, - fallback func(_, _ any) any) any { + callbackInts func(_, _ int) T, + callbackFloats func(_, _ float64) T, + callbackBigInts func(_, _ *big.Int) T, + callbackStrings func(_, _ string) T, + callbackArrays func(_, _ []any) T, + callbackMaps func(_, _ map[string]any) T, + fallback func(_, _ any) T) T { + if n, ok := l.(json.Number); ok { + l = parseNumber(n) + } + if n, ok := r.(json.Number); ok { + r = parseNumber(n) + } switch l := l.(type) { case int: switch r := r.(type) { @@ -284,19 +272,33 @@ func funcOpPlus(v any) any { return v case *big.Int: return v + case json.Number: + return v default: return &unaryTypeError{"plus", v} } } +func negate(v int) any { + if v == math.MinInt { + return new(big.Int).Neg(big.NewInt(int64(v))) + } + return -v +} + func funcOpNegate(v any) any { switch v := v.(type) { case int: - return -v + return negate(v) case float64: return -v case *big.Int: return new(big.Int).Neg(v) + case json.Number: + if strings.HasPrefix(v.String(), "-") { + return v[1:] + } + return "-" + v default: return &unaryTypeError{"negate", v} } @@ -334,12 +336,8 @@ func funcOpAdd(_, l, r any) any { return l } m := make(map[string]any, len(l)+len(r)) - for k, v := range l { - m[k] = v - } - for k, v := range r { - m[k] = v - } + maps.Copy(m, l) + maps.Copy(m, r) return m }, func(l, r any) any { @@ -387,6 +385,9 @@ func funcOpSub(_, l, r any) any { func funcOpMul(_, l, r any) any { return binopTypeSwitch(l, r, func(l, r int) any { + if r == -1 { + return negate(l) + } if v := l * r; r == 0 || v/r == l { return v } @@ -416,9 +417,7 @@ func funcOpMul(_, l, r any) any { func deepMergeObjects(l, r map[string]any) any { m := make(map[string]any, len(l)+len(r)) - for k, v := range l { - m[k] = v - } + maps.Copy(m, l) for k, v := range r { if mk, ok := m[k]; ok { if mk, ok := mk.(map[string]any); ok { @@ -433,25 +432,30 @@ func deepMergeObjects(l, r map[string]any) any { } func repeatString(s string, n float64) any { - if n < 0.0 || len(s) > 0 && n > float64(0x10000000/len(s)) || math.IsNaN(n) { + if lt(n, 0) { return nil } - if s == "" { - return "" + c := int(min(n, math.MaxInt32)) + if uint64(len(s))*uint64(c) >= math.MaxInt32 { + return &repeatStringTooLargeError{s, n} } - return strings.Repeat(s, int(n)) + return strings.Repeat(s, c) } func funcOpDiv(_, l, r any) any { return binopTypeSwitch(l, r, func(l, r int) any { - if r == 0 { + switch r { + case 0: return &zeroDivisionError{l, r} + case -1: + return negate(l) + default: + if l%r == 0 { + return l / r + } + return float64(l) / float64(r) } - if l%r == 0 { - return l / r - } - return float64(l) / float64(r) }, func(l, r float64) any { if r == 0.0 { @@ -489,19 +493,23 @@ func funcOpDiv(_, l, r any) any { func funcOpMod(_, l, r any) any { return binopTypeSwitch(l, r, func(l, r int) any { - if r == 0 { + switch r { + case 0: return &zeroModuloError{l, r} + case -1: + return 0 + default: + return l % r } - return l % r }, func(l, r float64) any { + if math.IsNaN(l) || math.IsNaN(r) { + return math.NaN() + } ri := floatToInt(r) if ri == 0 { return &zeroModuloError{l, r} } - if math.IsNaN(l) || math.IsNaN(r) { - return math.NaN() - } return floatToInt(l) % ri }, func(l, r *big.Int) any { diff --git a/vendor/github.com/itchyny/gojq/option.go b/vendor/github.com/itchyny/gojq/option.go index f1a110fa..801e9a99 100644 --- a/vendor/github.com/itchyny/gojq/option.go +++ b/vendor/github.com/itchyny/gojq/option.go @@ -33,7 +33,7 @@ func WithVariables(variables []string) CompilerOption { // WithFunction is a compiler option for adding a custom internal function. // Specify the minimum and maximum count of the function arguments. These // values should satisfy 0 <= minarity <= maxarity <= 30, otherwise panics. -// On handling numbers, you should take account to int, float64 and *big.Int. +// On handling numbers, take account of int, float64, *big.Int, and json.Number. // These are the number types you are allowed to return, so do not return int64. // Refer to [ValueError] to return a value error just like built-in error // function. If you want to emit multiple values, call the empty function, diff --git a/vendor/github.com/itchyny/gojq/parser.go b/vendor/github.com/itchyny/gojq/parser.go index 5a0dfdc7..98d8b8ee 100644 --- a/vendor/github.com/itchyny/gojq/parser.go +++ b/vendor/github.com/itchyny/gojq/parser.go @@ -147,147 +147,142 @@ const yyEofCode = 1 const yyErrCode = 2 const yyInitialStackSize = 16 -//line parser.go.y:671 +//line parser.go.y:669 //line yacctab:1 var yyExca = [...]int16{ -1, 1, 1, -1, -2, 0, - -1, 145, + -1, 139, 5, 0, -2, 27, - -1, 148, + -1, 142, 7, 0, -2, 30, - -1, 199, + -1, 194, 59, 114, -2, 49, } const yyPrivate = 57344 -const yyLast = 782 +const yyLast = 733 var yyAct = [...]int16{ - 78, 134, 186, 102, 103, 10, 175, 195, 32, 211, - 48, 108, 81, 176, 131, 6, 229, 5, 50, 73, - 74, 159, 14, 180, 181, 182, 124, 98, 110, 135, - 280, 97, 228, 279, 115, 104, 16, 158, 265, 121, - 114, 178, 123, 179, 244, 73, 74, 180, 181, 182, - 73, 74, 112, 113, 154, 155, 136, 117, 117, 117, - 254, 243, 137, 183, 282, 178, 255, 179, 220, 6, - 247, 116, 118, 119, 128, 129, 73, 74, 99, 73, - 74, 227, 73, 74, 246, 141, 238, 183, 201, 237, - 132, 200, 139, 6, 235, 226, 138, 163, 208, 80, - 157, 207, 241, 231, 230, 161, 162, 73, 74, 117, - 117, 117, 117, 117, 117, 117, 117, 117, 117, 83, - 82, 278, 84, 144, 145, 146, 147, 148, 149, 150, - 151, 152, 153, 184, 185, 174, 50, 160, 193, 73, - 74, 127, 196, 202, 203, 126, 197, 73, 74, 125, - 73, 74, 248, 253, 189, 204, 45, 240, 206, 73, - 74, 245, 143, 210, 214, 215, 73, 74, 104, 217, - 218, 213, 79, 219, 86, 87, 76, 90, 88, 89, - 169, 43, 44, 117, 117, 73, 74, 75, 166, 117, - 222, 224, 80, 225, 73, 74, 273, 212, 212, 232, - 132, 223, 234, 216, 120, 271, 73, 74, 191, 239, - 43, 44, 83, 82, 85, 84, 274, 270, 96, 91, - 92, 93, 94, 95, 73, 74, 93, 94, 95, 249, - 84, 164, 251, 252, 196, 236, 267, 250, 197, 130, - 25, 256, 73, 74, 262, 263, 187, 188, 3, 190, - 257, 258, 260, 261, 264, 24, 266, 73, 74, 9, - 221, 268, 269, 117, 117, 111, 171, 272, 172, 170, - 13, 275, 276, 77, 90, 277, 89, 212, 212, 13, - 177, 281, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 106, 107, 91, 92, 93, 94, 95, - 47, 43, 44, 101, 165, 259, 91, 92, 93, 94, - 95, 242, 156, 122, 194, 17, 192, 15, 37, 21, - 22, 23, 33, 133, 105, 205, 7, 34, 209, 35, - 36, 39, 41, 40, 42, 19, 20, 28, 31, 43, - 44, 8, 4, 2, 86, 87, 1, 90, 88, 89, - 0, 29, 30, 0, 168, 90, 18, 0, 0, 27, - 0, 142, 38, 0, 140, 26, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, - 66, 67, 68, 69, 70, 71, 72, 106, 107, 91, - 92, 93, 94, 95, 0, 43, 44, 91, 92, 93, - 94, 95, 0, 0, 0, 0, 0, 11, 12, 17, - 0, 15, 37, 21, 22, 23, 33, 0, 105, 0, - 0, 34, 100, 35, 36, 39, 41, 40, 42, 19, - 20, 28, 31, 43, 44, 0, 0, 0, 0, 86, - 87, 0, 90, 88, 89, 29, 30, 0, 0, 167, - 18, 0, 0, 27, 0, 0, 38, 0, 17, 26, - 15, 37, 21, 22, 23, 33, 0, 0, 0, 0, - 34, 0, 35, 36, 39, 41, 40, 42, 19, 20, - 28, 31, 43, 44, 91, 92, 93, 94, 95, 0, - 0, 0, 0, 0, 29, 30, 90, 88, 89, 18, - 0, 0, 27, 0, 0, 38, 0, 233, 26, 17, - 0, 15, 37, 21, 22, 23, 33, 0, 0, 0, - 0, 34, 0, 35, 36, 39, 41, 40, 42, 19, - 20, 28, 31, 43, 44, 0, 0, 0, 91, 92, - 93, 94, 95, 0, 0, 29, 30, 0, 0, 0, - 18, 0, 0, 27, 0, 0, 38, 0, 109, 26, - 17, 0, 15, 37, 21, 22, 23, 33, 0, 0, - 0, 0, 34, 0, 35, 36, 39, 41, 40, 42, - 19, 20, 28, 31, 43, 44, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 29, 30, 0, 0, - 0, 18, 0, 0, 27, 0, 0, 38, 0, 0, - 26, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, - 71, 72, 49, 0, 0, 0, 0, 0, 0, 0, - 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 79, 129, 174, 195, 103, 10, 210, 190, 175, 227, + 135, 32, 5, 158, 102, 108, 48, 93, 6, 123, + 243, 234, 50, 246, 233, 226, 225, 242, 110, 157, + 98, 264, 15, 99, 115, 122, 97, 245, 104, 120, + 224, 148, 149, 114, 37, 21, 22, 23, 33, 207, + 74, 253, 206, 34, 130, 35, 36, 39, 41, 40, + 42, 19, 20, 28, 31, 43, 44, 116, 117, 118, + 240, 229, 228, 92, 127, 160, 133, 29, 30, 159, + 126, 131, 18, 73, 75, 27, 136, 132, 38, 43, + 44, 26, 125, 95, 94, 204, 96, 153, 203, 124, + 156, 252, 198, 45, 239, 186, 161, 151, 74, 96, + 88, 89, 90, 150, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 137, 179, 180, 181, 183, 184, + 43, 44, 77, 188, 179, 180, 181, 191, 199, 50, + 173, 73, 75, 177, 192, 178, 185, 76, 74, 200, + 74, 119, 177, 202, 178, 205, 74, 80, 86, 87, + 88, 89, 90, 266, 214, 182, 91, 212, 216, 217, + 104, 6, 218, 209, 182, 165, 74, 74, 74, 219, + 6, 73, 75, 73, 75, 221, 222, 74, 223, 73, + 75, 134, 211, 211, 230, 74, 255, 281, 215, 3, + 279, 196, 197, 278, 136, 236, 231, 74, 238, 73, + 75, 73, 75, 170, 273, 171, 169, 74, 25, 74, + 73, 75, 74, 24, 237, 220, 162, 247, 73, 75, + 249, 250, 191, 176, 277, 248, 47, 17, 254, 192, + 73, 75, 251, 261, 262, 9, 256, 257, 101, 263, + 73, 75, 73, 75, 265, 73, 75, 259, 260, 78, + 267, 268, 164, 272, 244, 258, 271, 112, 113, 213, + 274, 275, 211, 211, 276, 74, 241, 155, 121, 74, + 280, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, - 71, 72, 49, 0, 0, 0, 0, 173, 0, 0, - 51, 37, 21, 22, 23, 33, 0, 0, 0, 0, + 71, 72, 106, 107, 189, 187, 128, 201, 73, 75, + 43, 44, 73, 75, 7, 8, 4, 2, 74, 1, + 111, 0, 168, 270, 16, 13, 14, 37, 21, 22, + 23, 33, 0, 105, 13, 0, 34, 208, 35, 36, + 39, 41, 40, 42, 19, 20, 28, 31, 43, 44, + 0, 73, 75, 81, 82, 0, 85, 83, 84, 0, + 29, 30, 269, 167, 85, 18, 84, 0, 27, 0, + 154, 38, 0, 152, 26, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 106, 107, 86, 87, + 88, 89, 90, 0, 43, 44, 86, 87, 88, 89, + 90, 0, 74, 0, 0, 0, 11, 12, 16, 0, + 14, 37, 21, 22, 23, 33, 0, 105, 0, 0, + 34, 100, 35, 36, 39, 41, 40, 42, 19, 20, + 28, 31, 43, 44, 0, 73, 75, 0, 81, 82, + 0, 85, 83, 84, 29, 30, 232, 0, 166, 18, + 0, 0, 27, 0, 0, 38, 0, 16, 26, 14, + 37, 21, 22, 23, 33, 0, 0, 0, 0, 34, + 0, 35, 36, 39, 41, 40, 42, 19, 20, 28, + 31, 43, 44, 86, 87, 88, 89, 90, 0, 0, + 0, 0, 0, 29, 30, 85, 83, 84, 18, 0, + 0, 27, 0, 0, 38, 0, 235, 26, 16, 0, + 14, 37, 21, 22, 23, 33, 0, 0, 0, 0, 34, 0, 35, 36, 39, 41, 40, 42, 19, 20, - 28, 31, 43, 44, 0, 0, 0, 46, 0, 0, - 0, 0, 0, 0, 29, 30, 0, 0, 0, 18, - 0, 0, 27, 0, 0, 38, 0, 0, 26, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, - 106, 199, 0, 0, 0, 0, 0, 0, 43, 44, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 28, 31, 43, 44, 0, 74, 0, 86, 87, 88, + 89, 90, 163, 0, 29, 30, 0, 0, 0, 18, + 0, 0, 27, 0, 0, 38, 0, 109, 26, 16, + 0, 14, 37, 21, 22, 23, 33, 0, 73, 75, + 0, 34, 0, 35, 36, 39, 41, 40, 42, 19, + 20, 28, 31, 43, 44, 0, 0, 81, 82, 0, + 85, 83, 84, 0, 0, 29, 30, 0, 0, 0, + 18, 0, 0, 27, 0, 0, 38, 0, 0, 26, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + 72, 49, 86, 87, 88, 89, 90, 0, 0, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + 72, 49, 85, 0, 0, 0, 172, 0, 0, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + 72, 106, 194, 0, 0, 0, 46, 0, 0, 43, + 44, 0, 0, 0, 86, 87, 88, 89, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 198, + 0, 0, 193, } var yyPact = [...]int16{ - 238, -1000, -1000, -48, 406, 98, 643, -1000, -1000, -1000, - 112, 150, 139, 557, 158, 184, 170, 189, 173, -1000, - -1000, -1000, -1000, -1000, 18, -1000, 368, 506, -1000, 665, - 665, 144, -1000, 557, 665, 665, 665, 174, 557, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -22, -1000, 90, - 86, 82, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 189, -1000, -1000, -45, 405, 45, 642, -1000, -1000, -1000, + 94, 110, 95, 556, 127, 593, 137, 39, 52, -1000, + -1000, -1000, -1000, -1000, -27, -1000, 367, 505, -1000, 28, + 28, 93, -1000, 556, 28, 28, 28, 121, 556, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -29, -1000, 40, + 33, 21, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, 557, 557, 225, -48, -1000, 112, -1, - -1000, -1000, -1000, 173, 312, 115, 665, 665, 665, 665, - 665, 665, 665, 665, 665, 665, -5, -1000, -1000, 557, - -1000, -27, -1000, 78, 46, 557, -1000, -1000, -1000, -1000, - 35, 557, 65, 65, -1000, 210, 162, 65, 445, 350, - -1000, 119, 229, -1000, 613, 30, 30, 30, 112, -1000, - 217, 96, -1000, 202, -1000, -1000, -1, 721, -1000, -1000, - -1000, 29, 557, 557, 170, 499, 267, 358, 256, 175, - 175, -1000, -1000, -1000, 557, 217, 40, 112, -1000, 274, - 665, 665, 103, -1000, 557, -1000, 665, -1, -1, -1000, - -1000, -1000, 557, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, 6, -1000, -1000, -48, -1000, -1000, -1000, - 557, -1, 33, -1000, -32, -1000, 45, 44, 557, -1000, - -1000, 455, 32, 112, 177, 28, -1000, -1000, 557, -1000, - -1000, 110, 170, 110, 43, 112, -1000, 1, -16, 100, - -1000, 22, -1000, 94, 112, -1000, -1000, -1, -1000, 721, - -1, -1, 92, -1000, -2, -1000, -1000, 7, 217, 112, - 665, 665, 230, 557, 557, -1000, -1000, 30, -1000, -1000, - -1000, -1000, -1000, -21, -1000, 557, -1000, 110, 110, 212, - 557, 557, 159, 147, -1000, -1, 138, -1000, 195, 112, - 557, 557, -1000, -1000, 557, 60, -28, 112, -1000, -1000, - 557, 3, -1000, + -1000, -1000, -1000, 556, 24, 556, 177, -45, -1000, 94, + 77, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, -18, -1000, -1000, -1000, 52, 311, -1000, -1000, 556, + -1000, -35, -1000, 20, 16, 556, -1000, -1000, -1000, -1000, + 164, 556, 39, 39, -1000, 531, 149, 444, 349, -1000, + 261, 176, -1000, 612, 108, 108, 108, 94, 99, -1000, + -1000, 24, 672, 163, 172, 44, -1000, 556, 593, 498, + 357, 665, 109, 59, 59, -1000, -1000, -1000, 556, 172, + -1000, -1000, -1000, 36, 556, -9, 94, -1000, 273, 28, + 28, 208, -1000, 556, -1000, 28, 24, 24, -1000, -1000, + -1000, 556, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 117, -1000, -1000, 556, 24, -22, -1000, -39, + -1000, 13, 12, 556, -1000, -45, -1000, -1000, -1000, 94, + 398, -37, -1000, -1000, 454, 162, -1000, 556, -1000, -1000, + 57, 593, 57, 11, 94, -1000, -33, -40, 203, -1000, + -25, -1000, 94, -1000, -1000, 24, -1000, 672, 24, 24, + 181, 43, -1000, -8, 172, -1000, 134, -1000, 94, 28, + 28, 235, 556, 556, -1000, -1000, 108, -1000, -1000, -1000, + -1000, -28, -1000, 556, -1000, -1000, 57, 57, 139, 556, + 556, 304, 265, -1000, 24, 205, -1000, 193, 94, 556, + 556, -1000, -1000, 556, 173, 142, 94, -1000, -1000, 556, + 136, -1000, } var yyPgo = [...]int16{ - 0, 356, 353, 352, 351, 14, 336, 259, 265, 335, - 0, 333, 1, 326, 324, 7, 36, 22, 8, 323, - 12, 322, 321, 315, 314, 313, 3, 9, 6, 13, - 310, 10, 280, 260, 2, 255, 240, 11, 4, + 0, 319, 317, 316, 315, 10, 314, 245, 320, 307, + 0, 306, 1, 305, 304, 7, 32, 237, 11, 278, + 17, 277, 276, 265, 262, 248, 14, 6, 2, 8, + 236, 16, 233, 225, 3, 223, 218, 15, 4, } var yyR1 = [...]int8{ @@ -330,66 +325,66 @@ var yyR2 = [...]int8{ var yyChk = [...]int16{ -1000, -1, -2, 10, -3, -29, 63, -6, -4, -7, - -10, 11, 12, -8, -17, 15, -16, 13, 54, 33, + -10, 11, 12, -8, 15, -16, 13, -17, 54, 33, 34, 17, 18, 19, -35, -36, 63, 57, 35, 49, 50, 36, -18, 20, 25, 27, 28, 16, 60, 29, 31, 30, 32, 37, 38, 58, 64, -30, -31, 29, -37, 37, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 47, 48, 37, 37, -7, -10, 14, - 34, -20, 55, 54, 57, 30, 4, 5, 8, 9, - 7, 49, 50, 51, 52, 53, 29, -20, -18, 60, + 26, 27, 28, 47, 14, 48, 37, 37, -7, -10, + 30, 4, 5, 8, 9, 7, 49, 50, 51, 52, + 53, 29, 34, -20, 55, 54, 57, -20, -18, 60, 64, -25, -26, -38, -18, 60, 29, 30, -37, 62, - -10, -8, -17, -17, -18, -10, -16, -17, -16, -16, - 30, -10, -19, 64, 48, 59, 59, 59, -10, -10, - 14, -5, -29, -11, -12, 30, 57, 63, -20, -18, - 62, -10, 59, 47, -16, -16, -16, -16, -16, -16, - -16, -16, -16, -16, 59, 60, -21, -10, 64, 48, - 59, 59, -10, 62, 21, -24, 26, 14, 14, 61, - 40, 37, 39, 64, -31, -28, -29, -32, 35, 37, - 17, 18, 19, 57, -28, -28, -34, 29, 30, 58, - 47, 6, -13, -12, -14, -15, -38, -18, 60, 30, - 62, 59, -10, -10, -10, -9, -34, 61, 58, 64, - -26, -27, -16, -27, 61, -10, -16, -12, -12, -10, - 62, -33, -28, -5, -10, -12, 62, 48, 64, 48, - 59, 59, -10, 62, -10, 62, 58, 61, 58, -10, - 47, 59, -22, 60, 60, 61, 62, 48, 58, -12, - -15, -12, -12, 61, 62, 59, -34, -27, -27, -23, - 22, 23, -10, -10, -28, 59, -10, 24, -10, -10, - 58, 58, -12, 58, 21, -10, -10, -10, 61, 61, - 58, -10, 61, + -10, -8, -17, -17, -18, -10, -16, -16, -16, 30, + -10, -19, 64, 48, 59, 59, 59, -10, -11, -12, + 30, 57, 63, -10, 14, -5, -29, 47, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16, 59, 60, + -20, -18, 62, -10, 59, -21, -10, 64, 48, 59, + 59, -10, 62, 21, -24, 26, 14, 14, 61, 40, + 37, 39, 64, -31, -28, -29, -32, 35, 37, 17, + 18, 19, 57, -28, -28, 47, 6, -13, -12, -14, + -15, -38, -18, 60, 30, -34, 29, 30, 58, -10, + -10, -9, -34, 62, 59, -10, 61, 58, 64, -26, + -27, -16, -27, 61, -10, -16, -12, -12, -10, 62, + -33, -28, -10, -12, 62, 48, 64, 48, 59, 59, + -10, -5, 58, 61, 58, 62, -10, 62, -10, 47, + 59, -22, 60, 60, 61, 62, 48, -12, -15, -12, + -12, 61, 58, 59, -34, 62, -27, -27, -23, 22, + 23, -10, -10, -28, 59, -10, 24, -10, -10, 58, + 58, -12, 58, 21, -10, -10, -10, 61, 61, 58, + -10, 61, } var yyDef = [...]int16{ 2, -2, 4, 0, 12, 0, 0, 1, 5, 10, - 11, 0, 0, 12, 36, 0, 25, 0, 50, 51, + 11, 0, 0, 12, 0, 25, 0, 36, 50, 51, 52, 55, 56, 57, 58, 60, 0, 0, 66, 0, 0, 69, 71, 0, 0, 0, 0, 0, 0, 89, 90, 91, 92, 84, 86, 3, 125, 0, 128, 0, 0, 0, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, - 155, 156, 157, 0, 0, 0, 8, 13, 20, 0, - 79, 80, 81, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 53, 54, 0, + 155, 156, 157, 0, 0, 0, 0, 8, 13, 20, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 79, 80, 81, 0, 0, 53, 54, 0, 61, 0, 106, 111, 112, 0, 113, 114, 115, 64, - 0, 0, 67, 68, 70, 0, 104, 36, 0, 0, - 77, 0, 0, 126, 0, 0, 0, 0, 21, 24, - 0, 0, 9, 0, 37, 39, 0, 0, 82, 83, - 93, 0, 0, 0, 26, -2, 28, 29, -2, 31, - 32, 33, 34, 35, 0, 0, 0, 98, 62, 0, - 0, 0, 0, 65, 0, 73, 0, 0, 0, 78, - 85, 87, 0, 127, 129, 130, 118, 119, 120, 121, - 122, 123, 124, 0, 131, 132, 8, 18, 19, 7, - 0, 0, 0, 42, 0, 44, 0, 0, 0, -2, - 94, 0, 0, 23, 0, 0, 16, 59, 0, 63, - 107, 108, 117, 109, 0, 100, 105, 0, 0, 0, - 133, 0, 135, 0, 22, 38, 40, 0, 41, 0, - 0, 0, 0, 95, 0, 96, 14, 0, 0, 99, - 0, 0, 102, 0, 0, 88, 134, 0, 6, 43, - 45, 46, 47, 0, 97, 0, 17, 116, 110, 0, - 0, 0, 0, 0, 136, 0, 0, 72, 0, 103, - 0, 0, 48, 15, 0, 0, 0, 101, 74, 75, - 0, 0, 76, + 0, 0, 67, 68, 70, 0, 104, 0, 0, 77, + 0, 0, 126, 0, 0, 0, 0, 21, 0, 37, + 39, 0, 0, 24, 0, 0, 9, 0, 26, -2, + 28, 29, -2, 31, 32, 33, 34, 35, 0, 0, + 82, 83, 93, 0, 0, 0, 98, 62, 0, 0, + 0, 0, 65, 0, 73, 0, 0, 0, 78, 85, + 87, 0, 127, 129, 130, 118, 119, 120, 121, 122, + 123, 124, 0, 131, 132, 0, 0, 0, 42, 0, + 44, 0, 0, 0, -2, 8, 18, 19, 7, 23, + 0, 0, 16, 94, 0, 0, 59, 0, 63, 107, + 108, 117, 109, 0, 100, 105, 0, 0, 0, 133, + 0, 135, 22, 38, 40, 0, 41, 0, 0, 0, + 0, 0, 14, 0, 0, 95, 0, 96, 99, 0, + 0, 102, 0, 0, 88, 134, 0, 43, 45, 46, + 47, 0, 6, 0, 17, 97, 116, 110, 0, 0, + 0, 0, 0, 136, 0, 0, 72, 0, 103, 0, + 0, 48, 15, 0, 0, 0, 101, 74, 75, 0, + 0, 76, } var yyTok1 = [...]int8{ @@ -868,187 +863,185 @@ yydefault: yyDollar = yyS[yypt-5 : yypt+1] //line parser.go.y:155 { - term := yyDollar[1].value.(*Term) - term.SuffixList = append(term.SuffixList, &Suffix{Bind: &Bind{yyDollar[3].value.([]*Pattern), yyDollar[5].value.(*Query)}}) - yyVAL.value = &Query{Term: term} + yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpPipe, Right: yyDollar[5].value.(*Query), Patterns: yyDollar[3].value.([]*Pattern)} } case 23: yyDollar = yyS[yypt-4 : yypt+1] -//line parser.go.y:161 +//line parser.go.y:159 { yyVAL.value = &Query{Term: &Term{Type: TermTypeLabel, Label: &Label{yyDollar[2].token, yyDollar[4].value.(*Query)}}} } case 24: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:165 +//line parser.go.y:163 { yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpComma, Right: yyDollar[3].value.(*Query)} } case 26: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:172 +//line parser.go.y:170 { yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: yyDollar[2].operator, Right: yyDollar[3].value.(*Query)} } case 27: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:176 +//line parser.go.y:174 { yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: yyDollar[2].operator, Right: yyDollar[3].value.(*Query)} } case 28: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:180 +//line parser.go.y:178 { yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpOr, Right: yyDollar[3].value.(*Query)} } case 29: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:184 +//line parser.go.y:182 { yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpAnd, Right: yyDollar[3].value.(*Query)} } case 30: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:188 +//line parser.go.y:186 { yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: yyDollar[2].operator, Right: yyDollar[3].value.(*Query)} } case 31: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:192 +//line parser.go.y:190 { yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpAdd, Right: yyDollar[3].value.(*Query)} } case 32: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:196 +//line parser.go.y:194 { yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpSub, Right: yyDollar[3].value.(*Query)} } case 33: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:200 +//line parser.go.y:198 { yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpMul, Right: yyDollar[3].value.(*Query)} } case 34: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:204 +//line parser.go.y:202 { yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpDiv, Right: yyDollar[3].value.(*Query)} } case 35: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:208 +//line parser.go.y:206 { yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpMod, Right: yyDollar[3].value.(*Query)} } case 36: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:212 +//line parser.go.y:210 { yyVAL.value = &Query{Term: yyDollar[1].value.(*Term)} } case 37: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:218 +//line parser.go.y:216 { yyVAL.value = []*Pattern{yyDollar[1].value.(*Pattern)} } case 38: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:222 +//line parser.go.y:220 { yyVAL.value = append(yyDollar[1].value.([]*Pattern), yyDollar[3].value.(*Pattern)) } case 39: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:228 +//line parser.go.y:226 { yyVAL.value = &Pattern{Name: yyDollar[1].token} } case 40: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:232 +//line parser.go.y:230 { yyVAL.value = &Pattern{Array: yyDollar[2].value.([]*Pattern)} } case 41: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:236 +//line parser.go.y:234 { yyVAL.value = &Pattern{Object: yyDollar[2].value.([]*PatternObject)} } case 42: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:242 +//line parser.go.y:240 { yyVAL.value = []*Pattern{yyDollar[1].value.(*Pattern)} } case 43: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:246 +//line parser.go.y:244 { yyVAL.value = append(yyDollar[1].value.([]*Pattern), yyDollar[3].value.(*Pattern)) } case 44: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:252 +//line parser.go.y:250 { yyVAL.value = []*PatternObject{yyDollar[1].value.(*PatternObject)} } case 45: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:256 +//line parser.go.y:254 { yyVAL.value = append(yyDollar[1].value.([]*PatternObject), yyDollar[3].value.(*PatternObject)) } case 46: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:262 +//line parser.go.y:260 { yyVAL.value = &PatternObject{Key: yyDollar[1].token, Val: yyDollar[3].value.(*Pattern)} } case 47: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:266 +//line parser.go.y:264 { yyVAL.value = &PatternObject{KeyString: yyDollar[1].value.(*String), Val: yyDollar[3].value.(*Pattern)} } case 48: yyDollar = yyS[yypt-5 : yypt+1] -//line parser.go.y:270 +//line parser.go.y:268 { yyVAL.value = &PatternObject{KeyQuery: yyDollar[2].value.(*Query), Val: yyDollar[5].value.(*Pattern)} } case 49: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:274 +//line parser.go.y:272 { yyVAL.value = &PatternObject{Key: yyDollar[1].token} } case 50: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:280 +//line parser.go.y:278 { yyVAL.value = &Term{Type: TermTypeIdentity} } case 51: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:284 +//line parser.go.y:282 { yyVAL.value = &Term{Type: TermTypeRecurse} } case 52: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:288 +//line parser.go.y:286 { yyVAL.value = &Term{Type: TermTypeIndex, Index: &Index{Name: yyDollar[1].token}} } case 53: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:292 +//line parser.go.y:290 { suffix := yyDollar[2].value.(*Suffix) if suffix.Iter { @@ -1059,452 +1052,452 @@ yydefault: } case 54: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:301 +//line parser.go.y:299 { yyVAL.value = &Term{Type: TermTypeIndex, Index: &Index{Str: yyDollar[2].value.(*String)}} } case 55: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:305 +//line parser.go.y:303 { yyVAL.value = &Term{Type: TermTypeNull} } case 56: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:309 +//line parser.go.y:307 { yyVAL.value = &Term{Type: TermTypeTrue} } case 57: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:313 +//line parser.go.y:311 { yyVAL.value = &Term{Type: TermTypeFalse} } case 58: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:317 +//line parser.go.y:315 { yyVAL.value = &Term{Type: TermTypeFunc, Func: &Func{Name: yyDollar[1].token}} } case 59: yyDollar = yyS[yypt-4 : yypt+1] -//line parser.go.y:321 +//line parser.go.y:319 { yyVAL.value = &Term{Type: TermTypeFunc, Func: &Func{Name: yyDollar[1].token, Args: yyDollar[3].value.([]*Query)}} } case 60: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:325 +//line parser.go.y:323 { yyVAL.value = &Term{Type: TermTypeFunc, Func: &Func{Name: yyDollar[1].token}} } case 61: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:329 +//line parser.go.y:327 { yyVAL.value = &Term{Type: TermTypeObject, Object: &Object{}} } case 62: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:333 +//line parser.go.y:331 { yyVAL.value = &Term{Type: TermTypeObject, Object: &Object{yyDollar[2].value.([]*ObjectKeyVal)}} } case 63: yyDollar = yyS[yypt-4 : yypt+1] -//line parser.go.y:337 +//line parser.go.y:335 { yyVAL.value = &Term{Type: TermTypeObject, Object: &Object{yyDollar[2].value.([]*ObjectKeyVal)}} } case 64: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:341 +//line parser.go.y:339 { yyVAL.value = &Term{Type: TermTypeArray, Array: &Array{}} } case 65: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:345 +//line parser.go.y:343 { yyVAL.value = &Term{Type: TermTypeArray, Array: &Array{yyDollar[2].value.(*Query)}} } case 66: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:349 +//line parser.go.y:347 { yyVAL.value = &Term{Type: TermTypeNumber, Number: yyDollar[1].token} } case 67: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:353 +//line parser.go.y:351 { yyVAL.value = &Term{Type: TermTypeUnary, Unary: &Unary{OpAdd, yyDollar[2].value.(*Term)}} } case 68: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:357 +//line parser.go.y:355 { yyVAL.value = &Term{Type: TermTypeUnary, Unary: &Unary{OpSub, yyDollar[2].value.(*Term)}} } case 69: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:361 +//line parser.go.y:359 { yyVAL.value = &Term{Type: TermTypeFormat, Format: yyDollar[1].token} } case 70: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:365 +//line parser.go.y:363 { yyVAL.value = &Term{Type: TermTypeFormat, Format: yyDollar[1].token, Str: yyDollar[2].value.(*String)} } case 71: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:369 +//line parser.go.y:367 { yyVAL.value = &Term{Type: TermTypeString, Str: yyDollar[1].value.(*String)} } case 72: yyDollar = yyS[yypt-7 : yypt+1] -//line parser.go.y:373 +//line parser.go.y:371 { yyVAL.value = &Term{Type: TermTypeIf, If: &If{yyDollar[2].value.(*Query), yyDollar[4].value.(*Query), yyDollar[5].value.([]*IfElif), yyDollar[6].value.(*Query)}} } case 73: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:377 +//line parser.go.y:375 { yyVAL.value = &Term{Type: TermTypeTry, Try: &Try{yyDollar[2].value.(*Query), yyDollar[3].value.(*Query)}} } case 74: yyDollar = yyS[yypt-9 : yypt+1] -//line parser.go.y:381 +//line parser.go.y:379 { yyVAL.value = &Term{Type: TermTypeReduce, Reduce: &Reduce{yyDollar[2].value.(*Query), yyDollar[4].value.(*Pattern), yyDollar[6].value.(*Query), yyDollar[8].value.(*Query)}} } case 75: yyDollar = yyS[yypt-9 : yypt+1] -//line parser.go.y:385 +//line parser.go.y:383 { yyVAL.value = &Term{Type: TermTypeForeach, Foreach: &Foreach{yyDollar[2].value.(*Query), yyDollar[4].value.(*Pattern), yyDollar[6].value.(*Query), yyDollar[8].value.(*Query), nil}} } case 76: yyDollar = yyS[yypt-11 : yypt+1] -//line parser.go.y:389 +//line parser.go.y:387 { yyVAL.value = &Term{Type: TermTypeForeach, Foreach: &Foreach{yyDollar[2].value.(*Query), yyDollar[4].value.(*Pattern), yyDollar[6].value.(*Query), yyDollar[8].value.(*Query), yyDollar[10].value.(*Query)}} } case 77: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:393 +//line parser.go.y:391 { yyVAL.value = &Term{Type: TermTypeBreak, Break: yyDollar[2].token} } case 78: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:397 +//line parser.go.y:395 { yyVAL.value = &Term{Type: TermTypeQuery, Query: yyDollar[2].value.(*Query)} } case 79: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:401 +//line parser.go.y:399 { yyDollar[1].value.(*Term).SuffixList = append(yyDollar[1].value.(*Term).SuffixList, &Suffix{Index: &Index{Name: yyDollar[2].token}}) } case 80: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:405 +//line parser.go.y:403 { yyDollar[1].value.(*Term).SuffixList = append(yyDollar[1].value.(*Term).SuffixList, yyDollar[2].value.(*Suffix)) } case 81: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:409 +//line parser.go.y:407 { yyDollar[1].value.(*Term).SuffixList = append(yyDollar[1].value.(*Term).SuffixList, &Suffix{Optional: true}) } case 82: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:413 +//line parser.go.y:411 { yyDollar[1].value.(*Term).SuffixList = append(yyDollar[1].value.(*Term).SuffixList, yyDollar[3].value.(*Suffix)) } case 83: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:417 +//line parser.go.y:415 { yyDollar[1].value.(*Term).SuffixList = append(yyDollar[1].value.(*Term).SuffixList, &Suffix{Index: &Index{Str: yyDollar[3].value.(*String)}}) } case 84: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:423 +//line parser.go.y:421 { yyVAL.value = &String{Str: yyDollar[1].token} } case 85: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:427 +//line parser.go.y:425 { yyVAL.value = &String{Queries: yyDollar[2].value.([]*Query)} } case 86: yyDollar = yyS[yypt-0 : yypt+1] -//line parser.go.y:433 +//line parser.go.y:431 { yyVAL.value = []*Query{} } case 87: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:437 +//line parser.go.y:435 { yyVAL.value = append(yyDollar[1].value.([]*Query), &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: yyDollar[2].token}}}) } case 88: yyDollar = yyS[yypt-4 : yypt+1] -//line parser.go.y:441 +//line parser.go.y:439 { yylex.(*lexer).inString = true yyVAL.value = append(yyDollar[1].value.([]*Query), &Query{Term: &Term{Type: TermTypeQuery, Query: yyDollar[3].value.(*Query)}}) } case 93: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:456 +//line parser.go.y:454 { yyVAL.value = &Suffix{Iter: true} } case 94: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:460 +//line parser.go.y:458 { yyVAL.value = &Suffix{Index: &Index{Start: yyDollar[2].value.(*Query)}} } case 95: yyDollar = yyS[yypt-4 : yypt+1] -//line parser.go.y:464 +//line parser.go.y:462 { yyVAL.value = &Suffix{Index: &Index{Start: yyDollar[2].value.(*Query), IsSlice: true}} } case 96: yyDollar = yyS[yypt-4 : yypt+1] -//line parser.go.y:468 +//line parser.go.y:466 { yyVAL.value = &Suffix{Index: &Index{End: yyDollar[3].value.(*Query), IsSlice: true}} } case 97: yyDollar = yyS[yypt-5 : yypt+1] -//line parser.go.y:472 +//line parser.go.y:470 { yyVAL.value = &Suffix{Index: &Index{Start: yyDollar[2].value.(*Query), End: yyDollar[4].value.(*Query), IsSlice: true}} } case 98: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:478 +//line parser.go.y:476 { yyVAL.value = []*Query{yyDollar[1].value.(*Query)} } case 99: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:482 +//line parser.go.y:480 { yyVAL.value = append(yyDollar[1].value.([]*Query), yyDollar[3].value.(*Query)) } case 100: yyDollar = yyS[yypt-0 : yypt+1] -//line parser.go.y:488 +//line parser.go.y:486 { yyVAL.value = []*IfElif(nil) } case 101: yyDollar = yyS[yypt-5 : yypt+1] -//line parser.go.y:492 +//line parser.go.y:490 { yyVAL.value = append(yyDollar[1].value.([]*IfElif), &IfElif{yyDollar[3].value.(*Query), yyDollar[5].value.(*Query)}) } case 102: yyDollar = yyS[yypt-0 : yypt+1] -//line parser.go.y:498 +//line parser.go.y:496 { yyVAL.value = (*Query)(nil) } case 103: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:502 +//line parser.go.y:500 { yyVAL.value = yyDollar[2].value } case 104: yyDollar = yyS[yypt-0 : yypt+1] -//line parser.go.y:508 +//line parser.go.y:506 { yyVAL.value = (*Query)(nil) } case 105: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:512 +//line parser.go.y:510 { yyVAL.value = yyDollar[2].value } case 106: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:518 +//line parser.go.y:516 { yyVAL.value = []*ObjectKeyVal{yyDollar[1].value.(*ObjectKeyVal)} } case 107: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:522 +//line parser.go.y:520 { yyVAL.value = append(yyDollar[1].value.([]*ObjectKeyVal), yyDollar[3].value.(*ObjectKeyVal)) } case 108: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:528 +//line parser.go.y:526 { yyVAL.value = &ObjectKeyVal{Key: yyDollar[1].token, Val: yyDollar[3].value.(*Query)} } case 109: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:532 +//line parser.go.y:530 { yyVAL.value = &ObjectKeyVal{KeyString: yyDollar[1].value.(*String), Val: yyDollar[3].value.(*Query)} } case 110: yyDollar = yyS[yypt-5 : yypt+1] -//line parser.go.y:536 +//line parser.go.y:534 { yyVAL.value = &ObjectKeyVal{KeyQuery: yyDollar[2].value.(*Query), Val: yyDollar[5].value.(*Query)} } case 111: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:540 +//line parser.go.y:538 { yyVAL.value = &ObjectKeyVal{Key: yyDollar[1].token} } case 112: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:544 +//line parser.go.y:542 { yyVAL.value = &ObjectKeyVal{KeyString: yyDollar[1].value.(*String)} } case 116: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:555 +//line parser.go.y:553 { yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpPipe, Right: yyDollar[3].value.(*Query)} } case 118: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:562 +//line parser.go.y:560 { yyVAL.value = &ConstTerm{Object: yyDollar[1].value.(*ConstObject)} } case 119: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:566 +//line parser.go.y:564 { yyVAL.value = &ConstTerm{Array: yyDollar[1].value.(*ConstArray)} } case 120: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:570 +//line parser.go.y:568 { yyVAL.value = &ConstTerm{Number: yyDollar[1].token} } case 121: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:574 +//line parser.go.y:572 { yyVAL.value = &ConstTerm{Str: yyDollar[1].token} } case 122: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:578 +//line parser.go.y:576 { yyVAL.value = &ConstTerm{Null: true} } case 123: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:582 +//line parser.go.y:580 { yyVAL.value = &ConstTerm{True: true} } case 124: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:586 +//line parser.go.y:584 { yyVAL.value = &ConstTerm{False: true} } case 125: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:592 +//line parser.go.y:590 { yyVAL.value = &ConstObject{} } case 126: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:596 +//line parser.go.y:594 { yyVAL.value = &ConstObject{yyDollar[2].value.([]*ConstObjectKeyVal)} } case 127: yyDollar = yyS[yypt-4 : yypt+1] -//line parser.go.y:600 +//line parser.go.y:598 { yyVAL.value = &ConstObject{yyDollar[2].value.([]*ConstObjectKeyVal)} } case 128: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:606 +//line parser.go.y:604 { yyVAL.value = []*ConstObjectKeyVal{yyDollar[1].value.(*ConstObjectKeyVal)} } case 129: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:610 +//line parser.go.y:608 { yyVAL.value = append(yyDollar[1].value.([]*ConstObjectKeyVal), yyDollar[3].value.(*ConstObjectKeyVal)) } case 130: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:616 +//line parser.go.y:614 { yyVAL.value = &ConstObjectKeyVal{Key: yyDollar[1].token, Val: yyDollar[3].value.(*ConstTerm)} } case 131: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:620 +//line parser.go.y:618 { yyVAL.value = &ConstObjectKeyVal{Key: yyDollar[1].token, Val: yyDollar[3].value.(*ConstTerm)} } case 132: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:624 +//line parser.go.y:622 { yyVAL.value = &ConstObjectKeyVal{KeyString: yyDollar[1].token, Val: yyDollar[3].value.(*ConstTerm)} } case 133: yyDollar = yyS[yypt-2 : yypt+1] -//line parser.go.y:630 +//line parser.go.y:628 { yyVAL.value = &ConstArray{} } case 134: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:634 +//line parser.go.y:632 { yyVAL.value = &ConstArray{yyDollar[2].value.([]*ConstTerm)} } case 135: yyDollar = yyS[yypt-1 : yypt+1] -//line parser.go.y:640 +//line parser.go.y:638 { yyVAL.value = []*ConstTerm{yyDollar[1].value.(*ConstTerm)} } case 136: yyDollar = yyS[yypt-3 : yypt+1] -//line parser.go.y:644 +//line parser.go.y:642 { yyVAL.value = append(yyDollar[1].value.([]*ConstTerm), yyDollar[3].value.(*ConstTerm)) } diff --git a/vendor/github.com/itchyny/gojq/parser.go.y b/vendor/github.com/itchyny/gojq/parser.go.y index 5481e211..5f9df778 100644 --- a/vendor/github.com/itchyny/gojq/parser.go.y +++ b/vendor/github.com/itchyny/gojq/parser.go.y @@ -151,11 +151,9 @@ query { $$ = &Query{Left: $1.(*Query), Op: OpPipe, Right: $3.(*Query)} } - | term tokAs bindpatterns '|' query + | query tokAs bindpatterns '|' query { - term := $1.(*Term) - term.SuffixList = append(term.SuffixList, &Suffix{Bind: &Bind{$3.([]*Pattern), $5.(*Query)}}) - $$ = &Query{Term: term} + $$ = &Query{Left: $1.(*Query), Op: OpPipe, Right: $5.(*Query), Patterns: $3.([]*Pattern)} } | tokLabel tokVariable '|' query { diff --git a/vendor/github.com/itchyny/gojq/preview.go b/vendor/github.com/itchyny/gojq/preview.go index e082eb56..92f1a54a 100644 --- a/vendor/github.com/itchyny/gojq/preview.go +++ b/vendor/github.com/itchyny/gojq/preview.go @@ -7,9 +7,9 @@ import "unicode/utf8" // by 30 bytes, and more efficient than truncating the result of [Marshal]. // // This method is used by error messages of built-in operators and functions, -// and accepts only limited types (nil, bool, int, float64, *big.Int, string, -// []any, and map[string]any). Note that the maximum width and trailing strings -// on truncation may be changed in the future. +// and accepts only limited types (nil, bool, int, float64, *big.Int, +// json.Number, string, []any, and map[string]any). Note that the maximum width +// and trailing strings on truncation may be changed in the future. func Preview(v any) string { bs := jsonLimitedMarshal(v, 32) if l := 30; len(bs) > l { diff --git a/vendor/github.com/itchyny/gojq/query.go b/vendor/github.com/itchyny/gojq/query.go index e7cf7789..512fa80d 100644 --- a/vendor/github.com/itchyny/gojq/query.go +++ b/vendor/github.com/itchyny/gojq/query.go @@ -26,15 +26,14 @@ type Query struct { FuncDefs []*FuncDef Term *Term Left *Query - Op Operator Right *Query - Func string + Patterns []*Pattern + Op Operator } // Run the query. // // It is safe to call this method in goroutines, to reuse a parsed [*Query]. -// But for arguments, do not give values sharing same data between goroutines. func (e *Query) Run(v any) Iter { return e.RunWithContext(context.Background(), v) } @@ -67,40 +66,28 @@ func (e *Query) writeTo(s *strings.Builder) { fd.writeTo(s) s.WriteByte(' ') } - if e.Func != "" { - s.WriteString(e.Func) - } else if e.Term != nil { + if e.Term != nil { e.Term.writeTo(s) } else if e.Right != nil { e.Left.writeTo(s) - if e.Op == OpComma { - s.WriteString(", ") - } else { + if e.Op != OpComma { s.WriteByte(' ') - s.WriteString(e.Op.String()) + } + for i, p := range e.Patterns { + if i == 0 { + s.WriteString("as ") + } else { + s.WriteString("?// ") + } + p.writeTo(s) s.WriteByte(' ') } + s.WriteString(e.Op.String()) + s.WriteByte(' ') e.Right.writeTo(s) } } -func (e *Query) minify() { - for _, e := range e.FuncDefs { - e.Minify() - } - if e.Term != nil { - if name := e.Term.toFunc(); name != "" { - e.Term = nil - e.Func = name - } else { - e.Term.minify() - } - } else if e.Right != nil { - e.Left.minify() - e.Right.minify() - } -} - func (e *Query) toIndexKey() any { if e.Term == nil { return nil @@ -177,11 +164,6 @@ func (e *FuncDef) writeTo(s *strings.Builder) { s.WriteByte(';') } -// Minify ... -func (e *FuncDef) Minify() { - e.Body.minify() -} - // Term ... type Term struct { Type TermType @@ -264,65 +246,6 @@ func (e *Term) writeTo(s *strings.Builder) { } } -func (e *Term) minify() { - switch e.Type { - case TermTypeIndex: - e.Index.minify() - case TermTypeFunc: - e.Func.minify() - case TermTypeObject: - e.Object.minify() - case TermTypeArray: - e.Array.minify() - case TermTypeUnary: - e.Unary.minify() - case TermTypeFormat: - if e.Str != nil { - e.Str.minify() - } - case TermTypeString: - e.Str.minify() - case TermTypeIf: - e.If.minify() - case TermTypeTry: - e.Try.minify() - case TermTypeReduce: - e.Reduce.minify() - case TermTypeForeach: - e.Foreach.minify() - case TermTypeLabel: - e.Label.minify() - case TermTypeQuery: - e.Query.minify() - } - for _, e := range e.SuffixList { - e.minify() - } -} - -func (e *Term) toFunc() string { - if len(e.SuffixList) != 0 { - return "" - } - // ref: compiler#compileQuery - switch e.Type { - case TermTypeIdentity: - return "." - case TermTypeRecurse: - return ".." - case TermTypeNull: - return "null" - case TermTypeTrue: - return "true" - case TermTypeFalse: - return "false" - case TermTypeFunc: - return e.Func.toFunc() - default: - return "" - } -} - func (e *Term) toIndexKey() any { switch e.Type { case TermTypeNumber: @@ -384,10 +307,6 @@ func (e *Unary) writeTo(s *strings.Builder) { e.Term.writeTo(s) } -func (e *Unary) minify() { - e.Term.minify() -} - func (e *Unary) toNumber() any { v := e.Term.toNumber() if v != nil && e.Op == OpSub { @@ -511,18 +430,6 @@ func (e *Index) writeSuffixTo(s *strings.Builder) { } } -func (e *Index) minify() { - if e.Str != nil { - e.Str.minify() - } - if e.Start != nil { - e.Start.minify() - } - if e.End != nil { - e.End.minify() - } -} - func (e *Index) toIndexKey() any { if e.Name != "" { return e.Name @@ -583,19 +490,6 @@ func (e *Func) writeTo(s *strings.Builder) { } } -func (e *Func) minify() { - for _, x := range e.Args { - x.minify() - } -} - -func (e *Func) toFunc() string { - if len(e.Args) != 0 { - return "" - } - return e.Name -} - // String ... type String struct { Str string @@ -626,12 +520,6 @@ func (e *String) writeTo(s *strings.Builder) { s.WriteByte('"') } -func (e *String) minify() { - for _, e := range e.Queries { - e.minify() - } -} - // Object ... type Object struct { KeyVals []*ObjectKeyVal @@ -658,12 +546,6 @@ func (e *Object) writeTo(s *strings.Builder) { s.WriteString(" }") } -func (e *Object) minify() { - for _, e := range e.KeyVals { - e.minify() - } -} - // ObjectKeyVal ... type ObjectKeyVal struct { Key string @@ -694,17 +576,6 @@ func (e *ObjectKeyVal) writeTo(s *strings.Builder) { } } -func (e *ObjectKeyVal) minify() { - if e.KeyString != nil { - e.KeyString.minify() - } else if e.KeyQuery != nil { - e.KeyQuery.minify() - } - if e.Val != nil { - e.Val.minify() - } -} - // Array ... type Array struct { Query *Query @@ -724,18 +595,11 @@ func (e *Array) writeTo(s *strings.Builder) { s.WriteByte(']') } -func (e *Array) minify() { - if e.Query != nil { - e.Query.minify() - } -} - // Suffix ... type Suffix struct { Index *Index Iter bool Optional bool - Bind *Bind } func (e *Suffix) String() string { @@ -755,16 +619,6 @@ func (e *Suffix) writeTo(s *strings.Builder) { s.WriteString("[]") } else if e.Optional { s.WriteByte('?') - } else if e.Bind != nil { - e.Bind.writeTo(s) - } -} - -func (e *Suffix) minify() { - if e.Index != nil { - e.Index.minify() - } else if e.Bind != nil { - e.Bind.minify() } } @@ -785,38 +639,6 @@ func (e *Suffix) toIndices(xs []any) []any { return e.Index.toIndices(xs) } -// Bind ... -type Bind struct { - Patterns []*Pattern - Body *Query -} - -func (e *Bind) String() string { - var s strings.Builder - e.writeTo(&s) - return s.String() -} - -func (e *Bind) writeTo(s *strings.Builder) { - for i, p := range e.Patterns { - if i == 0 { - s.WriteString(" as ") - p.writeTo(s) - s.WriteByte(' ') - } else { - s.WriteString("?// ") - p.writeTo(s) - s.WriteByte(' ') - } - } - s.WriteString("| ") - e.Body.writeTo(s) -} - -func (e *Bind) minify() { - e.Body.minify() -} - // If ... type If struct { Cond *Query @@ -847,17 +669,6 @@ func (e *If) writeTo(s *strings.Builder) { s.WriteString(" end") } -func (e *If) minify() { - e.Cond.minify() - e.Then.minify() - for _, x := range e.Elif { - x.minify() - } - if e.Else != nil { - e.Else.minify() - } -} - // IfElif ... type IfElif struct { Cond *Query @@ -877,11 +688,6 @@ func (e *IfElif) writeTo(s *strings.Builder) { e.Then.writeTo(s) } -func (e *IfElif) minify() { - e.Cond.minify() - e.Then.minify() -} - // Try ... type Try struct { Body *Query @@ -903,13 +709,6 @@ func (e *Try) writeTo(s *strings.Builder) { } } -func (e *Try) minify() { - e.Body.minify() - if e.Catch != nil { - e.Catch.minify() - } -} - // Reduce ... type Reduce struct { Query *Query @@ -936,12 +735,6 @@ func (e *Reduce) writeTo(s *strings.Builder) { s.WriteByte(')') } -func (e *Reduce) minify() { - e.Query.minify() - e.Start.minify() - e.Update.minify() -} - // Foreach ... type Foreach struct { Query *Query @@ -973,15 +766,6 @@ func (e *Foreach) writeTo(s *strings.Builder) { s.WriteByte(')') } -func (e *Foreach) minify() { - e.Query.minify() - e.Start.minify() - e.Update.minify() - if e.Extract != nil { - e.Extract.minify() - } -} - // Label ... type Label struct { Ident string @@ -1001,10 +785,6 @@ func (e *Label) writeTo(s *strings.Builder) { e.Body.writeTo(s) } -func (e *Label) minify() { - e.Body.minify() -} - // ConstTerm ... type ConstTerm struct { Object *ConstObject diff --git a/vendor/github.com/itchyny/gojq/type.go b/vendor/github.com/itchyny/gojq/type.go index bb388e20..89ccda0e 100644 --- a/vendor/github.com/itchyny/gojq/type.go +++ b/vendor/github.com/itchyny/gojq/type.go @@ -1,6 +1,7 @@ package gojq import ( + "encoding/json" "fmt" "math/big" ) @@ -8,14 +9,15 @@ import ( // TypeOf returns the jq-flavored type name of v. // // This method is used by built-in type/0 function, and accepts only limited -// types (nil, bool, int, float64, *big.Int, string, []any, and map[string]any). +// types (nil, bool, int, float64, *big.Int, json.Number, string, []any, and +// map[string]any). func TypeOf(v any) string { switch v.(type) { case nil: return "null" case bool: return "boolean" - case int, float64, *big.Int: + case int, float64, *big.Int, json.Number: return "number" case string: return "string" diff --git a/vendor/github.com/itchyny/timefmt-go/CHANGELOG.md b/vendor/github.com/itchyny/timefmt-go/CHANGELOG.md index d863ac3b..43b26213 100644 --- a/vendor/github.com/itchyny/timefmt-go/CHANGELOG.md +++ b/vendor/github.com/itchyny/timefmt-go/CHANGELOG.md @@ -1,4 +1,15 @@ # Changelog +## [v0.1.8](https://github.com/itchyny/timefmt-go/compare/v0.1.7..v0.1.8) (2026-04-01) +* fix parsing negative year and Unix time (`%Y`, `%G`, `%s`) +* fix formatting negative year, century, Unix time (`%Y`, `%G`, `%C`, `%y`, `%g`, `%s`) +* fix `%g` parsing to use the same two-digit year threshold 69 as `%y` +* fix `%s` formatting and parsing on 32-bit platforms +* support parsing time zone offset with `%:::z` +* improve performance of parsing/formatting compound directives + +## [v0.1.7](https://github.com/itchyny/timefmt-go/compare/v0.1.6..v0.1.7) (2025-10-01) +* refactor code using built-in `min` and `max` functions + ## [v0.1.6](https://github.com/itchyny/timefmt-go/compare/v0.1.5..v0.1.6) (2024-06-01) * support parsing week directives (`%A`, `%a`, `%w`, `%u`, `%V`, `%U`, `%W`) * validate range of values on parsing directives diff --git a/vendor/github.com/itchyny/timefmt-go/LICENSE b/vendor/github.com/itchyny/timefmt-go/LICENSE index 84d6cb03..de520bb3 100644 --- a/vendor/github.com/itchyny/timefmt-go/LICENSE +++ b/vendor/github.com/itchyny/timefmt-go/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2020-2022 itchyny +Copyright (c) 2020-2025 itchyny Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/github.com/itchyny/timefmt-go/format.go b/vendor/github.com/itchyny/timefmt-go/format.go index b38202df..24ea7b2c 100644 --- a/vendor/github.com/itchyny/timefmt-go/format.go +++ b/vendor/github.com/itchyny/timefmt-go/format.go @@ -1,7 +1,6 @@ package timefmt import ( - "math" "strconv" "time" ) @@ -14,7 +13,7 @@ func Format(t time.Time, format string) string { // AppendFormat appends formatted time string to the buffer. func AppendFormat(buf []byte, t time.Time, format string) []byte { year, month, day := t.Date() - hour, min, sec := t.Clock() + hour, minute, second := t.Clock() var width, colons int var padding byte var pending string @@ -69,21 +68,13 @@ func AppendFormat(buf []byte, t time.Time, format string) []byte { goto L case '1', '2', '3', '4', '5', '6', '7', '8', '9': width = int(b & 0x0F) - const maxWidth = 1024 for i++; i < len(format); i++ { - b = format[i] - if b <= '9' && '0' <= b { - width = width*10 + int(b&0x0F) - if width >= math.MaxInt/10 { - width = maxWidth - } + if b = format[i]; b <= '9' && '0' <= b { + width = min(width*10+int(b&0x0F), 1024) } else { break } } - if width > maxWidth { - width = maxWidth - } if padding == ^paddingMask { padding = ' ' | ^paddingMask } @@ -92,37 +83,27 @@ func AppendFormat(buf []byte, t time.Time, format string) []byte { } goto L case 'Y': - if width == 0 { - width = 4 - } - buf = appendInt(buf, year, width, padding) + buf = appendInt(buf, year, or(width, 4), padding) case 'y': - if width < 2 { - width = 2 - } - buf = appendInt(buf, year%100, width, padding) + buf = appendInt(buf, abs(year%100), max(width, 2), padding) case 'C': - if width < 2 { - width = 2 + c := year / 100 + z := year < 0 && c == 0 + if z { + c = -1 } - buf = appendInt(buf, year/100, width, padding) - case 'g': - if width < 2 { - width = 2 + buf = appendInt(buf, c, max(width, 2), padding) + if z { + buf[len(buf)-1] = '0' } + case 'g': year, _ := t.ISOWeek() - buf = appendInt(buf, year%100, width, padding) + buf = appendInt(buf, abs(year%100), max(width, 2), padding) case 'G': - if width == 0 { - width = 4 - } year, _ := t.ISOWeek() - buf = appendInt(buf, year, width, padding) + buf = appendInt(buf, year, or(width, 4), padding) case 'm': - if width < 2 { - width = 2 - } - buf = appendInt(buf, int(month), width, padding) + buf = appendInt(buf, int(month), max(width, 2), padding) case 'B': buf = appendString(buf, longMonthNames[month-1], width, padding, upper, swap) case 'b', 'h': @@ -134,74 +115,43 @@ func AppendFormat(buf []byte, t time.Time, format string) []byte { case 'w': buf = appendInt(buf, int(t.Weekday()), width, padding) case 'u': - w := int(t.Weekday()) - if w == 0 { - w = 7 - } - buf = appendInt(buf, w, width, padding) + buf = appendInt(buf, or(int(t.Weekday()), 7), width, padding) case 'V': - if width < 2 { - width = 2 - } _, week := t.ISOWeek() - buf = appendInt(buf, week, width, padding) + buf = appendInt(buf, week, max(width, 2), padding) case 'U': - if width < 2 { - width = 2 - } week := (t.YearDay() + 6 - int(t.Weekday())) / 7 - buf = appendInt(buf, week, width, padding) + buf = appendInt(buf, week, max(width, 2), padding) case 'W': - if width < 2 { - width = 2 - } week := t.YearDay() if int(t.Weekday()) > 0 { week -= int(t.Weekday()) - 7 } week /= 7 - buf = appendInt(buf, week, width, padding) + buf = appendInt(buf, week, max(width, 2), padding) case 'e': if padding < ^paddingMask { padding = ' ' } fallthrough case 'd': - if width < 2 { - width = 2 - } - buf = appendInt(buf, day, width, padding) + buf = appendInt(buf, day, max(width, 2), padding) case 'j': - if width < 3 { - width = 3 - } - buf = appendInt(buf, t.YearDay(), width, padding) + buf = appendInt(buf, t.YearDay(), max(width, 3), padding) case 'k': if padding < ^paddingMask { padding = ' ' } fallthrough case 'H': - if width < 2 { - width = 2 - } - buf = appendInt(buf, hour, width, padding) + buf = appendInt(buf, hour, max(width, 2), padding) case 'l': if padding < ^paddingMask { padding = ' ' } fallthrough case 'I': - if width < 2 { - width = 2 - } - h := hour - if h > 12 { - h -= 12 - } else if h == 0 { - h = 12 - } - buf = appendInt(buf, h, width, padding) + buf = appendInt(buf, or(hour%12, 12), max(width, 2), padding) case 'P': swap = !(upper || swap) fallthrough @@ -212,25 +162,16 @@ func AppendFormat(buf []byte, t time.Time, format string) []byte { buf = appendString(buf, "PM", width, padding, upper, swap) } case 'M': - if width < 2 { - width = 2 - } - buf = appendInt(buf, min, width, padding) + buf = appendInt(buf, minute, max(width, 2), padding) case 'S': - if width < 2 { - width = 2 - } - buf = appendInt(buf, sec, width, padding) + buf = appendInt(buf, second, max(width, 2), padding) case 's': if padding < ^paddingMask { padding = ' ' } - buf = appendInt(buf, int(t.Unix()), width, padding) + buf = appendInt64(buf, t.Unix(), width, padding) case 'f': - if width == 0 { - width = 6 - } - buf = appendInt(buf, t.Nanosecond()/1000, width, padding) + buf = appendInt(buf, t.Nanosecond()/1000, or(width, 6), padding) case 'Z', 'z': name, offset := t.Zone() if b == 'Z' && name != "" { @@ -266,19 +207,11 @@ func AppendFormat(buf []byte, t time.Time, format string) []byte { } } colons = 0 - if i != j { - l := len(buf) - k = j + 1 - (l - j) - if k < i { - l = j + 1 + i - k - k = i - } else { - l = j + 1 - } - copy(buf[k:], buf[j:]) - buf = buf[:l] + if k = min(len(buf)-j-1, j-i); k > 0 { + copy(buf[j-k:], buf[j:]) + buf = buf[:len(buf)-k] if padding&paddingMask == '0' { - buf[i], buf[k] = buf[k], buf[i] + buf[i], buf[j-k] = buf[j-k], buf[i] } } case ':': @@ -312,13 +245,24 @@ func AppendFormat(buf []byte, t time.Time, format string) []byte { buf = appendString(buf, "\n", width, padding, false, false) case '%': buf = appendString(buf, "%", width, padding, false, false) + case 'c': + pending, swap = "a b e H:M:S Y", false + case '+': + pending, swap = "a b e H:M:S Z Y", false + case 'v': + pending, swap = "e-b-Y", false + case 'r': + pending, swap = "I:M:S p", false + case 'F': + pending = "Y-m-d" + case 'D', 'x': + pending = "m/d/y" + case 'T', 'X': + pending = "H:M:S" + case 'R': + pending = "H:M" default: if pending == "" { - var ok bool - if pending, ok = compositions[b]; ok { - swap = false - break - } buf = appendLast(buf, format[:i], width-1, padding) } buf = append(buf, b) @@ -336,81 +280,79 @@ K: return appendLast(buf, format, width, padding) } +const smalls = "" + + "00010203040506070809" + + "10111213141516171819" + + "20212223242526272829" + + "30313233343536373839" + + "40414243444546474849" + + "50515253545556575859" + + "60616263646566676869" + + "70717273747576777879" + + "80818283848586878889" + + "90919293949596979899" + func appendInt(buf []byte, num, width int, padding byte) []byte { + var digits int + switch { + default: + fallthrough + case num < 0: + return appendInt64(buf, int64(num), width, padding) + case num < 100 && width == 2 && padding == '0': + return append(buf, smalls[num*2:num*2+2]...) + case num < 10: + digits = 1 + case num < 100: + digits = 2 + case num < 1000: + digits = 3 + case num < 10000: + digits = 4 + } if padding != ^paddingMask { padding &= paddingMask - switch width { - case 2: - if num < 10 { - buf = append(buf, padding) - goto L1 - } else if num < 100 { - goto L2 - } else if num < 1000 { - goto L3 - } else if num < 10000 { - goto L4 - } - case 4: - if num < 1000 { - buf = append(buf, padding) - if num < 100 { - buf = append(buf, padding) - if num < 10 { - buf = append(buf, padding) - goto L1 - } - goto L2 - } - goto L3 - } else if num < 10000 { - goto L4 - } - default: - i := len(buf) - for ; width > 1; width-- { - buf = append(buf, padding) - } - j := len(buf) - buf = strconv.AppendInt(buf, int64(num), 10) - l := len(buf) - if j+1 == l || i == j { - return buf - } - k := j + 1 - (l - j) - if k < i { - l = j + 1 + i - k - k = i - } else { - l = j + 1 - } - copy(buf[k:], buf[j:]) - return buf[:l] + for ; width > digits; width-- { + buf = append(buf, padding) } } - if num < 100 { - if num < 10 { - goto L1 - } - goto L2 - } else if num < 10000 { - if num < 1000 { - goto L3 + switch digits { + case 4: + buf = append(buf, byte(num/1000)|'0') + num %= 1000 + fallthrough + case 3: + buf = append(buf, byte(num/100)|'0') + num %= 100 + fallthrough + case 2: + buf = append(buf, byte(num/10)|'0') + num %= 10 + fallthrough + default: + return append(buf, byte(num)|'0') + } +} + +func appendInt64(buf []byte, num int64, width int, padding byte) []byte { + if padding == ^paddingMask { + return strconv.AppendInt(buf, num, 10) + } + padding &= paddingMask + i := len(buf) + for ; width > 1; width-- { + buf = append(buf, padding) + } + j := len(buf) + buf = strconv.AppendInt(buf, num, 10) + if k := min(len(buf)-j-1, j-i); k > 0 { + copy(buf[j-k:], buf[j:]) + buf = buf[:len(buf)-k] + if j -= k; buf[i] == '0' && buf[j] == '-' { + buf[i], buf[j] = '-', '0' } - goto L4 } - return strconv.AppendInt(buf, int64(num), 10) -L4: - buf = append(buf, byte(num/1000)|'0') - num %= 1000 -L3: - buf = append(buf, byte(num/100)|'0') - num %= 100 -L2: - buf = append(buf, byte(num/10)|'0') - num %= 10 -L1: - return append(buf, byte(num)|'0') + return buf } func appendString(buf []byte, str string, width int, padding byte, upper, swap bool) []byte { @@ -453,6 +395,20 @@ func appendLast(buf []byte, format string, width int, padding byte) []byte { return buf } +func or(x, y int) int { + if x != 0 { + return x + } + return y +} + +func abs(x int) int { + if x >= 0 { + return x + } + return -x +} + const paddingMask byte = 0x7F var longMonthNames = []string{ @@ -504,16 +460,3 @@ var shortWeekNames = []string{ "Fri", "Sat", } - -var compositions = map[byte]string{ - 'c': "a b e H:M:S Y", - '+': "a b e H:M:S Z Y", - 'F': "Y-m-d", - 'D': "m/d/y", - 'x': "m/d/y", - 'v': "e-b-Y", - 'T': "H:M:S", - 'X': "H:M:S", - 'r': "I:M:S p", - 'R': "H:M", -} diff --git a/vendor/github.com/itchyny/timefmt-go/parse.go b/vendor/github.com/itchyny/timefmt-go/parse.go index 26ae0f0c..ab606346 100644 --- a/vendor/github.com/itchyny/timefmt-go/parse.go +++ b/vendor/github.com/itchyny/timefmt-go/parse.go @@ -3,7 +3,6 @@ package timefmt import ( "errors" "fmt" - "math" "time" ) @@ -19,32 +18,39 @@ func ParseInLocation(source, format string, loc *time.Location) (t time.Time, er } func parse(source, format string, loc, base *time.Location) (t time.Time, err error) { - year, month, day, hour, min, sec, nsec := 1900, 1, 0, 0, 0, 0, 0 + year, month, day, hour, minute, second, nanosecond := 1900, 1, 0, 0, 0, 0, 0 defer func() { if err != nil { err = fmt.Errorf("failed to parse %q with %q: %w", source, format, err) } }() - var j, week, weekday, yday, colons int + var j, week, weekday, yday, colons, sign int century, weekstart := -1, time.Weekday(-1) var pm, hasISOYear, hasZoneName, hasZoneOffset bool var pending string for i, l := 0, len(source); i < len(format); i++ { if b := format[i]; b == '%' { - i++ - if i == len(format) { + if i++; i == len(format) { err = errors.New(`stray "%"`) return } b = format[i] L: switch b { + case 'G': + hasISOYear = true + fallthrough case 'Y': - if year, j, err = parseNumber(source, j, 4, 0, 9999, 'Y'); err != nil { + sign, j = parseSign(source, j, l) + if year, j, err = parseInt(source, j, 4, 0, 9999, b); err != nil { return } + year *= sign + case 'g': + hasISOYear = true + fallthrough case 'y': - if year, j, err = parseNumber(source, j, 2, 0, 99, 'y'); err != nil { + if year, j, err = parseInt(source, j, 2, 0, 99, b); err != nil { return } if year < 69 { @@ -53,22 +59,16 @@ func parse(source, format string, loc, base *time.Location) (t time.Time, err er year += 1900 } case 'C': - if century, j, err = parseNumber(source, j, 2, 0, 99, 'C'); err != nil { + sign, j = parseSign(source, j, l) + if sign < 0 { + err = errors.New(`negative century is not supported for "%C"`) return } - case 'g': - if year, j, err = parseNumber(source, j, 2, 0, 99, b); err != nil { + if century, j, err = parseInt(source, j, 2, 0, 99, 'C'); err != nil { return } - year += 2000 - hasISOYear = true - case 'G': - if year, j, err = parseNumber(source, j, 4, 0, 9999, b); err != nil { - return - } - hasISOYear = true case 'm': - if month, j, err = parseNumber(source, j, 2, 1, 12, 'm'); err != nil { + if month, j, err = parseInt(source, j, 2, 1, 12, 'm'); err != nil { return } case 'B': @@ -88,50 +88,44 @@ func parse(source, format string, loc, base *time.Location) (t time.Time, err er return } case 'w': - if weekday, j, err = parseNumber(source, j, 1, 0, 6, 'w'); err != nil { + if weekday, j, err = parseInt(source, j, 1, 0, 6, 'w'); err != nil { return } weekday++ case 'u': - if weekday, j, err = parseNumber(source, j, 1, 1, 7, 'u'); err != nil { + if weekday, j, err = parseInt(source, j, 1, 1, 7, 'u'); err != nil { return } weekday = weekday%7 + 1 case 'V': - if week, j, err = parseNumber(source, j, 2, 1, 53, b); err != nil { + if week, j, err = parseInt(source, j, 2, 1, 53, b); err != nil { return } weekstart = time.Thursday - if weekday == 0 { - weekday = 2 - } + weekday = or(weekday, 2) case 'U': - if week, j, err = parseNumber(source, j, 2, 0, 53, b); err != nil { + if week, j, err = parseInt(source, j, 2, 0, 53, b); err != nil { return } weekstart = time.Sunday - if weekday == 0 { - weekday = 1 - } + weekday = or(weekday, 1) case 'W': - if week, j, err = parseNumber(source, j, 2, 0, 53, b); err != nil { + if week, j, err = parseInt(source, j, 2, 0, 53, b); err != nil { return } weekstart = time.Monday - if weekday == 0 { - weekday = 2 - } + weekday = or(weekday, 2) case 'e': if j < l && source[j] == ' ' { j++ } fallthrough case 'd': - if day, j, err = parseNumber(source, j, 2, 1, 31, b); err != nil { + if day, j, err = parseInt(source, j, 2, 1, 31, b); err != nil { return } case 'j': - if yday, j, err = parseNumber(source, j, 3, 1, 366, 'j'); err != nil { + if yday, j, err = parseInt(source, j, 3, 1, 366, 'j'); err != nil { return } case 'k': @@ -140,7 +134,7 @@ func parse(source, format string, loc, base *time.Location) (t time.Time, err er } fallthrough case 'H': - if hour, j, err = parseNumber(source, j, 2, 0, 23, b); err != nil { + if hour, j, err = parseInt(source, j, 2, 0, 23, b); err != nil { return } case 'l': @@ -149,7 +143,7 @@ func parse(source, format string, loc, base *time.Location) (t time.Time, err er } fallthrough case 'I': - if hour, j, err = parseNumber(source, j, 2, 1, 12, b); err != nil { + if hour, j, err = parseInt(source, j, 2, 1, 12, b); err != nil { return } if hour == 12 { @@ -162,32 +156,33 @@ func parse(source, format string, loc, base *time.Location) (t time.Time, err er } pm = ampm == 2 case 'M': - if min, j, err = parseNumber(source, j, 2, 0, 59, 'M'); err != nil { + if minute, j, err = parseInt(source, j, 2, 0, 59, 'M'); err != nil { return } case 'S': - if sec, j, err = parseNumber(source, j, 2, 0, 60, 'S'); err != nil { + if second, j, err = parseInt(source, j, 2, 0, 60, 'S'); err != nil { return } case 's': - var unix int - if unix, j, err = parseNumber(source, j, 10, 0, math.MaxInt, 's'); err != nil { + sign, j = parseSign(source, j, l) + var unix int64 + if unix, j, err = parseInt64(source, j, 19, 's'); err != nil { return } - t = time.Unix(int64(unix), 0).In(time.UTC) + t = time.Unix(int64(sign)*unix, 0).In(time.UTC) var mon time.Month year, mon, day = t.Date() - hour, min, sec = t.Clock() + hour, minute, second = t.Clock() month = int(mon) case 'f': - usec, i := 0, j - if usec, j, err = parseNumber(source, j, 6, 0, 999999, 'f'); err != nil { + microsecond, i := 0, j + if microsecond, j, err = parseInt(source, j, 6, 0, 999999, 'f'); err != nil { return } for i = j - i; i < 6; i++ { - usec *= 10 + microsecond *= 10 } - nsec = usec * 1000 + nanosecond = microsecond * 1000 case 'Z': i := j for ; j < l; j++ { @@ -213,19 +208,19 @@ func parse(source, format string, loc, base *time.Location) (t time.Time, err er err = parseZFormatError(colons) return } - sign := 1 + sign = 1 switch source[j] { case '-': sign = -1 fallthrough case '+': - hour, min, sec, i := 0, 0, 0, j - if hour, j, _ = parseNumber(source, j+1, 2, 0, 23, 'z'); j != i+3 { + hour, minute, second, i := 0, 0, 0, j+1 + if hour, j, _ = parseInt(source, i, 2, 0, 23, 'z'); j != i+2 { err = parseZFormatError(colons) return } if j >= l || source[j] != ':' { - if colons > 0 { + if colons > 0 && colons < 3 { err = expectedColonForZFormatError(colons) return } @@ -233,26 +228,26 @@ func parse(source, format string, loc, base *time.Location) (t time.Time, err er colons = 4 } i = j - if min, j, _ = parseNumber(source, j, 2, 0, 59, 'z'); j != i+2 { - if colons > 0 { + if minute, j, _ = parseInt(source, i, 2, 0, 59, 'z'); j != i+2 { + if colons > 0 && colons != 3 { err = parseZFormatError(colons & 3) return } j = i } else if colons > 1 { if j >= l || source[j] != ':' { - if colons == 2 { + if colons < 3 { err = expectedColonForZFormatError(colons) return } } else { - i = j - if sec, j, _ = parseNumber(source, j+1, 2, 0, 59, 'z'); j != i+3 { - if colons == 2 { + i = j + 1 + if second, j, _ = parseInt(source, i, 2, 0, 59, 'z'); j != i+2 { + if colons < 3 { err = parseZFormatError(colons) return } - j = i + j = i - 1 } } } @@ -260,7 +255,7 @@ func parse(source, format string, loc, base *time.Location) (t time.Time, err er if hasZoneName { name, _ = locationZone(loc) } - loc, colons = time.FixedZone(name, sign*((hour*60+min)*60+sec)), 0 + loc, colons = time.FixedZone(name, sign*((hour*60+minute)*60+second)), 0 hasZoneOffset = true case 'Z': loc, colons, j = time.UTC, 0, j+1 @@ -276,12 +271,12 @@ func parse(source, format string, loc, base *time.Location) (t time.Time, err er } j++ } else { - for colons = 1; colons <= 2; colons++ { + for colons = 1; colons <= 3; colons++ { if i++; i == len(format) { break } else if b = format[i]; b == 'z' { goto L - } else if b != ':' || colons == 2 { + } else if b != ':' || colons == 3 { break } } @@ -308,12 +303,24 @@ func parse(source, format string, loc, base *time.Location) (t time.Time, err er return } j++ + case 'c': + pending = "a b e H:M:S Y" + case '+': + pending = "a b e H:M:S Z Y" + case 'v': + pending = "e-b-Y" + case 'r': + pending = "I:M:S p" + case 'F': + pending = "Y-m-d" + case 'D', 'x': + pending = "m/d/y" + case 'T', 'X': + pending = "H:M:S" + case 'R': + pending = "H:M" default: if pending == "" { - var ok bool - if pending, ok = compositions[b]; ok { - break - } err = fmt.Errorf(`unexpected format "%%%c"`, b) return } @@ -350,7 +357,7 @@ func parse(source, format string, loc, base *time.Location) (t time.Time, err er err = errors.New(`use "%Y" to parse non-ISO year for "%j"`) return } - return time.Date(year, time.January, yday, hour, min, sec, nsec, loc), nil + return time.Date(year, time.January, yday, hour, minute, second, nanosecond, loc), nil } if weekstart >= time.Sunday { if weekstart == time.Thursday { @@ -365,12 +372,12 @@ func parse(source, format string, loc, base *time.Location) (t time.Time, err er if weekstart > time.Sunday && weekday == 1 { week++ } - t := time.Date(year, time.January, -int(weekstart), hour, min, sec, nsec, loc) + t := time.Date(year, time.January, -int(weekstart), hour, minute, second, nanosecond, loc) return t.AddDate(0, 0, week*7-int(t.Weekday())+weekday-1), nil } day = 1 } - return time.Date(year, time.Month(month), day, hour, min, sec, nsec, loc), nil + return time.Date(year, time.Month(month), day, hour, minute, second, nanosecond, loc), nil } func locationZone(loc *time.Location) (name string, offset int) { @@ -392,37 +399,58 @@ func (err expectedFormatError) Error() string { type parseZFormatError int func (err parseZFormatError) Error() string { - return `cannot parse "%` + `::z"`[2-err:] + return `cannot parse "%` + `:::z"`[3-err:] } type expectedColonForZFormatError int func (err expectedColonForZFormatError) Error() string { - return `expected ':' for "%` + `::z"`[2-err:] + return `expected ':' for "%` + `:::z"`[3-err:] } type expectedZAfterColonError int func (err expectedZAfterColonError) Error() string { - return `expected 'z' after "%` + `::"`[2-err:] + return `expected 'z' after "%` + `:::"`[3-err:] } -func parseNumber(source string, index, size, min, max int, format byte) (int, int, error) { +func parseSign(source string, index, l int) (int, int) { + if index < l && source[index] == '-' { + return -1, index + 1 + } + return 1, index +} + +// parseInt parses an integer from source. This is intentionally not a +// wrapper of parseInt64 to avoid the overhead of int64 arithmetic and +// function call indirection in the hot path (~20% slower in benchmarks). +func parseInt(source string, index, size, minimum, maximum int, format byte) (int, int, error) { var value int - if l := len(source); index+size > l { - size = l - } else { - size += index + i := index + for size = min(i+size, len(source)); i < size; i++ { + if b := source[i] - '0'; b < 10 { + value = value*10 + int(b) + } else { + break + } + } + if i == index || value < minimum || maximum < value { + return 0, 0, parseFormatError(format) } + return value, i, nil +} + +func parseInt64(source string, index, size int, format byte) (int64, int, error) { + var value int64 i := index - for ; i < size; i++ { - if b := source[i]; '0' <= b && b <= '9' { - value = value*10 + int(b&0x0F) + for size = min(i+size, len(source)); i < size; i++ { + if b := source[i] - '0'; b < 10 { + value = value*10 + int64(b) } else { break } } - if i == index || value < min || max < value { + if i == index { return 0, 0, parseFormatError(format) } return value, i, nil diff --git a/vendor/modules.txt b/vendor/modules.txt index 41009177..bb461df9 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -10,11 +10,11 @@ github.com/google/go-github/v59/github # github.com/google/go-querystring v1.1.0 ## explicit; go 1.10 github.com/google/go-querystring/query -# github.com/itchyny/gojq v0.12.17 -## explicit; go 1.21 +# github.com/itchyny/gojq v0.12.19 +## explicit; go 1.24.0 github.com/itchyny/gojq -# github.com/itchyny/timefmt-go v0.1.6 -## explicit; go 1.20 +# github.com/itchyny/timefmt-go v0.1.8 +## explicit; go 1.24 github.com/itchyny/timefmt-go # github.com/kr/pretty v0.3.1 ## explicit; go 1.12