diff options
| -rw-r--r-- | mysql-test/main/anel_json.result | 31 | ||||
| -rw-r--r-- | mysql-test/main/anel_json.test | 47 | ||||
| -rw-r--r-- | mysql-test/std_data/negative_value_json.MYD | bin | 0 -> 24 bytes | |||
| -rw-r--r-- | mysql-test/std_data/negative_value_json.MYI | bin | 0 -> 1024 bytes | |||
| -rw-r--r-- | mysql-test/std_data/negative_value_json.frm | bin | 0 -> 8554 bytes | |||
| -rw-r--r-- | mysql-test/std_data/simple_ints_table_json_object.MYD | bin | 0 -> 48 bytes | |||
| -rw-r--r-- | mysql-test/std_data/simple_ints_table_json_object.MYI | bin | 0 -> 1024 bytes | |||
| -rw-r--r-- | mysql-test/std_data/simple_ints_table_json_object.frm | bin | 0 -> 8554 bytes | |||
| -rw-r--r-- | sql/field.cc | 17 | ||||
| -rw-r--r-- | sql/mysql_json.cc | 50 | ||||
| -rw-r--r-- | sql/mysql_json.h | 2 |
11 files changed, 125 insertions, 22 deletions
diff --git a/mysql-test/main/anel_json.result b/mysql-test/main/anel_json.result new file mode 100644 index 00000000000..3522cff268d --- /dev/null +++ b/mysql-test/main/anel_json.result @@ -0,0 +1,31 @@ +# +# MDEV-18323: Convert MySQL JSON type to MariaDB TEXT in mysql_upgrade +# Test integers +# +drop table if exists mysql_json; +Warnings: +Note 1051 Unknown table 'test.mysql_json' +# +# String value +# +select * from test.mysql_json; +t +{"key1":"val1","key2":"val2"} +Finshed +drop table mysql_json; +# +# Negative value +# +select * from test.mysql_json; +t +{"neg":-10} +Finshed +drop table mysql_json; +# +# Mix of INT32 and UINT64 +# +select * from test.mysql_json; +t +{"neg":470417432,"pos":8317990626162245660} +Finshed +drop table mysql_json; diff --git a/mysql-test/main/anel_json.test b/mysql-test/main/anel_json.test new file mode 100644 index 00000000000..21c06390546 --- /dev/null +++ b/mysql-test/main/anel_json.test @@ -0,0 +1,47 @@ +--echo # +--echo # MDEV-18323: Convert MySQL JSON type to MariaDB TEXT in mysql_upgrade +--echo # Test integers +--echo # + +let $datadir=`select @@datadir`; +drop table if exists mysql_json; + +--echo # +--echo # String value +--echo # + +--copy_file std_data/json.frm $datadir/test/mysql_json.frm +--copy_file std_data/json.MYI $datadir/test/mysql_json.MYI +--copy_file std_data/json.MYD $datadir/test/mysql_json.MYD + +# Now can read +select * from test.mysql_json; + +drop table mysql_json; + +--echo # +--echo # Negative value +--echo # + +--copy_file std_data/negative_value_json.frm $datadir/test/mysql_json.frm +--copy_file std_data/negative_value_json.MYI $datadir/test/mysql_json.MYI +--copy_file std_data/negative_value_json.MYD $datadir/test/mysql_json.MYD + +select * from test.mysql_json; + +drop table mysql_json; +--echo # +--echo # Mix of INT32 and UINT64 +--echo # + + + +# Make sure you have placed `json.[frm/myd/myi]` files in `source/mysql-test/std_data/` +--copy_file std_data/simple_ints_table_json_object.frm $datadir/test/mysql_json.frm +--copy_file std_data/simple_ints_table_json_object.MYI $datadir/test/mysql_json.MYI +--copy_file std_data/simple_ints_table_json_object.MYD $datadir/test/mysql_json.MYD + +# Now can read +select * from test.mysql_json; + +drop table mysql_json;
\ No newline at end of file diff --git a/mysql-test/std_data/negative_value_json.MYD b/mysql-test/std_data/negative_value_json.MYD Binary files differnew file mode 100644 index 00000000000..326cd6e7020 --- /dev/null +++ b/mysql-test/std_data/negative_value_json.MYD diff --git a/mysql-test/std_data/negative_value_json.MYI b/mysql-test/std_data/negative_value_json.MYI Binary files differnew file mode 100644 index 00000000000..0d9c1e9a9ba --- /dev/null +++ b/mysql-test/std_data/negative_value_json.MYI diff --git a/mysql-test/std_data/negative_value_json.frm b/mysql-test/std_data/negative_value_json.frm Binary files differnew file mode 100644 index 00000000000..c55262019fc --- /dev/null +++ b/mysql-test/std_data/negative_value_json.frm diff --git a/mysql-test/std_data/simple_ints_table_json_object.MYD b/mysql-test/std_data/simple_ints_table_json_object.MYD Binary files differnew file mode 100644 index 00000000000..c9df88058f3 --- /dev/null +++ b/mysql-test/std_data/simple_ints_table_json_object.MYD diff --git a/mysql-test/std_data/simple_ints_table_json_object.MYI b/mysql-test/std_data/simple_ints_table_json_object.MYI Binary files differnew file mode 100644 index 00000000000..d0034d471c5 --- /dev/null +++ b/mysql-test/std_data/simple_ints_table_json_object.MYI diff --git a/mysql-test/std_data/simple_ints_table_json_object.frm b/mysql-test/std_data/simple_ints_table_json_object.frm Binary files differnew file mode 100644 index 00000000000..c55262019fc --- /dev/null +++ b/mysql-test/std_data/simple_ints_table_json_object.frm diff --git a/sql/field.cc b/sql/field.cc index 7ff938b5d33..bd60483ac37 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -11194,6 +11194,8 @@ bool Field_mysql_json::parse_mysql(String *s, bool json_quoted, const char *data= s->ptr(); size_t length= s->length(); + // Empty the string + s->length(0); if (length == 0) { //@todo anel will need to see how to handle this @@ -11219,7 +11221,7 @@ bool Field_mysql_json::parse_mysql(String *s, bool json_quoted, case JSONB_TYPE_SMALL_OBJECT: { large=false; - parse_array_or_object(Field_mysql_json::enum_type::OBJECT, data1, len, large); + parse_array_or_object(s, Field_mysql_json::enum_type::OBJECT, data1, len, large); break; } case JSONB_TYPE_LARGE_OBJECT: @@ -11240,19 +11242,10 @@ bool Field_mysql_json::parse_mysql(String *s, bool json_quoted, ASSERT_COLUMN_MARKED_FOR_READ; String *buf1= Field_blob::val_str(buf1_tmp, buf2); bool parsed= this->parse_mysql(buf1, true, field_name.str); - if(parsed) - buf1->append("Too"); + if(parsed) + buf1->append("\nFinshed"); else buf1->length(0); - //buf1->set("",0,charset()); // A bit safer than buf1->length(0); - //buf1->length(0); - - /* - Json_wrapper wr; - if (is_null() || val_json(&wr) || wr.to_string(buf1, true, field_name.str)) - buf1->length(0); - return buf1; - */ return buf1; } diff --git a/sql/mysql_json.cc b/sql/mysql_json.cc index 4a158802281..9e8e5e66a16 100644 --- a/sql/mysql_json.cc +++ b/sql/mysql_json.cc @@ -38,7 +38,7 @@ static bool check_json_depth(size_t depth) } -bool parse_array_or_object(Field_mysql_json::enum_type t, const char *data, size_t len, bool large) +bool parse_array_or_object(String *buffer,Field_mysql_json::enum_type t, const char *data, size_t len, bool large) { //DBUG_ASSERT(t == Field_mysql_json::ARRAY || t == Field_mysql_json::OBJECT); /* @@ -77,7 +77,6 @@ bool parse_array_or_object(Field_mysql_json::enum_type t, const char *data, if (header_size > bytes) return true; /* purecov: inspected */ - String *buffer= new String(); // this will go as parameter if (t==Field_mysql_json::enum_type::OBJECT) { @@ -117,10 +116,11 @@ bool parse_array_or_object(Field_mysql_json::enum_type t, const char *data, value_type_offset= 2*offset_size+ (large?KEY_ENTRY_SIZE_LARGE:KEY_ENTRY_SIZE_SMALL)*(element_count)+(large ? VALUE_ENTRY_SIZE_LARGE : VALUE_ENTRY_SIZE_SMALL)*value_counter; value_counter++; - check_mysql_value_type_and_append(buffer, value_type_offset, data, is_last, large, 0); - if(i!=(element_count-1)) + if(i==(element_count-1)) is_last=true; + check_mysql_value_type_and_append(buffer, value_type_offset, data, is_last, large, 0); + is_last=false; } if(buffer->append('}')) @@ -139,19 +139,51 @@ bool parse_array_or_object(Field_mysql_json::enum_type t, const char *data, return true; value_json_type= data[value_type_offset]; - value_length_ptr= read_offset_or_size(data+value_type_offset+1, large); - value_length= (uint) data[value_length_ptr]; - switch(value_json_type) { + /** FINISHED WORKS **/ case JSONB_TYPE_INT16 : { - // value_length_ptr is a value of interest (negative should work, @todo) - buffer->append_longlong((longlong) (value_length_ptr)); + buffer->append_longlong((longlong) (sint2korr(data+value_type_offset+1))); break; } + + /*** NOT WORKING ****/ + case JSONB_TYPE_INT32: + { + // In this case value_length_ptr is start of the value and has 4 bytes + //value_element= new char[4]; + //value_length_ptr= read_offset_or_size(data+value_type_offset+1, large); + //memmove(value_element, const_cast<char*>(&data[value_length_ptr+1]), 4); + if( buffer->append_longlong(sint4korr(data+value_type_offset+1))) + return true; + // delete[] value_element; + + if(!is_last) + buffer->append(","); + break; + } + + /*** NOT WORKING ****/ + case JSONB_TYPE_UINT64: + { + // In this case value_length_ptr is start of the value and has 8 bytes + //value_element= new char[8]; + //value_length_ptr= read_offset_or_size(data+value_type_offset+1, large); + //memmove(value_element, const_cast<char*>(&data[value_length_ptr+1]), 8); + if( buffer->append_longlong(uint8korr(data+value_type_offset+1))) + return true; + //delete[] value_element; + if(!is_last) + buffer->append(","); + break; + } + + /** FINISHED WORKS **/ case JSONB_TYPE_STRING: { + value_length_ptr= read_offset_or_size(data+value_type_offset+1, large); + value_length= (uint) data[value_length_ptr]; value_element= new char[value_length+1]; memmove(value_element, const_cast<char*>(&data[value_length_ptr+1]), value_length); value_element[value_length]= '\0'; diff --git a/sql/mysql_json.h b/sql/mysql_json.h index 71b83b45eb9..d6d7d7657e2 100644 --- a/sql/mysql_json.h +++ b/sql/mysql_json.h @@ -140,7 +140,7 @@ enum enum_json_opaque_type { // Prototypes size_t read_offset_or_size(const char *, bool); -bool parse_array_or_object(Field_mysql_json::enum_type, +bool parse_array_or_object(String * buffer, Field_mysql_json::enum_type, const char *,size_t , bool); bool parse_scalar(); bool check_mysql_value_type_and_append(String* buffer, size_t value_type_offset, const char *data, bool is_last, bool large, size_t depth); |
