summaryrefslogtreecommitdiff
path: root/sql/my_json_writer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/my_json_writer.cc')
-rw-r--r--sql/my_json_writer.cc102
1 files changed, 92 insertions, 10 deletions
diff --git a/sql/my_json_writer.cc b/sql/my_json_writer.cc
index 8e35b25b822..c95e4c6d657 100644
--- a/sql/my_json_writer.cc
+++ b/sql/my_json_writer.cc
@@ -39,7 +39,7 @@ inline void Json_writer::on_start_object()
#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST)
if(!fmt_helper.is_making_writer_calls())
{
- VALIDITY_ASSERT(got_name == named_item_expected());
+ validate_named_item_expectation(true);
named_items_expectation.push_back(true);
}
#endif
@@ -68,7 +68,7 @@ void Json_writer::start_array()
#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST)
if(!fmt_helper.is_making_writer_calls())
{
- VALIDITY_ASSERT(got_name == named_item_expected());
+ validate_named_item_expectation(true);
named_items_expectation.push_back(false);
got_name= false;
}
@@ -91,9 +91,20 @@ void Json_writer::start_array()
void Json_writer::end_object()
{
#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST)
- VALIDITY_ASSERT(named_item_expected());
+ if (!named_item_expected())
+ {
+ print_json_tail_to_stderr(
+ "end_object failed since an unnamed item is expected");
+ VALIDITY_ASSERT(false);
+ }
named_items_expectation.pop_back();
- VALIDITY_ASSERT(!got_name);
+
+ if (got_name)
+ {
+ print_json_tail_to_stderr(
+ "end_object failed since got_name==true");
+ VALIDITY_ASSERT(false);
+ }
got_name= false;
#endif
indent_level-=INDENT_SIZE;
@@ -107,7 +118,12 @@ void Json_writer::end_object()
void Json_writer::end_array()
{
#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST)
- VALIDITY_ASSERT(!named_item_expected());
+ if (named_item_expected())
+ {
+ print_json_tail_to_stderr(
+ "end_array failed since a named item is expected");
+ VALIDITY_ASSERT(false);
+ }
named_items_expectation.pop_back();
got_name= false;
#endif
@@ -130,8 +146,18 @@ Json_writer& Json_writer::add_member(const char *name, size_t len)
{
if (!fmt_helper.on_add_member(name, len))
{
+#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST)
// assert that we are in an object
- DBUG_ASSERT(!element_started);
+ if (element_started)
+ {
+ char err_descr[200];
+ snprintf(err_descr, sizeof(err_descr),
+ "failed to add_member(\"%s\", %zu) since element_started=false",
+ name, len);
+ print_json_tail_to_stderr(err_descr);
+ VALIDITY_ASSERT(false);
+ }
+#endif
start_element();
output.append('"');
@@ -242,8 +268,12 @@ void Json_writer::add_unquoted_str(const char* str)
void Json_writer::add_unquoted_str(const char* str, size_t len)
{
- VALIDITY_ASSERT(fmt_helper.is_making_writer_calls() ||
- got_name == named_item_expected());
+#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST)
+ if (!fmt_helper.is_making_writer_calls())
+ {
+ validate_named_item_expectation();
+ }
+#endif
if (on_add_str(str, len))
return;
@@ -275,8 +305,12 @@ void Json_writer::add_str(const char *str)
void Json_writer::add_str(const char* str, size_t num_bytes)
{
- VALIDITY_ASSERT(fmt_helper.is_making_writer_calls() ||
- got_name == named_item_expected());
+#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST)
+ if (!fmt_helper.is_making_writer_calls())
+ {
+ validate_named_item_expectation();
+ }
+#endif
if (on_add_str(str, num_bytes))
return;
@@ -294,6 +328,53 @@ void Json_writer::add_str(const String &str)
add_str(str.ptr(), str.length());
}
+#if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST)
+void Json_writer::print_json_tail_to_stderr(const char *err_descr)
+{
+ size_t pos_to_print_from=
+ output.get_string()->length() < MAX_JSON_LEN_FOR_STDERR ?
+ 0 : output.get_string()->length() - MAX_JSON_LEN_FOR_STDERR;
+ auto str_to_print= output.get_string()->c_ptr() + pos_to_print_from;
+ fprintf(stderr, "JSON writer error: %s.\nJSON tail: %s\n",
+ err_descr, str_to_print);
+}
+
+void Json_writer::validate_named_item_expectation(bool fix_wth_implicit_member)
+{
+ if (got_name != named_item_expected())
+ {
+ if (!got_name && fix_wth_implicit_member)
+ {
+ /*
+ Context is expecting a named member but has an unnamed one.
+ Add a member with automatically assigned name to preserve
+ JSON document correctness
+ */
+ add_implicit_member();
+ return;
+ }
+ const char *expected= named_item_expected() ?
+ "named" : "unnamed";
+ const char *actual= named_item_expected() ?
+ "unnamed" : "named";
+ char err_descr[100];
+ snprintf(err_descr, sizeof(err_descr),
+ "expected a %s member but a %s one has been added",
+ expected, actual);
+ print_json_tail_to_stderr(err_descr);
+ VALIDITY_ASSERT(false);
+ }
+}
+
+void Json_writer::add_implicit_member()
+{
+ char name[50];
+ sprintf(name, "implicitly_added_member_#%u", implicit_member_num);
+ add_member(name);
+ implicit_member_num++;
+}
+#endif
+
Json_writer_temp_disable::Json_writer_temp_disable(THD *thd_arg)
{
thd= thd_arg;
@@ -308,6 +389,7 @@ bool Single_line_formatting_helper::on_add_member(const char *name,
size_t len)
{
DBUG_ASSERT(state== INACTIVE || state == DISABLED);
+
if (state != DISABLED)
{
// remove everything from the array