pitrou commented on code in PR #51038:
URL: https://github.com/apache/arrow/pull/51038#discussion_r4183166892


##########
cpp/src/arrow/json/parser.cc:
##########
@@ -762,102 +744,205 @@ class HandlerBase : public BlockParser,
   }
 
  protected:
-  template <typename Handler, typename Stream>
-  Status DoParse(Handler& handler, Stream&& json, size_t json_size) {
-    constexpr auto parse_flags = rj::kParseIterativeFlag | 
rj::kParseNanAndInfFlag |
-                                 rj::kParseStopWhenDoneFlag |
-                                 rj::kParseNumbersAsStringsFlag;
-
-    rj::Reader reader;
-    // ensure that the loop can exit when the block too large.
-    for (; num_rows_ < std::numeric_limits<int32_t>::max(); ++num_rows_) {
-      auto ok = reader.Parse<parse_flags>(json, handler);
-      switch (ok.Code()) {
-        case rj::kParseErrorNone:
-          // parse the next object
-          continue;
-        case rj::kParseErrorDocumentEmpty:
-          if (json.Tell() < json_size) {
-            return ParseError(rj::GetParseError_En(ok.Code()));
-          }
-          // parsed all objects, finish
-          return Status::OK();
-        case rj::kParseErrorTermination:
-          // handler emitted an error
-          return handler.Error();
-        default:
-          // rj emitted an error
-          return ParseError(rj::GetParseError_En(ok.Code()), " in row ", 
num_rows_);
+  Status Parse(const std::shared_ptr<Buffer>& json) override {
+    RETURN_NOT_OK(ReserveScalarStorage(json->size()));
+
+    const std::string_view input(reinterpret_cast<const char*>(json->data()),
+                                 json->size());
+
+    const int64_t input_size = input.size();
+    if (internal::ConsumeJsonWhitespace(input, /*trailing=*/false) == 
input_size) {
+      return Status::OK();
+    }
+
+    auto parse = [&](const auto& input) -> Status {
+      ARROW_ASSIGN_OR_RAISE(auto stream, 
arrow::internal::ResolveSimdjsonResult(
+                                             parser_.iterate_many(input),
+                                             "Failed to create JSON document 
stream"));
+
+      for (auto document_result : stream) {
+        ARROW_ASSIGN_OR_RAISE(
+            auto document,
+            arrow::internal::ResolveSimdjsonResult(
+                document_result, "Failed to iterate JSON document stream"));
+
+        if (num_rows_ == std::numeric_limits<int32_t>::max()) {
+          return Status::Invalid("Row count overflowed int32_t");
+        }
+
+        ARROW_ASSIGN_OR_RAISE(
+            auto value,
+            arrow::internal::ResolveSimdjsonResult(
+                document.get_value(), "JSON parse error: Failed to get JSON 
value"));
+
+        RETURN_NOT_OK(ParseValue(value));
+
+        ++num_rows_;
       }
+
+      if (stream.truncated_bytes() != 0) {
+        return ParseError("JSON document was truncated");
+      }

Review Comment:
   > I think the distinction from the chunker is that the chunker only needs to 
identify complete document boundaries and can leave a partial trailing document 
for the next chunk, whereas the parser needs to validate that the entire input 
is complete.
   
   I think you're right indeed.
   
   > For now, I think we can keep the ConsumeJsonWhitespace() check to avoid 
calling truncated_bytes() on empty input, and remove that check once Arrow 
bumps to simdjson v5.0.2.
   
   Sounds ok to me!



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to