summaryrefslogtreecommitdiff
path: root/sql/my_json_writer.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/my_json_writer.h')
-rw-r--r--sql/my_json_writer.h71
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()