summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/main/anel_json.result31
-rw-r--r--mysql-test/main/anel_json.test47
-rw-r--r--mysql-test/std_data/negative_value_json.MYDbin0 -> 24 bytes
-rw-r--r--mysql-test/std_data/negative_value_json.MYIbin0 -> 1024 bytes
-rw-r--r--mysql-test/std_data/negative_value_json.frmbin0 -> 8554 bytes
-rw-r--r--mysql-test/std_data/simple_ints_table_json_object.MYDbin0 -> 48 bytes
-rw-r--r--mysql-test/std_data/simple_ints_table_json_object.MYIbin0 -> 1024 bytes
-rw-r--r--mysql-test/std_data/simple_ints_table_json_object.frmbin0 -> 8554 bytes
-rw-r--r--sql/field.cc17
-rw-r--r--sql/mysql_json.cc50
-rw-r--r--sql/mysql_json.h2
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
new file mode 100644
index 00000000000..326cd6e7020
--- /dev/null
+++ b/mysql-test/std_data/negative_value_json.MYD
Binary files differ
diff --git a/mysql-test/std_data/negative_value_json.MYI b/mysql-test/std_data/negative_value_json.MYI
new file mode 100644
index 00000000000..0d9c1e9a9ba
--- /dev/null
+++ b/mysql-test/std_data/negative_value_json.MYI
Binary files differ
diff --git a/mysql-test/std_data/negative_value_json.frm b/mysql-test/std_data/negative_value_json.frm
new file mode 100644
index 00000000000..c55262019fc
--- /dev/null
+++ b/mysql-test/std_data/negative_value_json.frm
Binary files differ
diff --git a/mysql-test/std_data/simple_ints_table_json_object.MYD b/mysql-test/std_data/simple_ints_table_json_object.MYD
new file mode 100644
index 00000000000..c9df88058f3
--- /dev/null
+++ b/mysql-test/std_data/simple_ints_table_json_object.MYD
Binary files differ
diff --git a/mysql-test/std_data/simple_ints_table_json_object.MYI b/mysql-test/std_data/simple_ints_table_json_object.MYI
new file mode 100644
index 00000000000..d0034d471c5
--- /dev/null
+++ b/mysql-test/std_data/simple_ints_table_json_object.MYI
Binary files differ
diff --git a/mysql-test/std_data/simple_ints_table_json_object.frm b/mysql-test/std_data/simple_ints_table_json_object.frm
new file mode 100644
index 00000000000..c55262019fc
--- /dev/null
+++ b/mysql-test/std_data/simple_ints_table_json_object.frm
Binary files differ
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);