diff options
Diffstat (limited to 'sql/my_json_writer.h')
-rw-r--r-- | sql/my_json_writer.h | 71 |
1 files changed, 57 insertions, 14 deletions
diff --git a/sql/my_json_writer.h b/sql/my_json_writer.h index d82313f996f..e2d60df4bf5 100644 --- a/sql/my_json_writer.h +++ b/sql/my_json_writer.h @@ -17,9 +17,20 @@ #define JSON_WRITER_INCLUDED #include "my_base.h" -#include "sql_select.h" +#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST) || defined ENABLED_JSON_WRITER_CONSISTENCY_CHECKS #include <vector> +#endif + +#ifdef JSON_WRITER_UNIT_TEST +#include "sql_string.h" +constexpr uint FAKE_SELECT_LEX_ID= UINT_MAX; +// Also, mock objects are defined in my_json_writer-t.cc +#define VALIDITY_ASSERT(x) if (!(x)) this->invalid_json= true; +#else +#include "sql_select.h" +#define VALIDITY_ASSERT(x) DBUG_ASSERT(x) +#endif class Opt_trace_stmt; class Opt_trace_context; @@ -96,9 +107,18 @@ public: bool on_end_array(); void on_start_object(); // on_end_object() is not needed. - + bool on_add_str(const char *str, size_t num_bytes); + /* + Returns true if the helper is flushing its buffer and is probably + making calls back to its Json_writer. (The Json_writer uses this + function to avoid re-doing the processing that it has already done + before making a call to fmt_helper) + */ + bool is_making_writer_calls() const { return state == DISABLED; } + +private: void flush_on_one_line(); void disable_and_flush(); }; @@ -185,6 +205,25 @@ private: class Json_writer { +#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST) + /* + In debug mode, Json_writer will fail and assertion if one attempts to + produce an invalid JSON document (e.g. JSON array having named elements). + */ + std::vector<bool> named_items_expectation; + + bool named_item_expected() const; + + bool got_name; + +#ifdef JSON_WRITER_UNIT_TEST +public: + // When compiled for unit test, creating invalid JSON will set this to true + // instead of an assertion. + bool invalid_json= false; +#endif +#endif + public: /* Add a member. We must be in an object. */ Json_writer& add_member(const char *name); @@ -208,6 +247,10 @@ public: private: void add_unquoted_str(const char* val); void add_unquoted_str(const char* val, size_t len); + + bool on_add_str(const char *str, size_t num_bytes); + void on_start_object(); + public: /* Start a child object */ void start_object(); @@ -225,6 +268,9 @@ public: size_t get_truncated_bytes() { return output.get_truncated_bytes(); } Json_writer() : +#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST) + got_name(false), +#endif indent_level(0), document_start(true), element_started(false), first_child(true) { @@ -312,6 +358,9 @@ public: /* A common base for Json_writer_object and Json_writer_array */ class Json_writer_struct { + Json_writer_struct(const Json_writer_struct&)= delete; + Json_writer_struct& operator=(const Json_writer_struct&)= delete; + #ifdef ENABLED_JSON_WRITER_CONSISTENCY_CHECKS static thread_local std::vector<bool> named_items_expectation; #endif @@ -372,24 +421,18 @@ private: my_writer->add_member(name); } public: - explicit Json_writer_object(THD *thd) - : Json_writer_struct(thd, true) - { -#ifdef ENABLED_JSON_WRITER_CONSISTENCY_CHECKS - DBUG_ASSERT(!named_item_expected()); -#endif - if (unlikely(my_writer)) - my_writer->start_object(); - } - - explicit Json_writer_object(THD* thd, const char *str) + explicit Json_writer_object(THD* thd, const char *str= nullptr) : Json_writer_struct(thd, true) { #ifdef ENABLED_JSON_WRITER_CONSISTENCY_CHECKS DBUG_ASSERT(named_item_expected()); #endif if (unlikely(my_writer)) - my_writer->add_member(str).start_object(); + { + if (str) + my_writer->add_member(str); + my_writer->start_object(); + } } ~Json_writer_object() |