Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parameterized nested field reference inside User Op #4658

Closed
philrz opened this issue Jun 15, 2023 · 1 comment · Fixed by #4663
Closed

Parameterized nested field reference inside User Op #4658

philrz opened this issue Jun 15, 2023 · 1 comment · Fixed by #4663
Assignees

Comments

@philrz
Copy link
Contributor

philrz commented Jun 15, 2023

Repro is with Zed commit 2314053.

Let's start from this very simple example of outputting the value from a field in an embedded record.

$ zq -version
Version: v1.8.1-28-g23140538

$ echo '{foo: {bar: "baz"}}' | zq -Z 'yield foo.bar' -
"baz"

If we want to do the same when this is passed into a User Op, it's easy enough if we always know the precise field path and can express it in dotted notation or with indexing.

$ cat yield-in-op-1.zed 
op CallMe(...): (
  yield {dotted: foo.bar, indexed: this["foo"]["bar"]}
)
CallMe(this)

$ echo '{foo: {bar: "baz"}}' | zq -Z -I yield-in-op-1.zed -
{
    dotted: "baz",
    indexed: "baz"
}

However, we expect users will want to write User Ops when the field name/path is not known in advance and it's passed in from the main scope as a parameter. This currently works fine with a top-level field reference.

$ cat yield-in-op-2.zed 
op CallMe(..., const f): (
  yield this[f]
)
CallMe(this, "foo")

$ echo '{foo: {bar: "baz"}}' | zq -Z -I yield-in-op-2.zed -
{
    bar: "baz"
}

However, there's not currently a way to reference a nested field path this way. For instance, if I was a user hacking away, I might attempt:

$ cat yield-in-op-3.zed 
op CallMe(..., const f): (
  yield this[f]
)
CallMe(this, ["foo"]["bar"])

$ echo '{foo: {bar: "baz"}}' | zq -Z -I yield-in-op-3.zed -
zq: error parsing Zed in yield-in-op-3.zed at line 4, column 21:
CallMe(this, ["foo"]["bar"])
                === ^ ===

We've discussed as a team implementing an approach to this using "first class paths".

@philrz
Copy link
Contributor Author

philrz commented Jun 22, 2023

Verified in Zed commit e57e90e.

With the changes in the linked PR #4663, I can now pass in a dotted reference to a nested field or use field referencing with indexing to retrieve a field's value from inside the user op. Updating the repro steps to align with the revised syntax, we now see:

$ zq -version
Version: v1.8.1-37-ge57e90ee

$ cat yield-in-op-revised.zed
op CallMe(f): (
  yield f
)

$ echo '{foo: {bar: "baz"}}' | zq -Z -I yield-in-op-revised.zed 'CallMe(foo.bar)' -
"baz"

$ echo '{foo: {bar: "baz"}}' | zq -Z -I yield-in-op-revised.zed 'CallMe(this["foo"]["bar"])' -
"baz"

Thanks @mattnibs!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants