Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/eiiches/jackson-jq

jq for Jackson Java JSON Processor
https://github.com/eiiches/jackson-jq

jackson java jq json

Last synced: 3 months ago
JSON representation

jq for Jackson Java JSON Processor

Awesome Lists containing this project

README

        

jackson-jq
==========

Pure Java [jq](http://stedolan.github.io/jq/) Implementation for Jackson JSON Processor

[![GitHub Actions](https://github.com/eiiches/jackson-jq/workflows/test/badge.svg)](https://github.com/eiiches/jackson-jq/actions)

Usage
-----

First, you need Java 8 or later.

If you use Maven, add the following snippet to the `` section of your POM. For instructions for other build tools (Gradle, etc.), visit [jackson-jq](https://search.maven.org/artifact/net.thisptr/jackson-jq/1.0.0-preview.20240207/jar) on search.maven.org.

```xml

net.thisptr
jackson-jq
1.0.0-preview.20240207

```

See [jackson-jq/src/test/java/examples/Usage.java](jackson-jq/src/test/java/examples/Usage.java) for the API usage.

Using a jackson-jq command line tool
------------------------------------

To test a query quickly, we provide jackson-jq CLI.

*Please note that jackson-jq is a Java library and the CLI is provided solely for debugging/testing purpose (and not for production). The command-line options might change without notice.*

```sh
$ curl -LO https://repo1.maven.org/maven2/net/thisptr/jackson-jq-cli/1.0.0-preview.20240207/jackson-jq-cli-1.0.0-preview.20240207.jar

$ java -jar jackson-jq-cli-1.0.0-preview.20240207.jar --help
usage: jackson-jq [OPTIONS...] QUERY
-c,--compact compact instead of pretty-printed output
-h,--help print this message
--jq specify jq version
-n,--null-input use `null` as the single input value
-r,--raw output raw strings, not JSON texts

$ java -jar jackson-jq-cli-1.0.0-preview.20240207.jar '.foo'
{"foo": 42}
42
```

To test a query with a specific jq version,

```sh
$ java -jar jackson-jq-cli-1.0.0-preview.20240207.jar --jq 1.5 'join("-")'
["1", 2]
jq: error: string ("-") and number (2) cannot be added

$ java -jar jackson-jq-cli-1.0.0-preview.20240207.jar --jq 1.6 'join("-")' # jq-1.6 can join any values, not only strings
["1", 2]
"1-2"
```

Homebrew (or Linuxbrew) users can alternatively run `brew tap eiiches/jackson-jq && brew install jackson-jq` to install the CLI. `jackson-jq` will be available on your $PATH.

Branches and versioning
-----------------------

There are currently two development branches.

* `develop/1.x`: This branch (you are viewing), which is currently under development for the future 1.0 release. You can find preview releases at [Releases](https://github.com/eiiches/jackson-jq/releases) page (tags: `1.0.0-preview.yyyyMMdd`). Although the API is not stable yet, I recommend new users to use these releases insetad of 0.x versions, because these releases have more features, better compatibility, and better performance.
* `develop/0.x`: The development branch for 0.x versions. Features that need breaking API changes will no longer be added. Go to [Releases](https://github.com/eiiches/jackson-jq/releases) and find the latest 0.x.y version.

PRs can be sent to any of the develop/\* branches. The patch will be ported to the other branch(es) if necessary.

We use [Semantic Versioning 2.0.0](https://semver.org/) for Java API versioning, 1.0.0 onwards. A jq behavior fix (even if it may possibly affect users) will not be considered a major change if the fix is to make the bahavior compatible with ./jq; these kind of incompatible changes are documented in the release note.

If you get different results between ./jq and jackson-jq, please [file an issue](https://github.com/eiiches/jackson-jq/issues). That is a bug on jackson-jq side.

Implementation Status
---------------------

jackson-jq aims to be a compatible jq implementation. However, not every feature is available; some are intentionally omitted because thay are not relevant as a Java library; some may be incomplete, have bugs or are yet to be implemented.

### List of Features

Click to see the list

This table illustrates which features (picked from jq-1.5 manual) are supported and which are not in jackson-jq. We try to keep this list accurate and up to date. If you find something is missing or wrong, please file an issue.

| Language Features / Functions | jackson-jq |
|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|
| [Basic filters](https://stedolan.github.io/jq/manual/v1.5/#Basicfilters) | ○ |
|     • [`.`](https://stedolan.github.io/jq/manual/v1.5/#.) | ○ |
|     • [`.foo`, `.foo.bar`](https://stedolan.github.io/jq/manual/v1.5/#.foo,.foo.bar) | ○ |
|     • [`.foo?`](https://stedolan.github.io/jq/manual/v1.5/#.foo?) | ○ |
|     • [`.[]`, `.[2]`, `.[10:15]`](https://stedolan.github.io/jq/manual/v1.5/#.[<string>],.[2],.[10:15]) | ○ |
|     • [`.[]`](https://stedolan.github.io/jq/manual/v1.5/#.[]) | ○ |
|     • [`.[]?`](https://stedolan.github.io/jq/manual/v1.5/#.[]?) | ○ |
|     • [`,`](https://stedolan.github.io/jq/manual/v1.5/#,) | ○ |
|     • [`ǀ`](https://stedolan.github.io/jq/manual/v1.5/#|) | ○ |
| [Types and Values](https://stedolan.github.io/jq/manual/v1.5/#TypesandValues) | ○ |
|     • [Array construction - `[]`](https://stedolan.github.io/jq/manual/v1.5/#Arrayconstruction-[]) | ○ |
|     • [Objects - `{}`](https://stedolan.github.io/jq/manual/v1.5/#Objects-{}) | ○*4 |
| [Builtin operators and functions](https://stedolan.github.io/jq/manual/v1.5/#Builtinoperatorsandfunctions) | ○ |
|     • [Addition - `+`](https://stedolan.github.io/jq/manual/v1.5/#Addition-+) | ○ |
|     • [Subtraction - `-`](https://stedolan.github.io/jq/manual/v1.5/#Subtraction--) | ○ |
|     • [Multiplication, division, modulo - `*`, `/`, and `%`](https://stedolan.github.io/jq/manual/v1.5/#Multiplication,division,modulo-*,/,and%) | ○*5 |
|     • [`length`](https://stedolan.github.io/jq/manual/v1.5/#length) | ○ |
|     • [`keys`, `keys_unsorted`](https://stedolan.github.io/jq/manual/v1.5/#keys,keys_unsorted) | ○ |
|     • [`has(key)`](https://stedolan.github.io/jq/manual/v1.5/#has(key)) | ○ |
|     • [`in`](https://stedolan.github.io/jq/manual/v1.5/#in) | ○ |
|     • [`path(path_expression)`](https://stedolan.github.io/jq/manual/v1.5/#path(path_expression)) | ○*7 |
|     • [`del(path_expression)`](https://stedolan.github.io/jq/manual/v1.5/#del(path_expression)) | ○ |
|     • [`to_entries`, `from_entries`, `with_entries`](https://stedolan.github.io/jq/manual/v1.5/#to_entries,from_entries,with_entries) | ○ |
|     • [`select(boolean_expression)`](https://stedolan.github.io/jq/manual/v1.5/#select(boolean_expression)) | ○ |
|     • [`arrays`, `objects`, `iterables`, `booleans`, `numbers`, `normals`, `finites`, `strings`, `nulls`, `values`, `scalars`](https://stedolan.github.io/jq/manual/v1.5/#arrays,objects,iterables,booleans,numbers,normals,finites,strings,nulls,values,scalars) | ○ |
|     • [`empty`](https://stedolan.github.io/jq/manual/v1.5/#empty) | ○ |
|     • [`error(message)`](https://stedolan.github.io/jq/manual/v1.5/#error(message)) | ○ |
|     • [`$__loc__`](https://stedolan.github.io/jq/manual/v1.5/#$__loc__) | × |
|     • [`map(x)`, `map_values(x)`](https://stedolan.github.io/jq/manual/v1.5/#map(x),map_values(x)) | ○ |
|     • [`paths`, `paths(node_filter)`, `leaf_paths`](https://stedolan.github.io/jq/manual/v1.5/#paths,paths(node_filter),leaf_paths) | ○ |
|     • [`add`](https://stedolan.github.io/jq/manual/v1.5/#add) | ○ |
|     • [`any`, `any(condition)`, `any(generator; condition)`](https://stedolan.github.io/jq/manual/v1.5/#any,any(condition),any(generator;condition)) | ○ |
|     • [`all`, `all(condition)`, `all(generator; condition)`](https://stedolan.github.io/jq/manual/v1.5/#all,all(condition),all(generator;condition)) | ○ |
|     • [`flatten`, `flatten(depth)`](https://stedolan.github.io/jq/manual/v1.5/#flatten,flatten(depth)) | ○ |
|     • [`range(upto)`, `range(from;upto)` `range(from;upto;by)`](https://stedolan.github.io/jq/manual/v1.5/#range(upto),range(from;upto)range(from;upto;by)) | ○ |
|     • [`floor`](https://stedolan.github.io/jq/manual/v1.5/#floor) | ○ |
|     • [`sqrt`](https://stedolan.github.io/jq/manual/v1.5/#sqrt) | ○ |
|     • [`tonumber`](https://stedolan.github.io/jq/manual/v1.5/#tonumber) | ○ |
|     • [`tostring`](https://stedolan.github.io/jq/manual/v1.5/#tostring) | ○ |
|     • [`type`](https://stedolan.github.io/jq/manual/v1.5/#type) | ○ |
|     • [`infinite`, `nan`, `isinfinite`, `isnan`, `isfinite`, `isnormal`](https://stedolan.github.io/jq/manual/v1.5/#infinite,nan,isinfinite,isnan,isfinite,isnormal) | ○ |
|     • [`sort, sort_by(path_expression)`](https://stedolan.github.io/jq/manual/v1.5/#sort,sort_by(path_expression)) | ○ |
|     • [`group_by(path_expression)`](https://stedolan.github.io/jq/manual/v1.5/#group_by(path_expression)) | ○ |
|     • [`min`, `max`, `min_by(path_exp)`, `max_by(path_exp)`](https://stedolan.github.io/jq/manual/v1.5/#min,max,min_by(path_exp),max_by(path_exp)) | ○ |
|     • [`unique`, `unique_by(path_exp)`](https://stedolan.github.io/jq/manual/v1.5/#unique,unique_by(path_exp)) | ○ |
|     • [`reverse`](https://stedolan.github.io/jq/manual/v1.5/#reverse) | ○ |
|     • [`contains(element)`](https://stedolan.github.io/jq/manual/v1.5/#contains(element)) | ○ |
|     • [`indices(s)`](https://stedolan.github.io/jq/manual/v1.5/#indices(s)) | ○*9 |
|     • [`index(s)`, `rindex(s)`](https://stedolan.github.io/jq/manual/v1.5/#index(s),rindex(s)) | ○ |
|     • [`inside`](https://stedolan.github.io/jq/manual/v1.5/#inside) | ○ |
|     • [`startswith(str)`](https://stedolan.github.io/jq/manual/v1.5/#startswith(str)) | ○ |
|     • [`endswith(str)`](https://stedolan.github.io/jq/manual/v1.5/#endswith(str)) | ○ |
|     • [`combinations`, `combinations(n)`](https://stedolan.github.io/jq/manual/v1.5/#combinations,combinations(n)) | ○ |
|     • [`ltrimstr(str)`](https://stedolan.github.io/jq/manual/v1.5/#ltrimstr(str)) | ○ |
|     • [`rtrimstr(str)`](https://stedolan.github.io/jq/manual/v1.5/#rtrimstr(str)) | ○ |
|     • [`explode`](https://stedolan.github.io/jq/manual/v1.5/#explode) | ○ |
|     • [`implode`](https://stedolan.github.io/jq/manual/v1.5/#implode) | ○ |
|     • [`split`](https://stedolan.github.io/jq/manual/v1.5/#split) | ○ |
|     • [`join(str)`](https://stedolan.github.io/jq/manual/v1.5/#join(str)) | ○ |
|     • [`ascii_downcase`, `ascii_upcase`](https://stedolan.github.io/jq/manual/v1.5/#ascii_downcase,ascii_upcase) | ○ |
|     • [`while(cond; update)`](https://stedolan.github.io/jq/manual/v1.5/#while(cond;update)) | ○ |
|     • [`until(cond; next)`](https://stedolan.github.io/jq/manual/v1.5/#until(cond;next)) | ○ |
|     • [`recurse(f)`, `recurse`, `recurse(f; condition)`, `recurse_down`](https://stedolan.github.io/jq/manual/v1.5/#recurse(f),recurse,recurse(f;condition),recurse_down) | ○ |
|     • [`..`](https://stedolan.github.io/jq/manual/v1.5/#..) | ○ |
|     • [`env`](https://stedolan.github.io/jq/manual/v1.5/#env) | ○*6 |
|     • [`transpose`](https://stedolan.github.io/jq/manual/v1.5/#transpose) | ○ |
|     • [`bsearch(x)`](https://stedolan.github.io/jq/manual/v1.5/#bsearch(x)) | × |
|     • [String interpolation - `\(foo)`](https://stedolan.github.io/jq/manual/v1.5/#Stringinterpolation-\(foo)) | ○ |
|     • [Convert to/from JSON](https://stedolan.github.io/jq/manual/v1.5/#Convertto/fromJSON) | ○ |
|     • [Format strings and escaping](https://stedolan.github.io/jq/manual/v1.5/#Formatstringsandescaping) | ○ |
|     • [Dates](https://stedolan.github.io/jq/manual/v1.5/#Dates) | × |
| [Conditionals and Comparisons](https://stedolan.github.io/jq/manual/v1.5/#ConditionalsandComparisons) | ○ |
|     • [`==`, `!=`](https://stedolan.github.io/jq/manual/v1.5/#==,!=) | ○ |
|     • [if-then-else](https://stedolan.github.io/jq/manual/v1.5/#if-then-else) | ○ |
|     • [`>, >=, <=, <`](https://stedolan.github.io/jq/manual/v1.5/#>,>=,<=,<) | ○ |
|     • [and/or/not](https://stedolan.github.io/jq/manual/v1.5/#and/or/not) | ○ |
|     • [Alternative operator - `//`](https://stedolan.github.io/jq/manual/v1.5/#Alternativeoperator-//) | ○ |
|     • [try-catch](https://stedolan.github.io/jq/manual/v1.5/#try-catch) | ○*1 |
|     • [Breaking out of control structures](https://stedolan.github.io/jq/manual/v1.5/#Breakingoutofcontrolstructures) | ○*2 |
|     • [`?` operator](https://stedolan.github.io/jq/manual/v1.5/#?operator) | ○ |
| [Regular expressions (PCRE)](https://stedolan.github.io/jq/manual/v1.5/#Regularexpressions(PCRE)) | ○ |
|     • [`test(val)`, `test(regex; flags)`](https://stedolan.github.io/jq/manual/v1.5/#test(val),test(regex;flags)) | ○ |
|     • [`match(val)`, `match(regex; flags)`](https://stedolan.github.io/jq/manual/v1.5/#match(val),match(regex;flags)) | ○ |
|     • [`capture(val)`, `capture(regex; flags)`](https://stedolan.github.io/jq/manual/v1.5/#capture(val),capture(regex;flags)) | ○ |
|     • [`scan(regex)`, `scan(regex; flags)`](https://stedolan.github.io/jq/manual/v1.5/#scan(regex),scan(regex;flags)) | ○ |
|     • [`split(regex; flags)`](https://stedolan.github.io/jq/manual/v1.5/#split(regex;flags)) | ○ |
|     • [`splits(regex)`, `splits(regex; flags)`](https://stedolan.github.io/jq/manual/v1.5/#splits(regex),splits(regex;flags)) | ○ |
|     • [`sub(regex; tostring)` `sub(regex; string; flags)`](https://stedolan.github.io/jq/manual/v1.5/#sub(regex;tostring)sub(regex;string;flags)) | ○ |
|     • [`gsub(regex; string)`, `gsub(regex; string; flags)`](https://stedolan.github.io/jq/manual/v1.5/#gsub(regex;string),gsub(regex;string;flags)) | ○ |
| [Advanced features](https://stedolan.github.io/jq/manual/v1.5/#Advancedfeatures) | ○ |
|     • [Variables](https://stedolan.github.io/jq/manual/v1.5/#Variables) | ○*11 |
|     • [Destructuring Alternative Operator: ?//](https://stedolan.github.io/jq/manual/v1.6/#DestructuringAlternativeOperator:?//) | ✕ (#44) |
|     • [Defining Functions](https://stedolan.github.io/jq/manual/v1.5/#DefiningFunctions) | ○*3 |
|     • [Reduce](https://stedolan.github.io/jq/manual/v1.5/#Reduce) | ○ |
|     • [`limit(n; exp)`](https://stedolan.github.io/jq/manual/v1.5/#limit(n;exp)) | ○ |
|     • [`first(expr)`, `last(expr)`, `nth(n; expr)`](https://stedolan.github.io/jq/manual/v1.5/#first(expr),last(expr),nth(n;expr)) | ○ |
|     • [`first`, `last`, `nth(n)`](https://stedolan.github.io/jq/manual/v1.5/#first,last,nth(n)) | ○ |
|     • [`foreach`](https://stedolan.github.io/jq/manual/v1.5/#foreach) | ○ |
|     • [Recursion](https://stedolan.github.io/jq/manual/v1.5/#Recursion) | ○ |
|     • [Generators and iterators](https://stedolan.github.io/jq/manual/v1.5/#Generatorsanditerators) | ○ |
| [Math](https://stedolan.github.io/jq/manual/v1.5/#Math) | △ |
| [I/O](https://stedolan.github.io/jq/manual/v1.5/#I/O) | N/A |
|     • [`input`](https://stedolan.github.io/jq/manual/v1.5/#input) | N/A |
|     • [`inputs`](https://stedolan.github.io/jq/manual/v1.5/#inputs) | N/A |
|     • [`debug`](https://stedolan.github.io/jq/manual/v1.5/#debug) | N/A |
|     • [`input_filename`](https://stedolan.github.io/jq/manual/v1.5/#input_filename) | N/A |
|     • [`input_line_number`](https://stedolan.github.io/jq/manual/v1.5/#input_line_number) | N/A |
| [Streaming](https://stedolan.github.io/jq/manual/v1.5/#Streaming) | N/A |
|     • [`truncate_stream(stream_expression)`](https://stedolan.github.io/jq/manual/v1.5/#truncate_stream(stream_expression)) | N/A |
|     • [`fromstream(stream_expression)`](https://stedolan.github.io/jq/manual/v1.5/#fromstream(stream_expression)) | N/A |
|     • [`tostream`](https://stedolan.github.io/jq/manual/v1.5/#tostream) | N/A |
| [Assignment](https://stedolan.github.io/jq/manual/v1.5/#Assignment) | ○ |
|     • [`=`](https://stedolan.github.io/jq/manual/v1.5/#=) | ○ |
|     • [`ǀ=`](https://stedolan.github.io/jq/manual/v1.5/#|=) | ○*8 |
|     • [`+=`, `-=`, `*=`, `/=`, `%=`, `//=`](https://stedolan.github.io/jq/manual/v1.5/#+=,-=,*=,/=,%=,//=) | ○ |
|     • [Complex assignments](https://stedolan.github.io/jq/manual/v1.5/#Complexassignments) | ○ |
| [Modules](https://stedolan.github.io/jq/manual/v1.5/#Modules) | △ |
|     • [`import RelativePathString as NAME [];`](https://stedolan.github.io/jq/manual/v1.5/#importRelativePathStringasNAME[<metadata>];) | ○ |
|     • [`include RelativePathString [];`](https://stedolan.github.io/jq/manual/v1.5/#includeRelativePathString[<metadata>];) | ○ |
|     • [`import RelativePathString as $NAME [];`](https://stedolan.github.io/jq/manual/v1.5/#importRelativePathStringas$NAME[<metadata>];) | ○ |
|     • [`module ;`](https://stedolan.github.io/jq/manual/v1.5/#module<metadata>;) | ○ |
|     • [`modulemeta`](https://stedolan.github.io/jq/manual/v1.5/#modulemeta) | × |

### Known Compatibility Issues / Differences

#### Category: BUG

(*11) Operator Precedences in 1 + 3 as $a | ($a * 2)

##### Description

The presence of `as $a` affects precedence of `|` and other operators in jq:

```console
$ jq -n '1 + 3 | (. * 2)' # interpreted as (1 + 3) | (. * 2)
8
$ jq -n '1 + 3 as $a | ($a * 2)' # interpreted as 1 + (3 as $a | ($a * 2))
7
```

whereas jackson-jq consistently interprets them as `(1 + 3)` whether `as $a` is used or not:

```console
$ java -jar jackson-jq-cli-1.0.0-preview.20240207.jar -n '1 + 3 | (. * 2)' # interpreted as (1 + 3) | (. * 2)
8
$ java -jar jackson-jq-cli-1.0.0-preview.20240207.jar -n '1 + 3 as $a | ($a * 2)' # interpreted as (1 + 3) as $a | ($a * 2)
8
```

##### Examples

```console
$ jq -n '1 + 3 as $a | ($a * 2)' # interpreted as 1 + (3 as $a | ($a * 2))
7
$ java -jar jackson-jq-cli-1.0.0-preview.20240207.jar -n '1 + 3 as $a | ($a * 2)' # interpreted as (1 + 3) as $a | ($a * 2)
8
```

##### Workaround

Use explicit parentheses.

##### Links

* [jackson-jq#72](https://github.com/eiiches/jackson-jq/issues/72)

(*3) Multiple functions with the same name in the same scope

##### Description

If the function with the same is defined more than once at the same scope, jackson-jq uses the last one.

##### Examples

```console
$ jq -n 'def f: 1; def g: f; def f: 2; g'
1
$ java -jar jackson-jq-cli-1.0.0-preview.20240207.jar -n 'def f: 1; def g: f; def f: 2; g'
2
```

##### Workaround

Avoid using the duplicate function name.

```console
$ java -jar jackson-jq-cli-1.0.0-preview.20240207.jar -n 'def f1: 1; def g: f1; def f2: 2; g'
1
```

#### Category: BY DESIGN

(*1) Error Message Wording

##### Description

Error messages differ between jq and jackson-jq and they also tend to change between versions.

##### Workaround

None. This is by design and will not be fixed.

(*6) env/0 is not available by default.

##### Description

`env/0` is not available by default for security reasons and must be added manually to the scope.

##### Workaround

Add `env/0` manually into the scope:

```java
SCOPE.addFunction("env", 0, new EnvFunction())
```

(*4) Field Ordering in JSON Object

##### Description

The order of the keys in JSON is not preserved. It was a design decision but we are slowly trying to fix this in order to improve the compatibility with jq.

##### Workaround

None. Use array if the order is important.

(*5) 0 / 0 is an error in jackson-jq.

##### Description

jq evaluates `0 / 0`, if hard-coded, to NaN without any errors, whereas `0 | 0 / .` results in a zero-division error. jackson-jq always raises an error in both cases.

##### Examples

```console
$ jq -n '0 / 0'
null
$ jq -n '10 / 0'
jq: error: Division by zero? at , line 1:
10 / 0
jq: 1 compile error
$ jq '. / 0' <<< 0
jq: error (at :1): number (0) and number (0) cannot be divided because the divisor is zero
$ java -jar jackson-jq-cli-1.0.0-preview.20240207.jar -n '0 / 0'
jq: error: number (0) and number (0) cannot be divided because the divisor is zero
```

##### Workaround

If you need NaN, use `nan` instead of `0 / 0`.

(*8) ... |= empty is an error in jackson-jq.

##### Description

`.foo |= empty` always throws an error in jackson-jq instead of producing an unexpected result. jq-1.5 and jq-1.6 respectively produces a different and incorrect result for `[1,2,3] | ((.[] | select(. > 1)) |= empty)`. [jq#897](https://github.com/stedolan/jq/issues/897) says "empty in the RHS is undefined". You can still use `_modify/2` directly if you really want to emulate the exact jq-1.5 or jq-1.6 behavior.

##### Examples

```console
$ jq-1.6 -n '[1,2,3] | ((.[] | select(. > 1)) |= empty)'
[
1,
3
]
$ jq-1.5 -n '[1,2,3] | ((.[] | select(. > 1)) |= empty)'
null
$ jq-1.2 -n '[1,2,3] | ((.[] | select(. > 1)) |= empty)'
[
1,
2,
3
]
$ java -jar jackson-jq-cli-1.0.0-preview.20240207.jar --jq 1.6 -n '[1,2,3] | ((.[] | select(. > 1)) |= empty)'
jq: error: `|= empty` is undefined. See https://github.com/stedolan/jq/issues/897
$ java -jar jackson-jq-cli-1.0.0-preview.20240207.jar --jq 1.5 -n '[1,2,3] | ((.[] | select(. > 1)) |= empty)'
jq: error: `|= empty` is undefined. See https://github.com/stedolan/jq/issues/897
```

##### Workaround

You can use `_modify/2` if you really want to the original behavior.

```console
$ java -jar jackson-jq-cli-1.0.0-preview.20240207.jar --jq 1.6 -n '[1,2,3] | _modify((.[] | select(. > 1)); empty)'
[ 1, 3 ]
$ java -jar jackson-jq-cli-1.0.0-preview.20240207.jar --jq 1.5 -n '[1,2,3] | _modify((.[] | select(. > 1)); empty)'
null
```

(*7) Variables don't carry path information even in jq 1.5 compat mode.

##### Description

`path(.foo as $a | $a)` always throws an error as $variables in jackson-jq do not carry path information like jq-1.5 accidentally? did. The behavior is fixed in jq-1.6 whose [documentation](https://stedolan.github.io/jq/manual/v1.6/#Assignment) explicitly states them as "not a valid or useful path expression". So, I dicided not to implement it even in jq-1.5 compatible mode.

##### Examples

jq 1.5

```console
$ jq-1.5 -c 'path(.foo as $a | $a)' <<< '{"foo": 1}'
["foo"]
$ java -jar jackson-jq-cli-1.0.0-preview.20240207.jar --jq 1.5 -c 'path(.foo as $a | $a)' <<< '{"foo": 1}'
jq: error: Invalid path expression with result 1
```

jq 1.6

```console
$ jq-1.6 -c 'path(.foo as $a | $a)' <<< '{"foo": 1}'
jq: error (at :1): Invalid path expression with result 1
$ java -jar jackson-jq-cli-1.0.0-preview.20240207.jar --jq 1.6 -c 'path(.foo as $a | $a)' <<< '{"foo": 1}'
jq: error: Invalid path expression with result 1
```

##### Workaround

None

(*2) try (break $label) catch . always produces {"__jq": 0}.

##### Description

try (break $label) catch . always produces {"__jq": 0} in jackson-jq, while `__jq` should contain the index of the label the `break` statement jumps to.

##### Examples

```console
$ jq -n 'label $a | label $b | try (break $b) catch .'
{
"__jq": 1
}
$ java -jar jackson-jq-cli-1.0.0-preview.20240207.jar -n 'label $a | label $b | try (break $b) catch .'
{
"__jq" : 0
}
```

##### Workaround

None. Tell us your use case if you need this feature.

#### Category: BUGFIX

(*9) indices("") returns [] (empty array) in jackson-jq.

##### Description

`indices/1` implementation in jq-1.5 and jq-1.6 had a bug that caused `indices("")` to end up in infinite loop which eventually leads to OOM. The bug is [fixed](https://github.com/stedolan/jq/commit/2660b04a731568c54eb4b91fe811d81cbbf3470b) and likely to be in jq-1.7 (not released yet). jackson-jq chose not to simulate this bug.

##### Examples

```console
$ jq-1.5 -n '"x" | indices("")' # stuck in infinite loop
^C
$ jq-1.6 -n '"x" | indices("")' # stuck in infinite loop
^C
$ jq-1.6-83-gb52fc10 -n '"x" | indices("")'
[]
$ java -jar jackson-jq-cli-1.0.0-preview.20240207.jar -n '"x" | indices("")'
[ ]
```

Using jackson-jq/extras module
------------------------------

The `jackson-jq/extras` module is a jq module that provides some useful functions that do not exist in jq.

To use this module, you need to add the following Maven dependency and set `BuiltinModuleLoader` (see [jackson-jq/src/test/java/examples/Usage.java](jackson-jq/src/test/java/examples/Usage.java)) to the scope.

```xml

net.thisptr
jackson-jq-extra
1.0.0-preview.20240207

```

Now, you can import the module in jq:

```jq
import "jackson-jq/extras" as extras;

extras::uuid4
```

For a historical reason, adding the Maven dependency also makes the functions directly available to jq. This behavior is deprecated and will be removed at some point in the future.

List of Functions

#### uuid4/0

- `jackson-jq -n 'uuid4'` #=> `"a69cf146-f40e-42e1-ae88-12590bdae947"`

#### random/0

- `jackson-jq -n 'random'` #=> `0.43292159535427466`

#### timestamp/0, strptime/{1, 2}, strftime/{1, 2}

- `jackson-jq -n 'timestamp'` #=> `1477162056362`
- `jackson-jq -n '1477162342372 | strftime("yyyy-MM-dd HH:mm:ss.SSSXXX")'` #=> `"2016-10-23 03:52:22.372+09:00"`
- `jackson-jq -n '1477162342372 | strftime("yyyy-MM-dd HH:mm:ss.SSSXXX"; "UTC")'` #=> `"2016-10-22 18:52:22.372Z"`
- `jackson-jq -n '"2016-10-23 03:52:22.372+09:00" | strptime("yyyy-MM-dd HH:mm:ss.SSSXXX")'` #=> `1477162342372`
- `jackson-jq -n '"2016-10-22 18:52:22.372" | strptime("yyyy-MM-dd HH:mm:ss.SSS"; "UTC")'` #=> `1477162342372`

#### uriparse/0

- `jackson-jq -n '"http://[email protected]:8080/index.html?foo=1&bar=%20#hash" | uriparse'` #=>

```json
{
"scheme" : "http",
"user_info" : "user",
"raw_user_info" : "user",
"host" : "www.example.com",
"port" : 8080,
"authority" : "[email protected]:8080",
"raw_authority" : "[email protected]:8080",
"path" : "/index.html",
"raw_path" : "/index.html",
"query" : "foo=1&bar= ",
"raw_query" : "foo=1&bar=%20",
"query_obj" : {
"bar" : " ",
"foo" : "1"
},
"fragment" : "hash",
"raw_fragment" : "hash"
}
```

#### uridecode/0

- `jackson-jq -n '"%66%6f%6f" | uridecode'` #=> `"foo"`

#### hostname/0

- `jackson-jq -n 'hostname'` #=> `"jenkins-slave01"`

Contributing
------------

* If you are planning to send a PR and the change is not small, please open an issue and discuss it with the authors first.
* Other than bug reports or patches, documentation improvements (including small grammatical or wording corrections) would be greatly appreciated.

License
-------

This software is licensed under Apache Software License, Version 2.0, with some exceptions:

- [jackson-jq/src/test/resources](jackson-jq/src/test/resources) contains test cases from [stedolan/jq](https://github.com/stedolan/jq).
- [jackson-jq/src/main/resources/net/thisptr/jackson/jq/jq.json](jackson-jq/src/main/resources/net/thisptr/jackson/jq/jq.json) contains function definitions extracted from [stedolan/jq](https://github.com/stedolan/jq).

See [COPYING](COPYING) for details.