zed
zed copied to clipboard
Complex value search fails unless inner value types match precisely
Repro is with Zed commit f497079.
Start from these working examples of searching for a primitive value in a named field of a record. All three of these work regardless of whether the value port
in the input record is of the undecorated numeric type int64
, decorated to a non-default numeric type such as uint16
, or a named field that points to a non-default numeric type.
$ zq -version
Version: v1.16.0-6-gf4970799
$ echo '{port: 53}' | zq -z 'search port==53' -
{port:53}
$ echo '{port: 53 (uint16)}' | zq -z 'search port==53' -
{port:53(uint16)}
$ echo '{port: 53 (port=uint16)}' | zq -z 'search port==53' -
{port:53(port=uint16)}
However, things become inconsistent when I start searching for a complex constant value that happens to include these. #2424 shows an example of where this can work, e.g.:
$ echo '{server:{addr: 10.0.0.100, port: 53}}' | zq -z 'server=={addr: 10.0.0.100, port: 53}' -
{server:{addr:10.0.0.100,port:53}}
However, it's no longer a match once the inner port
value is decorated to indicate it's a uint16
.
$ echo '{server:{addr: 10.0.0.100, port: 53 (uint16)}}' | zq -z 'server=={addr: 10.0.0.100, port: 53}' -
[no output]
I can force it to work if I cast the value in my search term.
$ echo '{server:{addr: 10.0.0.100, port: 53 (uint16)}}' | zq -z 'server=={addr: 10.0.0.100, port: uint16(53)}' -
{server:{addr:10.0.0.100,port:53(uint16)}}
But it breaks down yet again if it's a named type in the original data.
$ echo '{server:{addr: 10.0.0.100, port: 53 (port=uint16)}}' | zq -z 'server=={addr: 10.0.0.100, port: uint16(53)}' -
[no output]
And finally, I can force it one more time if cast()
to the specific named type.
$ echo '{server:{addr: 10.0.0.100, port: 53 (port=uint16)}}' | zq -z 'server=={addr: 10.0.0.100, port: cast(53, <port>)}' -
{server:{addr:10.0.0.100,port:53(port=uint16)}}
Ultimately though, what I expected was something like the first examples where search port==53
matched in all three cases, i.e., I'd been hoping to see matches in all these searches for complex values as long as the underlying values of the inner elements would have matched in a search as primitive values. If a user wanted the kind of "strict equality" including precise types/names that I've shown here, I'd expect there to maybe be a different operator for that, e.g., like ===
in JavaScript, though I don't believe I've heard any user demand for that yet in Zed.
Zui Context
Here's some wider context of where this topic came up recently. In the Zui app, the "right click" features Filter == Value will append the current Zed pipeline with the filtering logic to isolate the value clicked, e.g., ts==2020-02-25T16:03:13.978298Z
if the user right-clicks on that ts
value in a displayed query result. However, this has traditionally only worked for primitive, top-level fields. @jameskerr recently looked into adding a right-click option for complex values, e.g., the id
fields in Zeek records that contain a 4-tuple of source/dest IP/port. However, the port values in the Zeek data that many of our users still rely on happen to be named types that point to uint16
, and other users surely also rely heavily on named types (e.g., our community zync users with their Kafka data extensively use them). So to implement the feature with what's there today, it seems @jameskerr would have to do something like:
This feels awkward.