diff --git a/mysql-test/suite/json/r/json_table.result b/mysql-test/suite/json/r/json_table.result index 00f4ecf0c8d..3b38d748b05 100644 --- a/mysql-test/suite/json/r/json_table.result +++ b/mysql-test/suite/json/r/json_table.result @@ -88,7 +88,7 @@ a b select * from JSON_TABLE( '[{"a": [1, 2], "b": [11,111]}, {"a": 2, "b": [22,222]}, {"a":3} xx YY]', '$[*]' COLUMNS( a INT PATH '$.a' default '202' on error default '101' on empty, NESTED PATH '$.b[*]' COLUMNS (b INT PATH '$'))) as jt; ERROR HY000: Syntax error in JSON text in argument 1 to function 'JSON_TABLE' at position 65 select * from JSON_TABLE( '[{"a": [1, 2], "b": [11,111]}, {"a": 2, "b": [22,222]}, {"a":3}]', '$[*]' COLUMNS( a INT PATH '$.a' error on error default '101' on empty, NESTED PATH '$.b[*]' COLUMNS (b INT PATH '$'))) as jt; -ERROR HY000: Field 'a' can't be set for JSON_TABLE 'jt'. +ERROR HY000: Can't store an array or an object in the scalar column 'a' of JSON_TABLE 'jt'. select * from json_table('{"a":0}',"$" columns(a decimal(1,1) path '$.a')) foo; a 0.0 @@ -573,5 +573,13 @@ id 3 drop table json_table; # +# MDEV-25146 JSON_TABLE: Non-descriptive + wrong error messages upon trying to store array or object. +# +select a from json_table('[[]]', '$' columns(a char(8) path '$' error on error)) t; +ERROR HY000: Can't store an array or an object in the scalar column 'a' of JSON_TABLE 't'. +show warnings; +Level Code Message +Error 4177 Can't store an array or an object in the scalar column 'a' of JSON_TABLE 't'. +# # End of 10.6 tests # diff --git a/mysql-test/suite/json/r/json_table_mysql.result b/mysql-test/suite/json/r/json_table_mysql.result index b1db299c94e..24cc5fa64b6 100644 --- a/mysql-test/suite/json/r/json_table_mysql.result +++ b/mysql-test/suite/json/r/json_table_mysql.result @@ -115,7 +115,7 @@ json_table( jpath varchar(100) path '$.a' error on error, jexst int exists path '$.b') ) as tt; -ERROR HY000: Field 'jpath' can't be set for JSON_TABLE 'tt'. +ERROR HY000: Can't store an array or an object in the scalar column 'jpath' of JSON_TABLE 'tt'. select * from json_table( '!#@$!@#$', @@ -396,18 +396,18 @@ v CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIE DROP VIEW v; SELECT * FROM JSON_TABLE('"asdf"', '$' COLUMNS (a INT PATH '$' ERROR ON ERROR)) AS jt; -ERROR HY000: Field 'a' can't be set for JSON_TABLE 'jt'. +ERROR HY000: Can't store an array or an object in the scalar column 'a' of JSON_TABLE 'jt'. SELECT * FROM JSON_TABLE('[{"a":1},{"a":2}]', '$' COLUMNS (a INT PATH '$[*].a' ERROR ON ERROR)) AS jt; -ERROR HY000: Field 'a' can't be set for JSON_TABLE 'jt'. +ERROR HY000: Can't store multiple matches of the path in the column 'a' of JSON_TABLE 'jt'. SELECT * FROM JSON_TABLE('[{"a":1},{"a":2}]', '$' COLUMNS (a JSON PATH '$[*].a' ERROR ON ERROR)) AS jt; -ERROR HY000: Field 'a' can't be set for JSON_TABLE 'jt'. +ERROR HY000: Can't store multiple matches of the path in the column 'a' of JSON_TABLE 'jt'. SELECT * FROM JSON_TABLE('123.456', '$' COLUMNS (a DECIMAL(2,1) PATH '$' ERROR ON ERROR)) AS jt; -ERROR HY000: Field 'a' can't be set for JSON_TABLE 'jt'. +ERROR HY000: Can't store an array or an object in the scalar column 'a' of JSON_TABLE 'jt'. SELECT * FROM JSON_TABLE('123.456', '$' COLUMNS (a DECIMAL(2,1) PATH '$')) AS jt; a @@ -811,7 +811,7 @@ SELECT * FROM JSON_TABLE('[3.14159]', '$[*]' COLUMNS (col18 DECIMAL(3,3) PATH '$' ERROR ON ERROR) ) AS alias2; -ERROR HY000: Field 'col18' can't be set for JSON_TABLE 'alias2'. +ERROR HY000: Can't store an array or an object in the scalar column 'col18' of JSON_TABLE 'alias2'. SELECT * FROM JSON_TABLE('[0.9]', '$[*]' COLUMNS (col18 DECIMAL(3,3) PATH '$') diff --git a/mysql-test/suite/json/t/json_table.test b/mysql-test/suite/json/t/json_table.test index 4b0293f6bea..7d7085c7e89 100644 --- a/mysql-test/suite/json/t/json_table.test +++ b/mysql-test/suite/json/t/json_table.test @@ -41,7 +41,7 @@ select * from JSON_TABLE( '[ {"a": [1, 2], "b": [11,111]}, {"a": 2, "b": [22,222 --error ER_JSON_SYNTAX select * from JSON_TABLE( '[{"a": [1, 2], "b": [11,111]}, {"a": 2, "b": [22,222]}, {"a":3} xx YY]', '$[*]' COLUMNS( a INT PATH '$.a' default '202' on error default '101' on empty, NESTED PATH '$.b[*]' COLUMNS (b INT PATH '$'))) as jt; ---error ER_JSON_TABLE_ERROR_ON_FIELD +--error ER_JSON_TABLE_SCALAR_EXPECTED select * from JSON_TABLE( '[{"a": [1, 2], "b": [11,111]}, {"a": 2, "b": [22,222]}, {"a":3}]', '$[*]' COLUMNS( a INT PATH '$.a' error on error default '101' on empty, NESTED PATH '$.b[*]' COLUMNS (b INT PATH '$'))) as jt; # @@ -446,6 +446,13 @@ insert into json_table values (1), (2), (3); select * from json_table; drop table json_table; +--echo # +--echo # MDEV-25146 JSON_TABLE: Non-descriptive + wrong error messages upon trying to store array or object. +--echo # +--error ER_JSON_TABLE_SCALAR_EXPECTED +select a from json_table('[[]]', '$' columns(a char(8) path '$' error on error)) t; +show warnings; + --echo # --echo # End of 10.6 tests --echo # diff --git a/mysql-test/suite/json/t/json_table_mysql.test b/mysql-test/suite/json/t/json_table_mysql.test index 0d322c8b286..821d262283d 100644 --- a/mysql-test/suite/json/t/json_table_mysql.test +++ b/mysql-test/suite/json/t/json_table_mysql.test @@ -91,7 +91,7 @@ select * from jexst int exists path '$.b') ) as tt; ---error ER_JSON_TABLE_ERROR_ON_FIELD +--error ER_JSON_TABLE_SCALAR_EXPECTED select * from json_table( '[{"a":"3"},{"a":2},{"a":1},{"a":[0,1]}]', @@ -327,20 +327,19 @@ SELECT * FROM v; SHOW CREATE VIEW v; DROP VIEW v; ---error ER_JSON_TABLE_ERROR_ON_FIELD +--error ER_JSON_TABLE_SCALAR_EXPECTED SELECT * FROM JSON_TABLE('"asdf"', '$' COLUMNS (a INT PATH '$' ERROR ON ERROR)) AS jt; -#--error ER_WRONG_JSON_TABLE_VALUE ---error ER_JSON_TABLE_ERROR_ON_FIELD +--error ER_JSON_TABLE_MULTIPLE_MATCHES SELECT * FROM JSON_TABLE('[{"a":1},{"a":2}]', '$' COLUMNS (a INT PATH '$[*].a' ERROR ON ERROR)) AS jt; # psergey-added: ---error ER_JSON_TABLE_ERROR_ON_FIELD +--error ER_JSON_TABLE_MULTIPLE_MATCHES SELECT * FROM JSON_TABLE('[{"a":1},{"a":2}]', '$' COLUMNS (a JSON PATH '$[*].a' ERROR ON ERROR)) AS jt; ---error ER_JSON_TABLE_ERROR_ON_FIELD +--error ER_JSON_TABLE_SCALAR_EXPECTED SELECT * FROM JSON_TABLE('123.456', '$' COLUMNS (a DECIMAL(2,1) PATH '$' ERROR ON ERROR)) AS jt; SELECT * FROM @@ -722,7 +721,7 @@ SELECT * FROM ) AS alias2; #--error ER_JT_VALUE_OUT_OF_RANGE ---error ER_JSON_TABLE_ERROR_ON_FIELD +--error ER_JSON_TABLE_SCALAR_EXPECTED SELECT * FROM JSON_TABLE('[3.14159]', '$[*]' COLUMNS (col18 DECIMAL(3,3) PATH '$' ERROR ON ERROR) diff --git a/sql/handler.cc b/sql/handler.cc index 482d7939c1a..6fd0175a09b 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -4225,7 +4225,11 @@ void handler::print_error(int error, myf errflag) } } else - my_error(ER_GET_ERRNO, errflag, error, table_type()); + { + if (!temporary) + my_error(ER_GET_ERRNO, errflag, error, table_type()); + /* else no error message. */ + } DBUG_VOID_RETURN; } } diff --git a/sql/json_table.cc b/sql/json_table.cc index e80e4bce891..157e9379a4c 100644 --- a/sql/json_table.cc +++ b/sql/json_table.cc @@ -23,6 +23,7 @@ #include "json_table.h" #include "sql_show.h" +#define HA_ERR_JSON_TABLE (HA_ERR_LAST+1) class table_function_handlerton { @@ -104,6 +105,12 @@ public: { return NULL; } int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info) override { return 1; } + /* Give no message. */ + bool get_error_message(int error, String *buf) override + { + buf->length(0); + return TRUE; + } }; @@ -284,7 +291,7 @@ int ha_json_table::rnd_next(uchar *buf) error code that just doesn't produce extra messages. */ - return HA_ERR_TABLE_IN_FK_CHECK; + return HA_ERR_JSON_TABLE; } return HA_ERR_END_OF_FILE; } @@ -297,7 +304,7 @@ int ha_json_table::rnd_next(uchar *buf) table->in_use->count_cuted_fields= CHECK_FIELD_EXPRESSION; res= fill_column_values(buf, NULL); table->in_use->count_cuted_fields= cf_orig; - return res ? HA_ERR_TABLE_IN_FK_CHECK : 0; + return res ? HA_ERR_JSON_TABLE : 0; } @@ -401,7 +408,7 @@ int ha_json_table::fill_column_values(uchar * buf, uchar *pos) { if (not_found) { - if (jc->m_on_empty.respond(jc, *f)) + if (jc->m_on_empty.respond(jc, *f, ER_JSON_TABLE_ERROR_ON_FIELD)) goto error_return; } else @@ -409,7 +416,7 @@ int ha_json_table::fill_column_values(uchar * buf, uchar *pos) if (!json_value_scalar(&je) || store_json_in_field(*f, &je)) { - if (jc->m_on_error.respond(jc, *f)) + if (jc->m_on_error.respond(jc, *f, ER_JSON_TABLE_SCALAR_EXPECTED)) goto error_return; } else @@ -424,7 +431,7 @@ int ha_json_table::fill_column_values(uchar * buf, uchar *pos) !json_find_path(&je, &jc->m_path, &cur_step, array_counters))) { - if (jc->m_on_error.respond(jc, *f)) + if (jc->m_on_error.respond(jc, *f, ER_JSON_TABLE_MULTIPLE_MATCHES)) goto error_return; } } @@ -449,7 +456,7 @@ error_return: int ha_json_table::rnd_pos(uchar * buf, uchar *pos) { - return fill_column_values(buf, pos) ? HA_ERR_TABLE_IN_FK_CHECK : 0; + return fill_column_values(buf, pos) ? HA_ERR_JSON_TABLE : 0; } @@ -1024,9 +1031,12 @@ int Json_table_nested_path::set_path(THD *thd, const LEX_CSTRING &path) @brief Perform the action of this response on field @f (emit an error, or set @f to NULL, or set it to default value). + error_num supposed to have the error message with field_name and table_name + arguments. */ -int Json_table_column::On_response::respond(Json_table_column *jc, Field *f) +int Json_table_column::On_response::respond(Json_table_column *jc, Field *f, + uint error_num) { switch (m_response) { @@ -1036,8 +1046,7 @@ int Json_table_column::On_response::respond(Json_table_column *jc, Field *f) break; case Json_table_column::RESPONSE_ERROR: f->set_null(); - my_error(ER_JSON_TABLE_ERROR_ON_FIELD, MYF(0), - f->field_name.str, f->table->alias.ptr()); + my_error(error_num, MYF(0), f->field_name.str, f->table->alias.ptr()); return 1; case Json_table_column::RESPONSE_DEFAULT: f->set_notnull(); diff --git a/sql/json_table.h b/sql/json_table.h index e4816e72287..c9df5d8322a 100644 --- a/sql/json_table.h +++ b/sql/json_table.h @@ -141,7 +141,7 @@ public: public: Json_table_column::enum_on_response m_response; LEX_CSTRING m_default; - int respond(Json_table_column *jc, Field *f); + int respond(Json_table_column *jc, Field *f, uint error_num); int print(const char *name, String *str) const; bool specified() const { return m_response != RESPONSE_NOT_SPECIFIED; } }; diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 7f70a0ff337..293dede8d29 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -7979,3 +7979,7 @@ ER_JSON_TABLE_ERROR_ON_FIELD eng "Field '%s' can't be set for JSON_TABLE '%s'." ER_JSON_TABLE_ALIAS_REQUIRED eng "Every table function must have an alias." +ER_JSON_TABLE_SCALAR_EXPECTED + eng "Can't store an array or an object in the scalar column '%s' of JSON_TABLE '%s'." +ER_JSON_TABLE_MULTIPLE_MATCHES + eng "Can't store multiple matches of the path in the column '%s' of JSON_TABLE '%s'."