summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/main/anel_int.result11
-rw-r--r--mysql-test/main/anel_int.test17
-rw-r--r--mysql-test/main/anel_json.result2
-rw-r--r--sql/mysql_json.cc87
4 files changed, 89 insertions, 28 deletions
diff --git a/mysql-test/main/anel_int.result b/mysql-test/main/anel_int.result
new file mode 100644
index 00000000000..b452bbc4625
--- /dev/null
+++ b/mysql-test/main/anel_int.result
@@ -0,0 +1,11 @@
+drop table if exists mysql_json;
+Warnings:
+Note 1051 Unknown table 'test.mysql_json'
+#
+# Mix of INT32 and UINT64
+#
+select * from test.mysql_json;
+t
+{"neg":-1234567890,"pos":9876543210}
+Finshed
+drop table mysql_json;
diff --git a/mysql-test/main/anel_int.test b/mysql-test/main/anel_int.test
new file mode 100644
index 00000000000..370c312844a
--- /dev/null
+++ b/mysql-test/main/anel_int.test
@@ -0,0 +1,17 @@
+let $datadir=`select @@datadir`;
+drop table if exists 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;
diff --git a/mysql-test/main/anel_json.result b/mysql-test/main/anel_json.result
index 3522cff268d..56652e374c1 100644
--- a/mysql-test/main/anel_json.result
+++ b/mysql-test/main/anel_json.result
@@ -26,6 +26,6 @@ drop table mysql_json;
#
select * from test.mysql_json;
t
-{"neg":470417432,"pos":8317990626162245660}
+{"neg":-1234567890,"pos":9876543210}
Finshed
drop table mysql_json;
diff --git a/sql/mysql_json.cc b/sql/mysql_json.cc
index 9e8e5e66a16..299e85aa59c 100644
--- a/sql/mysql_json.cc
+++ b/sql/mysql_json.cc
@@ -130,10 +130,9 @@ bool parse_array_or_object(String *buffer,Field_mysql_json::enum_type t, const c
return 1;
}
- 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)
+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)
{
- size_t value_json_type, value_length, value_length_ptr;
- char *value_element;
+ size_t value_json_type;
if (check_json_depth(++depth))
return true;
@@ -142,46 +141,78 @@ bool parse_array_or_object(String *buffer,Field_mysql_json::enum_type t, const c
switch(value_json_type)
{
/** FINISHED WORKS **/
- case JSONB_TYPE_INT16 :
+ case JSONB_TYPE_INT16 :
{
buffer->append_longlong((longlong) (sint2korr(data+value_type_offset+1)));
break;
}
- /*** NOT WORKING ****/
+ /** FINISHED WORKS **/
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;
+ // depending on large -> can be inline or not-inline value @todo test
+ if(!large)
+ {
+ // In this case value_length_ptr is start of the value and has 4 bytes -> mysql is checking the length which is sent and raise an error (bytes-value_length_pt)
+ size_t value_length_ptr;
+ char *value_element;
+ uint num_bytes=8;
+ value_element= new char[num_bytes+1];
+ value_length_ptr= read_offset_or_size(data+value_type_offset+1, large);
+ memmove(value_element, const_cast<char*>(&data[value_length_ptr]), num_bytes);
+ value_element[num_bytes+1]= '\0';
+ if( buffer->append_longlong(sint4korr(value_element)))
+ return true;
+ delete[] value_element;
+ break;
+ }
+ else
+ {
+ if( buffer->append_longlong(sint4korr(data+value_type_offset+1)))
+ return true;
+ }
+ break;
+ }
- if(!is_last)
- buffer->append(",");
+ /** @todo Need to test ! **/
+ case JSONB_TYPE_UINT16 :
+ {
+ buffer->append_longlong((longlong) (uint2korr(data+value_type_offset+1)));
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(",");
+ // depending on large -> can be inline or not-inline value @todo test
+ if(!large)
+ {
+ // In this case value_length_ptr is start of the value and has 8 bytes -> mysql is checking the length which is sent and raise an error (bytes-value_length_pt)
+ size_t value_length_ptr;
+ char *value_element;
+ uint num_bytes=8;
+
+ value_element= new char[num_bytes+1];
+ value_length_ptr= read_offset_or_size(data+value_type_offset+1, large);
+ memmove(value_element, const_cast<char*>(&data[value_length_ptr]),num_bytes);
+ value_element[num_bytes+1]= '\0';
+ if( buffer->append_longlong(uint8korr(value_element)))
+ return true;
+ delete[] value_element;
+ break;
+ }
+ else
+ {
+ if( buffer->append_longlong(uint8korr(data+value_type_offset+1)))
+ return true;
+ }
break;
}
-
/** FINISHED WORKS **/
case JSONB_TYPE_STRING:
{
+ size_t value_length, value_length_ptr;
+ char *value_element;
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];
@@ -194,11 +225,13 @@ bool parse_array_or_object(String *buffer,Field_mysql_json::enum_type t, const c
if(buffer->append('"'))
return true;
delete[] value_element;
- if(!is_last)
- buffer->append(",");
- break;
}
}
+ if(!is_last)
+ {
+ buffer->append(",");
+ }
+
return false;
} \ No newline at end of file