MDEV-36986 Support tracing arrays of primitive types - #5583
bsrikanth-mariadb merged 1 commit into
Conversation
1b03eeb to
f895946
Compare
AI says to this part:
Is this meaningful? If yes, let's also split this change into separate commit from the quoting fix (this is trivial, right?) |
|
What if we fix it the other way: void Json_writer::add_escaped_str(const char* str, size_t num_bytes)Make this Make void Json_writer::add_unquoted_str(const char* str)
{
size_t len= strlen(str);
add_unquoted_str(str, len);
}This one has only a few users all of which know the string length. Remove it. void Json_writer::add_unquoted_str(const char* str, size_t len)
{Do we need this or it's the same as add_escaped_quoted_str ? Then, |
Yes Sergei, they seem relevant. sure, will have it in a separate commit. But, I assume we can do it in he same PR, right? |
f895946 to
cf9c3df
Compare
sure, made these changes. |
|
Let-me-run-mreview-for-you: |
|
Can we also remove this function: I think all callers do know the string length? where my_snprintf returns the length. |
cf9c3df to
1f6aee4
Compare
| { | ||
| VALIDITY_ASSERT(fmt_helper.is_making_writer_calls() || | ||
| got_name == named_item_expected()); | ||
| DBUG_ASSERT(num_bytes == 0 || |
There was a problem hiding this comment.
adding a zero-length string should be invalid. Empty strings should be quoted.
writing a non-quoted empty string would produce invalid json like '{"memb": }'
| @@ -572,14 +555,17 @@ int json_escape_to_string(const char *str, size_t len, CHARSET_INFO *cs, | |||
| out->length(out->alloced_length()); | |||
| const uchar *str_ptr= (const uchar*)str; | |||
|
|
|||
| // first, and the last byte of buf is used for double quote | |||
There was a problem hiding this comment.
"First and the last bytes of buf are used for double quotes".
spetrunia
left a comment
There was a problem hiding this comment.
Please address the above and then it's ok to push.
4360b13 to
3870414
Compare
Json_writer had two separate code paths: add_unquoted_str() for numbers/bool/null, and add_escaped_str() which added the surrounding quotes itself for strings. Single_line_formatting_helper, which buffers consecutive array/object elements to decide if they fit on one line, assumed only strings could ever be buffered and always wrapped the flushed values in quotes. As a result, arrays of numbers (e.g. "depends_on_map_bits", "rec_per_key") were incorrectly rendered with their elements quoted as strings. Unify both paths into add_escaped_quoted_str(): the caller now hands over bytes that are already in their final on-the-wire form. String escaping (json_escape_to_string) writes its own surrounding quotes, while numbers/bool/null are passed through unquoted, so the one-line helper just concatenates the buffered payloads on flush instead of adding quotes itself. A DBUG_ASSERT in add_escaped_quoted_str() now checks that every payload is already a quoted string or a bare number/bool/null token, so a caller that violates the contract trips an assertion in debug builds instead of silently producing invalid JSON. Also: - Fix Json_writer_array::add(ulonglong)/(size_t), which went through add_ll() with a cast to longlong and corrupted large unsigned values (e.g. ULLONG_MAX); route them through add_ull() instead. - Fix mysql-test/include/opt_context_schema.inc: "subquery_runs" was nested inside the preceding object instead of being a sibling member, and "rec_per_key" items are now declared as "number" to match the corrected output. - Update recorded .result files for opt_trace, opt_context_*, and subselect_mat_analyze_json to reflect numbers/booleans no longer being quoted inside JSON arrays. - Extend unittest/sql/my_json_writer-t.cc with coverage for arrays of primitives: plain integers, mixed types, sizes, multi-line arrays, values flushed before a nested object, strings that were already escaped by the one-line buffer, and invalid utf8mb4 input through add_str(). - Rewrite the "multi-line array of integers" test to actually overflow the one-line buffer (9 seven-digit numbers instead of 7), since the previous version fit on one line and never exercised the element-per-line flush path it claimed to test. - Drop the now-redundant single-argument add_escaped_quoted_str() overload; all call sites already know their length. - Update json_escape_to_string()'s doc comments (my_json_writer.h, sql_json_lib.h) to state that it quotes its output, not just escapes it.
3870414 to
a4ae3f2
Compare
Json_writer had two separate code paths: add_unquoted_str() for
numbers/bool/null, and add_escaped_str() which added the surrounding
quotes itself for strings. Single_line_formatting_helper, which
buffers consecutive array/object elements to decide if they fit on
one line, assumed only strings could ever be buffered and always
wrapped the flushed values in quotes. As a result, arrays of numbers
(e.g. "depends_on_map_bits", "rec_per_key") were incorrectly rendered
with their elements quoted as strings.
Unify both paths into add_escaped_quoted_str(): the caller now hands
over bytes that are already in their final on-the-wire form. String
escaping (json_escape_to_string) writes its own surrounding quotes,
while numbers/bool/null are passed through unquoted, so the one-line
helper just concatenates the buffered payloads on flush instead of
adding quotes itself.
Also:
add_ll() with a cast to longlong and corrupted large unsigned
values (e.g. ULLONG_MAX); route them through add_ull() instead.
nested inside the preceding object instead of being a sibling
member, and "rec_per_key" items are now declared as "number" to
match the corrected output.
subselect_mat_analyze_json to reflect numbers/booleans no longer
being quoted inside JSON arrays.
of primitives: plain integers, mixed types, sizes, multi-line
arrays, values flushed before a nested object, and strings that
were already escaped by the one-line buffer.