#pragma once #include #include #include namespace DB { class ReadBuffer; template class JSONDataParser { public: static void readJSON(String & s, ReadBuffer & buf) { readJSONObjectPossiblyInvalid(s, buf); } std::optional parse(const char * begin, size_t length); private: using Element = typename ParserImpl::Element; using JSONObject = typename ParserImpl::Object; using JSONArray = typename ParserImpl::Array; struct ParseContext { PathInDataBuilder builder; std::vector paths; std::vector values; }; using PathPartsWithArray = std::pair; using PathToArray = HashMapWithStackMemory; using PathToSizes = HashMapWithStackMemory, UInt128TrivialHash, 5>; struct ParseArrayContext { size_t current_size = 0; size_t total_size = 0; PathToArray arrays_by_path; PathToSizes nested_sizes_by_path; Arena strings_pool; }; void traverse(const Element & element, ParseContext & ctx); void traverseObject(const JSONObject & object, ParseContext & ctx); void traverseArray(const JSONArray & array, ParseContext & ctx); void traverseArrayElement(const Element & element, ParseArrayContext & ctx); static void fillMissedValuesInArrays(ParseArrayContext & ctx); static bool tryInsertDefaultFromNested( ParseArrayContext & ctx, const PathInData::Parts & path, Array & array); static Field getValueAsField(const Element & element); static std::optional getHashOfNestedPath(const PathInData::Parts & path, const Field & value); ParserImpl parser; }; }