yq
yq copied to clipboard
Value operator can replace empty stream with single value
Split from #1515
The value operator (when a value is used as a constant-valued function, like . | "foo"
) should replace each value in its input stream with the given value, producing an output stream of the same length as the input. However, when given an empty input stream (what jq calls empty
), instead of producing an empty output stream, they instead produce an output stream with one copy of the given value.
This breaks some intuitive invariants, like that for any array arr
and operator f
, that (arr | map(f) | length) == (arr | length)
, since map(f)
≡ [.[] | f]
. This is how I found it in the first place; I was surprised when extra empty values appeared deep in a query after a map operation.
- Version of yq: tested with 4.30.8 (unexpected behavior) and 3.1.0 (expected behavior)
- Operating system: tested on macOS and Linux
- Installed via: built from source
Input Yaml
data1.yml
:
[]
Command
yq eval '.[] | "foo"' data1.yml
Actual behavior
The empty stream is replaced with a value:
foo
Expected behavior
The empty stream is mapped over, producing an empty output stream:
Additional context
Expected behavior is present in yq 3 (try yq -n '[] | .[] | "foo"'
) and jq (try jq -n 'empty | "foo"'
). Note that in #1515, arrays and objects used as value operators had the expected behavior with multi-valued streams; with empty streams, however, they have the same unexpected behavior (replacing empty streams with a single value) as other values.