Commit d2e2219e authored by Alexey Botchkov's avatar Alexey Botchkov

MDEV-25146 JSON_TABLE: Non-descriptive + wrong error messages upon trying to store array or object.

More informative messages added.
Do not issue additional messages if already handled.
parent 48dffa3c
...@@ -88,7 +88,7 @@ a b ...@@ -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; 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 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; 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; select * from json_table('{"a":0}',"$" columns(a decimal(1,1) path '$.a')) foo;
a a
0.0 0.0
...@@ -573,5 +573,13 @@ id ...@@ -573,5 +573,13 @@ id
3 3
drop table json_table; 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 # End of 10.6 tests
# #
...@@ -115,7 +115,7 @@ json_table( ...@@ -115,7 +115,7 @@ json_table(
jpath varchar(100) path '$.a' error on error, jpath varchar(100) path '$.a' error on error,
jexst int exists path '$.b') jexst int exists path '$.b')
) as tt; ) 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 select * from
json_table( json_table(
'!#@$!@#$', '!#@$!@#$',
...@@ -396,18 +396,18 @@ v CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIE ...@@ -396,18 +396,18 @@ v CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIE
DROP VIEW v; DROP VIEW v;
SELECT * FROM JSON_TABLE('"asdf"', SELECT * FROM JSON_TABLE('"asdf"',
'$' COLUMNS (a INT PATH '$' ERROR ON ERROR)) AS jt; '$' 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 SELECT * FROM
JSON_TABLE('[{"a":1},{"a":2}]', JSON_TABLE('[{"a":1},{"a":2}]',
'$' COLUMNS (a INT PATH '$[*].a' ERROR ON ERROR)) AS jt; '$' 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 SELECT * FROM
JSON_TABLE('[{"a":1},{"a":2}]', JSON_TABLE('[{"a":1},{"a":2}]',
'$' COLUMNS (a JSON PATH '$[*].a' ERROR ON ERROR)) AS jt; '$' 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 SELECT * FROM
JSON_TABLE('123.456', '$' COLUMNS (a DECIMAL(2,1) PATH '$' ERROR ON ERROR)) AS jt; 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 SELECT * FROM
JSON_TABLE('123.456', '$' COLUMNS (a DECIMAL(2,1) PATH '$')) AS jt; JSON_TABLE('123.456', '$' COLUMNS (a DECIMAL(2,1) PATH '$')) AS jt;
a a
...@@ -811,7 +811,7 @@ SELECT * FROM ...@@ -811,7 +811,7 @@ SELECT * FROM
JSON_TABLE('[3.14159]', JSON_TABLE('[3.14159]',
'$[*]' COLUMNS (col18 DECIMAL(3,3) PATH '$' ERROR ON ERROR) '$[*]' COLUMNS (col18 DECIMAL(3,3) PATH '$' ERROR ON ERROR)
) AS alias2; ) 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 SELECT * FROM
JSON_TABLE('[0.9]', JSON_TABLE('[0.9]',
'$[*]' COLUMNS (col18 DECIMAL(3,3) PATH '$') '$[*]' COLUMNS (col18 DECIMAL(3,3) PATH '$')
......
...@@ -41,7 +41,7 @@ select * from JSON_TABLE( '[ {"a": [1, 2], "b": [11,111]}, {"a": 2, "b": [22,222 ...@@ -41,7 +41,7 @@ select * from JSON_TABLE( '[ {"a": [1, 2], "b": [11,111]}, {"a": 2, "b": [22,222
--error ER_JSON_SYNTAX --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; 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; 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); ...@@ -446,6 +446,13 @@ insert into json_table values (1), (2), (3);
select * from json_table; select * from json_table;
drop table 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 #
--echo # End of 10.6 tests --echo # End of 10.6 tests
--echo # --echo #
...@@ -91,7 +91,7 @@ select * from ...@@ -91,7 +91,7 @@ select * from
jexst int exists path '$.b') jexst int exists path '$.b')
) as tt; ) as tt;
--error ER_JSON_TABLE_ERROR_ON_FIELD --error ER_JSON_TABLE_SCALAR_EXPECTED
select * from select * from
json_table( json_table(
'[{"a":"3"},{"a":2},{"a":1},{"a":[0,1]}]', '[{"a":"3"},{"a":2},{"a":1},{"a":[0,1]}]',
...@@ -327,20 +327,19 @@ SELECT * FROM v; ...@@ -327,20 +327,19 @@ SELECT * FROM v;
SHOW CREATE VIEW v; SHOW CREATE VIEW v;
DROP VIEW v; DROP VIEW v;
--error ER_JSON_TABLE_ERROR_ON_FIELD --error ER_JSON_TABLE_SCALAR_EXPECTED
SELECT * FROM JSON_TABLE('"asdf"', SELECT * FROM JSON_TABLE('"asdf"',
'$' COLUMNS (a INT PATH '$' ERROR ON ERROR)) AS jt; '$' COLUMNS (a INT PATH '$' ERROR ON ERROR)) AS jt;
#--error ER_WRONG_JSON_TABLE_VALUE --error ER_JSON_TABLE_MULTIPLE_MATCHES
--error ER_JSON_TABLE_ERROR_ON_FIELD
SELECT * FROM SELECT * FROM
JSON_TABLE('[{"a":1},{"a":2}]', JSON_TABLE('[{"a":1},{"a":2}]',
'$' COLUMNS (a INT PATH '$[*].a' ERROR ON ERROR)) AS jt; '$' COLUMNS (a INT PATH '$[*].a' ERROR ON ERROR)) AS jt;
# psergey-added: # psergey-added:
--error ER_JSON_TABLE_ERROR_ON_FIELD --error ER_JSON_TABLE_MULTIPLE_MATCHES
SELECT * FROM SELECT * FROM
JSON_TABLE('[{"a":1},{"a":2}]', JSON_TABLE('[{"a":1},{"a":2}]',
'$' COLUMNS (a JSON PATH '$[*].a' ERROR ON ERROR)) AS jt; '$' 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 SELECT * FROM
JSON_TABLE('123.456', '$' COLUMNS (a DECIMAL(2,1) PATH '$' ERROR ON ERROR)) AS jt; JSON_TABLE('123.456', '$' COLUMNS (a DECIMAL(2,1) PATH '$' ERROR ON ERROR)) AS jt;
SELECT * FROM SELECT * FROM
...@@ -722,7 +721,7 @@ SELECT * FROM ...@@ -722,7 +721,7 @@ SELECT * FROM
) AS alias2; ) AS alias2;
#--error ER_JT_VALUE_OUT_OF_RANGE #--error ER_JT_VALUE_OUT_OF_RANGE
--error ER_JSON_TABLE_ERROR_ON_FIELD --error ER_JSON_TABLE_SCALAR_EXPECTED
SELECT * FROM SELECT * FROM
JSON_TABLE('[3.14159]', JSON_TABLE('[3.14159]',
'$[*]' COLUMNS (col18 DECIMAL(3,3) PATH '$' ERROR ON ERROR) '$[*]' COLUMNS (col18 DECIMAL(3,3) PATH '$' ERROR ON ERROR)
......
...@@ -4225,7 +4225,11 @@ void handler::print_error(int error, myf errflag) ...@@ -4225,7 +4225,11 @@ void handler::print_error(int error, myf errflag)
} }
} }
else else
{
if (!temporary)
my_error(ER_GET_ERRNO, errflag, error, table_type()); my_error(ER_GET_ERRNO, errflag, error, table_type());
/* else no error message. */
}
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
} }
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "json_table.h" #include "json_table.h"
#include "sql_show.h" #include "sql_show.h"
#define HA_ERR_JSON_TABLE (HA_ERR_LAST+1)
class table_function_handlerton class table_function_handlerton
{ {
...@@ -104,6 +105,12 @@ class ha_json_table: public handler ...@@ -104,6 +105,12 @@ class ha_json_table: public handler
{ return NULL; } { return NULL; }
int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info) int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info)
override { return 1; } 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) ...@@ -284,7 +291,7 @@ int ha_json_table::rnd_next(uchar *buf)
error code that just doesn't produce extra error code that just doesn't produce extra
messages. messages.
*/ */
return HA_ERR_TABLE_IN_FK_CHECK; return HA_ERR_JSON_TABLE;
} }
return HA_ERR_END_OF_FILE; return HA_ERR_END_OF_FILE;
} }
...@@ -297,7 +304,7 @@ int ha_json_table::rnd_next(uchar *buf) ...@@ -297,7 +304,7 @@ int ha_json_table::rnd_next(uchar *buf)
table->in_use->count_cuted_fields= CHECK_FIELD_EXPRESSION; table->in_use->count_cuted_fields= CHECK_FIELD_EXPRESSION;
res= fill_column_values(buf, NULL); res= fill_column_values(buf, NULL);
table->in_use->count_cuted_fields= cf_orig; 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) ...@@ -401,7 +408,7 @@ int ha_json_table::fill_column_values(uchar * buf, uchar *pos)
{ {
if (not_found) 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; goto error_return;
} }
else else
...@@ -409,7 +416,7 @@ int ha_json_table::fill_column_values(uchar * buf, uchar *pos) ...@@ -409,7 +416,7 @@ int ha_json_table::fill_column_values(uchar * buf, uchar *pos)
if (!json_value_scalar(&je) || if (!json_value_scalar(&je) ||
store_json_in_field(*f, &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; goto error_return;
} }
else else
...@@ -424,7 +431,7 @@ int ha_json_table::fill_column_values(uchar * buf, uchar *pos) ...@@ -424,7 +431,7 @@ int ha_json_table::fill_column_values(uchar * buf, uchar *pos)
!json_find_path(&je, &jc->m_path, &cur_step, !json_find_path(&je, &jc->m_path, &cur_step,
array_counters))) 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; goto error_return;
} }
} }
...@@ -449,7 +456,7 @@ int ha_json_table::fill_column_values(uchar * buf, uchar *pos) ...@@ -449,7 +456,7 @@ int ha_json_table::fill_column_values(uchar * buf, uchar *pos)
int ha_json_table::rnd_pos(uchar * buf, uchar *pos) 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) ...@@ -1024,9 +1031,12 @@ int Json_table_nested_path::set_path(THD *thd, const LEX_CSTRING &path)
@brief @brief
Perform the action of this response on field @f (emit an error, or set @f Perform the action of this response on field @f (emit an error, or set @f
to NULL, or set it to default value). 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) switch (m_response)
{ {
...@@ -1036,8 +1046,7 @@ int Json_table_column::On_response::respond(Json_table_column *jc, Field *f) ...@@ -1036,8 +1046,7 @@ int Json_table_column::On_response::respond(Json_table_column *jc, Field *f)
break; break;
case Json_table_column::RESPONSE_ERROR: case Json_table_column::RESPONSE_ERROR:
f->set_null(); f->set_null();
my_error(ER_JSON_TABLE_ERROR_ON_FIELD, MYF(0), my_error(error_num, MYF(0), f->field_name.str, f->table->alias.ptr());
f->field_name.str, f->table->alias.ptr());
return 1; return 1;
case Json_table_column::RESPONSE_DEFAULT: case Json_table_column::RESPONSE_DEFAULT:
f->set_notnull(); f->set_notnull();
......
...@@ -141,7 +141,7 @@ class Json_table_column : public Sql_alloc ...@@ -141,7 +141,7 @@ class Json_table_column : public Sql_alloc
public: public:
Json_table_column::enum_on_response m_response; Json_table_column::enum_on_response m_response;
LEX_CSTRING m_default; 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; int print(const char *name, String *str) const;
bool specified() const { return m_response != RESPONSE_NOT_SPECIFIED; } bool specified() const { return m_response != RESPONSE_NOT_SPECIFIED; }
}; };
......
...@@ -7979,3 +7979,7 @@ ER_JSON_TABLE_ERROR_ON_FIELD ...@@ -7979,3 +7979,7 @@ ER_JSON_TABLE_ERROR_ON_FIELD
eng "Field '%s' can't be set for JSON_TABLE '%s'." eng "Field '%s' can't be set for JSON_TABLE '%s'."
ER_JSON_TABLE_ALIAS_REQUIRED ER_JSON_TABLE_ALIAS_REQUIRED
eng "Every table function must have an alias." 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'."
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment