diff --git a/include/json_lib.h b/include/json_lib.h index ecd108c7567..aabf97ad073 100644 --- a/include/json_lib.h +++ b/include/json_lib.h @@ -172,6 +172,14 @@ enum json_value_types }; +enum json_num_flags +{ + JSON_NUM_NEG=1, /* Number is negative. */ + JSON_NUM_FRAC_PART=2, /* The fractional part is not empty. */ + JSON_NUM_EXP=4, /* The number has the 'e' part. */ +}; + + typedef struct st_json_engine_t { json_string_t s; /* String to parse. */ @@ -185,6 +193,9 @@ typedef struct st_json_engine_t enum json_value_types value_type; /* type of the value.*/ const uchar *value; /* Points to the value. */ const uchar *value_begin;/* Points to where the value starts in the JSON. */ + uint num_flags; /* the details of the JSON_VALUE_NUMBER, is it negative, + or if it has the fractional part. + See the enum json_num_flags. */ /* In most cases the 'value' and 'value_begin' are equal. diff --git a/mysql-test/r/func_json.result b/mysql-test/r/func_json.result index 1778a2b3514..e3eb8328deb 100644 --- a/mysql-test/r/func_json.result +++ b/mysql-test/r/func_json.result @@ -215,7 +215,10 @@ json_type("true") BOOLEAN select json_type('123'); json_type('123') -NUMBER +INTEGER +select json_type('123.12'); +json_type('123.12') +DOUBLE select json_keys('{"a":{"c":1, "d":2}, "b":2}'); json_keys('{"a":{"c":1, "d":2}, "b":2}') ["a", "b"] diff --git a/mysql-test/t/func_json.test b/mysql-test/t/func_json.test index 4ac2c6e3c04..894e16809ec 100644 --- a/mysql-test/t/func_json.test +++ b/mysql-test/t/func_json.test @@ -93,6 +93,7 @@ select json_type('{"k1":123, "k2":345}'); select json_type('[123, "k2", 345]'); select json_type("true"); select json_type('123'); +select json_type('123.12'); select json_keys('{"a":{"c":1, "d":2}, "b":2}'); select json_keys('{"a":{"c":1, "d":2}, "b":2}', "$.a"); diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc index 00621bbfade..e39e8118028 100644 --- a/sql/item_jsonfunc.cc +++ b/sql/item_jsonfunc.cc @@ -1310,7 +1310,7 @@ String *Item_func_json_type::val_str(String *str) type= "STRING"; break; case JSON_VALUE_NUMBER: - type= "NUMBER"; + type= (je.num_flags & JSON_NUM_FRAC_PART) ? "DOUBLE" : "INTEGER"; break; case JSON_VALUE_TRUE: case JSON_VALUE_FALSE: diff --git a/strings/json_lib.c b/strings/json_lib.c index 3c6cc717aac..976fab7e7f6 100644 --- a/strings/json_lib.c +++ b/strings/json_lib.c @@ -477,13 +477,29 @@ static int json_num_states[NS_NUM_STATES][N_NUM_CLASSES]= }; +static uint json_num_state_flags[NS_NUM_STATES]= +{ +/*OK*/ 0, +/*GO*/ 0, +/*GO1*/ JSON_NUM_NEG, +/*ZERO*/ 0, +/*ZE1*/ 0, +/*INT*/ 0, +/*FRAC*/ JSON_NUM_FRAC_PART, +/*EX*/ JSON_NUM_EXP, +/*EX1*/ 0, +}; + + static int skip_num_constant(json_engine_t *j) { int state= json_num_states[NS_GO][json_num_chr_map[j->s.c_next]]; int c_len; + j->num_flags= 0; for (;;) { + j->num_flags|= json_num_state_flags[state]; if ((c_len= json_next_char(&j->s)) > 0) { if ((state= json_num_states[state][json_num_chr_map[j->s.c_next]]) > 0)