-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Add new builtin fetch
#1738
Add new builtin fetch
#1738
Conversation
Most people, I think, would agree that
should emit Perhaps the following achieves the semantics you have in mind:
However this is evidently very inefficient, so perhaps a C implementation is warranted. It would probably be wise, though, to agree on the semantics before getting too deep into implementation details. For example, what should |
Ah, yes. Great edge cases! I think if we're following the pattern of the Ruby implemention, we should pass falsey and null values through if they are being set on the key value (as we can see happening in Ruby here http://rubyfiddle.com/riddles/71c57/2 ). Also, to answer your other question about deeper nesting of the key that is being fetched, maybe we should take cue from Ruby and require a string of just a single key and use For example:
|
What about logic (untested, just off the top of my head) like:
|
@bbbco - For
Example:
|
Thanks for the suggestion @pkoppstein ! I've incorporated your code, slightly tweaked so that the default can also refer to a path expression as well. I've also added a few more tests to the tests and docs. |
|
Huh. You're right. I could have sworn it wasn't working right without that. Anyways, I've updated, added a test to ensure it passes through null values, and squashed the commits into one tidy one. |
The def using Here's one way to have our cake and eat it:
|
The problem with this approach can be seen in the following examples:
and
|
Revised, but probably still needs more work. |
Thanks @pkoppstein . I can confirm that this works as expected now. Also, I can confirm that this algorithm is more performant. Here are the performance benchmarks I ran based on the citylots.json file from https://github.com/tidwall/sf-city-lots-json . Baseline:
First algorithm from #1738 (comment)
Second algorithm from #1738 (comment)
Seems like your latest iteration is certainly better performant. Updated algorithm incoming along with extra tests. |
[EDIT: The following implementation has been revised.] The following version of
|
This version does not pass through null values:
(returns empty) Here's the performance benchmarks:
Hmm... so seems like this implementation is slightly better when run I'm not as familiar with working with lower level C. Do you have suggestions for a lower level C implementation? Or are you going to be ok with accepting one of these implementations for the time being? |
Yes, the bug has been fixed.
I am not a Decider. Also, please be aware that the current Deciders do not want to add new defs to builtin.jq until a major overhaul of the mechanism for handling such defs has been completed (which to judge from recent lack of progress, may be quite a while). However, working on a "library" function is, in my opinion, worthwhile, both for those who may want to use it, and also to get a better handle on semantic issues. |
Thanks for fixing the bug. Looks good as far as tests passing now. Here's the updated benchmarks:
|
We had config machinery that determined which math functions are available in libc. If a c math function was missing on the host system, then the corresponding jq function would be removed from the source, enabling the build to proceed anyway. The detection machinery was broken in a subtle way, as was shown after glibc updated to 2.27, dropping the `pow10` function. This caused compilation to fail. The essential problem was that we detected whether a math function was available by compiling and linking a small program evaluating that function on constants. However, since gcc's optimization machinery has special knowledge of some math functions (e.g. `pow10`), it can optimize them away, even if they don't exist in the library and are not linkable. That is, the following example compiles and links against glibc 2.27, even though `pow10` has been removed: ``` int main () { printf("%f", pow10(0.5)); return 0; } ``` What?! On the other hand, this program does not link: ``` int main () { double f; printf("%f", &f); printf("%f", pow10(f)); return 0; } ``` In the first program the call to `pow10` can be optimized away as a constant expression. This requires GCC to know about `pow10` (which it does!), but it does not require `pow10` to be in the library (and actually linkable). The solution is to use autoconf's machinery for detecting function presence, instead of our own (buggy) machinery. This has the added benefit of simplifying the code. The bug was reported in issue jqlang#1659
Closing request. Seems that @pkoppstein decided to implement as |
I added a new builtin called
fetch
, which allows you to specify a key and returns the value or nothing (or another default you define). This is similar to the Ruby#fetch
method on Hash-like objects.I've added tests and docs for this new builtin, and running
make check
passes.