GH-50627: [C++] Migrate from_string.cc to simdjson - #50653
Conversation
|
Thanks for working on this! This part of the migration ( |
|
Putting into |
Yes, I think it's fine. |
| } | ||
|
|
||
| template <typename SimdjsonValueType> | ||
| Result<SimdjsonValueType> GetAs(sj::value& value) { |
| return "string"; | ||
| } else if constexpr (std::is_same_v<SimdjsonClass, bool>) { | ||
| return "boolean"; | ||
| } else if constexpr (std::is_same_v<SimdjsonClass, std::monostate>) { |
There was a problem hiding this comment.
std::monostate
We probably want to add a typedef for this (if we want to keep this at all?). Alternatively, we could check the null case also always by hand
| }; | ||
|
|
||
| // Use fold expression to process all handlers in order | ||
| (process_one(std::forward<Handlers>(handlers)) && ...); |
There was a problem hiding this comment.
Note that Status supports the & operator, which might allow simplifying this a bit.
There was a problem hiding this comment.
I did now use it, but am unsure about readability improvements. Is this what you meant?
It made the body a bit cleaner, but it is now more difficult to reason about the error message, but maybe that is just me ^^
There was a problem hiding this comment.
Yes, that's what I had in mind. I understand what you mean with "difficult to reason about the error message", but normally the first should be kept :)
|
Hmm, this CI error looks related: https://github.com/apache/arrow/actions/runs/30342146109/job/90219928526?pr=50653 (perhaps my suggestion re |
| return "string"; | ||
| } else if constexpr (std::is_same_v<SimdjsonClass, bool>) { | ||
| return "boolean"; | ||
| } else if constexpr (std::is_same_v<SimdjsonClass, std::monostate>) { |
There was a problem hiding this comment.
Is std::monostate somehow imposed by simdjson? Otherwise can we use something more distinctive?
There was a problem hiding this comment.
Yes, I replaced it with a custom empty class
| template <typename> | ||
| inline constexpr bool kAlwaysFalse = false; |
There was a problem hiding this comment.
Doesn't seem used, which errors out on some compilers (see CI :-)).
There was a problem hiding this comment.
I see. Was able to replace with static_assert(false,..) inline. Not sure why this produced an error for me before. Might had missed a constexpr in one of the elif branches and thought this indirection was necessary
There was a problem hiding this comment.
I see in the CI run that the way I solved it is indeed not portable:
/Users/runner/work/arrow/arrow/cpp/src/arrow/json/from_string.cc:109:5: error: static assertion failed: unmapped simdjson value type
static_assert(false, "unmapped simdjson value type");
^ ~~~~~
Yes, it is related. Nono, the mistake was on my part. But yes, consuming more elements from the iterator after an error is UB in simdjson. Sloppy by me, sorry. I refactored it and found a much cleaner solution to only template the |
Rationale for this change
This is part of the work for #35460. Back in January I started working on this change-set, but after discussions came up regarding the use of the
simdjson::domvssimdjson::ondemandfront-end the development went stale. I saw that @Reranko05 started the work on #35460 and already made great progress, well done!I still wanted to put up this change-set as a possible view-point, but feel free to disregard @Reranko05 if you already started your own work.
What changes are included in this PR?
This changes
from_string.ccto use simdjson instead of RapidJSON.Are there any user-facing changes?
Yes, the API has changed to no longer allow non-utf8 compatible strings.
simdjsondoes not support non-compliant inputs and does not intent to support it in the future [1] [2] [3]All call-sites in tests only used a transformation to non-utf8 json as an intermediate result to easily go from
string -> Array, so I changed these to use different helper methods instead.Another difficult problem arises in the handling of
NaNandInfliterals in inputs.simdjsonfollows the json standard, whereasRapidJSONimplemented an extension where the following is a valid input:We need to decide whether to be breaking here or not. This PR now contains a non-breaking version of the change. This can be quite elegantly added by using the public
ondemandapi's function to retrieve the raw token string in theConvertNumberfunction.Alternatively, we can wait for the next
simdjsonmajor release, which will ship with support for aSIMDJSON_ENABLE_NAN_INFcompilation flag as per this pull request. (this was only merged to simdjson main)Are these changes tested?
Yes
simdjsoninfrom_string.ccand tests #50627