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

jq 1.6 different (incorrect?) behavior for tonumber? // tostring compared to jq 1.5 #1885

Closed
evantorrie opened this issue Apr 11, 2019 · 9 comments · Fixed by #2750
Closed
Labels

Comments

@evantorrie
Copy link

Describe the bug
jq-1.6 behaves differently (and as I read the manual, incorrectly) when running map_values with a filter which includes an alternate //.

To Reproduce

% jq-1.5 'map_values( tonumber? // tostring)' <<< '{"fish": "food", "account": "1234"}'
{
  "fish": "food",
  "account": 1234
}
% jq-1.6 'map_values( tonumber? // tostring)' <<< '{"fish": "food", "account": "1234"}'
{
  "fish": "food"
}

Expected behavior
Expected jq-1.5 output to appear in both cases

Environment (please complete the following information):

  • MacOS Mojave
  • jq version 1.5.3 and 1.6 (poured from homebrew bottles)
@nicowilliams
Copy link
Contributor

Thanks for the report!

@nicowilliams
Copy link
Contributor

Oddly this is fixed in my dlopen branch...

@pkoppstein
Copy link
Contributor

Note that the problem seems to have nothing to do with // and everything to do with ?:

$ jq-1.6 'map_values( tostring?)' <<< '{"fish": null, "account": "1234"}'
{}

@nicowilliams
Copy link
Contributor

@pkoppstein yes, it's probably another manifestation of #1859.

@Alanscut
Copy link
Contributor

hi , @nicowilliams
I tested your branch “dlopen” , but the output is wrong

jq 'map_values( tonumber? // tostring)' <<< '{"fish": "food", "account": "1234"}'

result:
{
  "__jq": 1,
  "__jqv": 1877772117465177
}

This situation is also handled incorrectly, so This bug may not have been fixed perfectly

 echo ['1'] | jq  'map_values(tonumber)'
{
  "__jq": 0,
  "__jqv": 1514811160447560
}

@nicowilliams
Copy link
Contributor

@Alanscut it's fixed in my dlopen branch now, and there are tests for #1859 in it.

@Alanscut
Copy link
Contributor

Alanscut commented Jan 2, 2020

@nicowilliams Thanks for your work,The result of the current dlopen branch is correct.

@nicowilliams
Copy link
Contributor

@Alanscut thank you for testing it!

@benaryorg
Copy link

Any chance of getting a fix for this released as this is breaking behaviour for jq-1.6?

nicowilliams added a commit to nicowilliams/jq that referenced this issue Jul 24, 2023
Close jqlang#1885, jqlang#2140, jqlang#2011, jqlang#2220, jqlang#2485, 2073

Rename the FORK_OPT opcode to TRY_BEGIN, add a TRY_END opcode, and wrap
errors when raising through a TRY_END so that they will not be caught by
the matching TRY_BEGIN.

Now a `try exp catch handler` expression generates code like:

    TRY_BEGIN handler
    <exp>
    TRY_END
    JUMP past_handler
    handler: <handler>
    past_handler:
    ...

On backtrack through TRY_BEGIN it just backtracks.

If anything past the whole thing raises when <exp> produced a value,
then the TRY_END will catch the error, wrap it in another, and
backtrack.  The TRY_BEGIN will see a wrapped error and then it will
unwrap and re-raise the error.

If <exp> raises, then TRY_BEGIN will catch the error and jump to the
handler, but the TRY_BEGIN will not stack_save() in that case, so on
raise/backtrack the TRY_BEGIN will not execute again (nor will the
TRY_END).
emanuele6 pushed a commit that referenced this issue Jul 24, 2023
Close #1885, #2140, #2011, #2220, #2485, #2073

Rename the FORK_OPT opcode to TRY_BEGIN, add a TRY_END opcode, and wrap
errors when raising through a TRY_END so that they will not be caught by
the matching TRY_BEGIN.

Now a `try exp catch handler` expression generates code like:

    TRY_BEGIN handler
    <exp>
    TRY_END
    JUMP past_handler
    handler: <handler>
    past_handler:
    ...

On backtrack through TRY_BEGIN it just backtracks.

If anything past the whole thing raises when <exp> produced a value,
then the TRY_END will catch the error, wrap it in another, and
backtrack.  The TRY_BEGIN will see a wrapped error and then it will
unwrap and re-raise the error.

If <exp> raises, then TRY_BEGIN will catch the error and jump to the
handler, but the TRY_BEGIN will not stack_save() in that case, so on
raise/backtrack the TRY_BEGIN will not execute again (nor will the
TRY_END).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants