01mf02 / jaq

A jq clone focussed on correctness, speed, and simplicity
MIT License
2.61k stars 63 forks source link

Nesting index where parent is not found returns `Error: cannot use null as iterable (array or object)` #160

Closed mohan-tenovos closed 3 months ago

mohan-tenovos commented 5 months ago

Where the index is two levels deep and the parent is not found jaq returns cannot use null as iterable (array or object), this behavior is different to jq.

e.g.

echo '{ "name": "John" }' | jaq -n '{ "firstName": "John", "lastName": .foo.bar }' or echo '{ "name": "John" }' | jaq -n '{ "firstName": "John", "lastName": .foo?.bar }'

I assume I'm missing something obvious....

wader commented 5 months ago

Hi, not sure if related to the error but you probably don't want -n in this case? (ignore input and use null instead).

My guess is this boils down to that jq allows indexing of null which returns null, ex:

$ jq -n '.a, .[1], .a.b.c.d, .a[1].b'
null
null
null
null

Don't know if it's intentional that jaq throw error instead.

mohan-tenovos commented 5 months ago

Unfortunately, the behavior is the same:

echo '{ "name": "John" }' | jaq '{ "firstName": .name, "lastName": .foo.bar }'
Error: cannot use null as iterable (array or object)

The expected result (as per jq):

echo '{ "name": "John" }' | jq '{ "firstName": .name, "lastName": .foo.bar }'
{
  "firstName": "John",
  "lastName": null
}
wader commented 5 months ago

Yeap. As a workaround you can maybe do something like:

$ echo '{"a": {"b": 2}}' | jaq -c '{"c": (.a.b)? // null}'
{"c":2}
$ echo '{}' | jaq -c '{"c": (.a.b)? // null}'
{"c":null}

But maybe should be careful and only do indexing inside (...)? to not catch other errors.

01mf02 commented 3 months ago

I would also go with @wader's approach. To prevent future confusion, I added a little note in a83e980e7f011a82a162b07433587e45ae5c376c.