mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-25822 JSON_TABLE: default values should allow non-string literals
(Polished initial patch by Alexey Botchkov) Make the code handle DEFAULT values of any datatype - Make Json_table_column::On_response::m_default be Item*, not LEX_STRING. - Change the parser to use string literal non-terminals for producing the DEFAULT value -- Also, stop updating json_table->m_text_literal_cs for the DEFAULT value literals as it is not used.
This commit is contained in:
@@ -1036,5 +1036,50 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
2 DEPENDENT SUBQUERY jt ALL NULL NULL NULL NULL 40 Table function: json_table
|
||||
drop table t1;
|
||||
#
|
||||
# MDEV-25822: JSON_TABLE: default values should allow non-string literals
|
||||
#
|
||||
select * from json_table('{"a": "b"}', '$' columns(col1 varchar(32) path '$.fooo' default 0.5 on empty)) as T;
|
||||
col1
|
||||
0.5
|
||||
select * from json_table('{"a": "b"}', '$' columns(col1 varchar(32) path '$.fooo' default 5 on empty)) as T;
|
||||
col1
|
||||
5
|
||||
select * from json_table('{"a": "b"}', '$' columns(col1 varchar(32) path '$.fooo' default 'asdf' on empty)) as T;
|
||||
col1
|
||||
asdf
|
||||
select * from json_table('{"a": "b"}', '$' columns(col1 varchar(32) path '$.fooo' default -0.5 on empty)) as T;
|
||||
col1
|
||||
-0.5
|
||||
select * from json_table('{"a": "b"}', '$' columns(col1 varchar(32) path '$.fooo' default 18446744073709551615 on empty)) as T;
|
||||
col1
|
||||
18446744073709551615
|
||||
select * from json_table('{"a": "b"}', '$' columns(col1 varchar(32) path '$.fooo' default DATE '2021-01-01' on empty)) as T;
|
||||
col1
|
||||
2021-01-01
|
||||
create view v as select * from json_table('{"a": "b"}', '$' columns(col1 varchar(32) path '$.fooo' default 5 on empty)) as T;
|
||||
select * from v;
|
||||
col1
|
||||
5
|
||||
show create view v;
|
||||
View Create View character_set_client collation_connection
|
||||
v CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v` AS select `T`.`col1` AS `col1` from JSON_TABLE('{"a": "b"}', '$' COLUMNS (`col1` varchar(32) PATH '$.fooo' DEFAULT 5 ON EMPTY)) `T` latin1 latin1_swedish_ci
|
||||
drop view v;
|
||||
create view v as select * from json_table('{"a": "b"}', '$' columns(col1 varchar(32) path '$.fooo' default 18446744073709551615 on empty)) as T;
|
||||
select * from v;
|
||||
col1
|
||||
18446744073709551615
|
||||
show create view v;
|
||||
View Create View character_set_client collation_connection
|
||||
v CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v` AS select `T`.`col1` AS `col1` from JSON_TABLE('{"a": "b"}', '$' COLUMNS (`col1` varchar(32) PATH '$.fooo' DEFAULT 18446744073709551615 ON EMPTY)) `T` latin1 latin1_swedish_ci
|
||||
drop view v;
|
||||
create view v as select * from json_table('{"a": "b"}', '$' columns(col1 varchar(32) path '$.fooo' default 'asdf' on empty)) as T;
|
||||
select * from v;
|
||||
col1
|
||||
asdf
|
||||
show create view v;
|
||||
View Create View character_set_client collation_connection
|
||||
v CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v` AS select `T`.`col1` AS `col1` from JSON_TABLE('{"a": "b"}', '$' COLUMNS (`col1` varchar(32) PATH '$.fooo' DEFAULT 'asdf' ON EMPTY)) `T` latin1 latin1_swedish_ci
|
||||
drop view v;
|
||||
#
|
||||
# End of 10.6 tests
|
||||
#
|
||||
|
@@ -545,10 +545,12 @@ Warning 1366 Incorrect double value: 'asdf' for column ``.`(temporary)`.`f` at r
|
||||
Warning 1366 Incorrect decimal value: 'asdf' for column ``.`(temporary)`.`d` at row 1
|
||||
SELECT * FROM
|
||||
JSON_TABLE('{}', '$' COLUMNS (x INT PATH '$.x' DEFAULT NULL ON EMPTY)) jt;
|
||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'NULL ON EMPTY)) jt' at line 2
|
||||
x
|
||||
NULL
|
||||
SELECT * FROM
|
||||
JSON_TABLE('{}', '$' COLUMNS (x INT PATH '$.x' DEFAULT NULL ON ERROR)) jt;
|
||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'NULL ON ERROR)) jt' at line 2
|
||||
x
|
||||
NULL
|
||||
SELECT * FROM
|
||||
JSON_TABLE('{}', '$' COLUMNS (x INT PATH '$.x' DEFAULT 0 ON EMPTY)) jt;
|
||||
x
|
||||
@@ -561,12 +563,14 @@ SELECT * FROM
|
||||
JSON_TABLE('{}', '$' COLUMNS (x DATE
|
||||
PATH '$.x'
|
||||
DEFAULT DATE'2020-01-01' ON EMPTY)) jt;
|
||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'DATE'2020-01-01' ON EMPTY)) jt' at line 4
|
||||
x
|
||||
2020-01-01
|
||||
SELECT * FROM
|
||||
JSON_TABLE('{}', '$' COLUMNS (x DATE
|
||||
PATH '$.x'
|
||||
DEFAULT DATE'2020-01-01' ON ERROR)) jt;
|
||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'DATE'2020-01-01' ON ERROR)) jt' at line 4
|
||||
x
|
||||
NULL
|
||||
#
|
||||
# Bug#25413069: SIG11 IN CHECK_COLUMN_GRANT_IN_TABLE_REF
|
||||
#
|
||||
|
@@ -893,6 +893,30 @@ explain select c,
|
||||
|
||||
drop table t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-25822: JSON_TABLE: default values should allow non-string literals
|
||||
--echo #
|
||||
select * from json_table('{"a": "b"}', '$' columns(col1 varchar(32) path '$.fooo' default 0.5 on empty)) as T;
|
||||
select * from json_table('{"a": "b"}', '$' columns(col1 varchar(32) path '$.fooo' default 5 on empty)) as T;
|
||||
select * from json_table('{"a": "b"}', '$' columns(col1 varchar(32) path '$.fooo' default 'asdf' on empty)) as T;
|
||||
select * from json_table('{"a": "b"}', '$' columns(col1 varchar(32) path '$.fooo' default -0.5 on empty)) as T;
|
||||
select * from json_table('{"a": "b"}', '$' columns(col1 varchar(32) path '$.fooo' default 18446744073709551615 on empty)) as T;
|
||||
select * from json_table('{"a": "b"}', '$' columns(col1 varchar(32) path '$.fooo' default DATE '2021-01-01' on empty)) as T;
|
||||
|
||||
create view v as select * from json_table('{"a": "b"}', '$' columns(col1 varchar(32) path '$.fooo' default 5 on empty)) as T;
|
||||
select * from v;
|
||||
show create view v;
|
||||
drop view v;
|
||||
create view v as select * from json_table('{"a": "b"}', '$' columns(col1 varchar(32) path '$.fooo' default 18446744073709551615 on empty)) as T;
|
||||
select * from v;
|
||||
show create view v;
|
||||
drop view v;
|
||||
create view v as select * from json_table('{"a": "b"}', '$' columns(col1 varchar(32) path '$.fooo' default 'asdf' on empty)) as T;
|
||||
select * from v;
|
||||
show create view v;
|
||||
drop view v;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # End of 10.6 tests
|
||||
--echo #
|
||||
|
@@ -445,11 +445,8 @@ SELECT * FROM JSON_TABLE('"asdf"', '$' COLUMNS(
|
||||
f FLOAT PATH '$',
|
||||
d DECIMAL PATH '$')) AS jt;
|
||||
|
||||
# DEFAULT NULL is not accepted syntax.
|
||||
--error ER_PARSE_ERROR
|
||||
SELECT * FROM
|
||||
JSON_TABLE('{}', '$' COLUMNS (x INT PATH '$.x' DEFAULT NULL ON EMPTY)) jt;
|
||||
--error ER_PARSE_ERROR
|
||||
SELECT * FROM
|
||||
JSON_TABLE('{}', '$' COLUMNS (x INT PATH '$.x' DEFAULT NULL ON ERROR)) jt;
|
||||
|
||||
@@ -457,13 +454,10 @@ SELECT * FROM
|
||||
JSON_TABLE('{}', '$' COLUMNS (x INT PATH '$.x' DEFAULT 0 ON EMPTY)) jt;
|
||||
SELECT * FROM
|
||||
JSON_TABLE('{}', '$' COLUMNS (x INT PATH '$.x' DEFAULT 0 ON ERROR)) jt;
|
||||
# We don't accept dates in DEFAULT
|
||||
--error 1064
|
||||
SELECT * FROM
|
||||
JSON_TABLE('{}', '$' COLUMNS (x DATE
|
||||
PATH '$.x'
|
||||
DEFAULT DATE'2020-01-01' ON EMPTY)) jt;
|
||||
--error 1064
|
||||
SELECT * FROM
|
||||
JSON_TABLE('{}', '$' COLUMNS (x DATE
|
||||
PATH '$.x'
|
||||
|
@@ -1030,8 +1030,7 @@ int Json_table_column::On_response::respond(Json_table_column *jc, Field *f,
|
||||
return 1;
|
||||
case Json_table_column::RESPONSE_DEFAULT:
|
||||
f->set_notnull();
|
||||
f->store(m_default.str,
|
||||
m_default.length, jc->m_defaults_cs);
|
||||
m_default->save_in_field(f, TRUE);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
@@ -1041,7 +1040,11 @@ int Json_table_column::On_response::respond(Json_table_column *jc, Field *f,
|
||||
int Json_table_column::On_response::print(const char *name, String *str) const
|
||||
{
|
||||
LEX_CSTRING resp;
|
||||
const LEX_CSTRING *ds= NULL;
|
||||
|
||||
char valbuf[512];
|
||||
String val(valbuf, sizeof(valbuf), str->charset());
|
||||
String *ds= NULL;
|
||||
|
||||
if (m_response == Json_table_column::RESPONSE_NOT_SPECIFIED)
|
||||
return 0;
|
||||
|
||||
@@ -1056,7 +1059,7 @@ int Json_table_column::On_response::print(const char *name, String *str) const
|
||||
case Json_table_column::RESPONSE_DEFAULT:
|
||||
{
|
||||
lex_string_set3(&resp, STRING_WITH_LEN("DEFAULT"));
|
||||
ds= &m_default;
|
||||
ds= m_default->val_str(&val);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -1065,9 +1068,14 @@ int Json_table_column::On_response::print(const char *name, String *str) const
|
||||
}
|
||||
|
||||
return (str->append(' ') || str->append(resp) ||
|
||||
(ds && (str->append(STRING_WITH_LEN(" '")) ||
|
||||
str->append_for_single_quote(ds->str, ds->length) ||
|
||||
str->append('\''))) ||
|
||||
(ds &&
|
||||
(str->append(' ') ||
|
||||
(m_default->result_type()==STRING_RESULT && str->append('\''))||
|
||||
|
||||
str->append_for_single_quote(ds) ||
|
||||
|
||||
(m_default->result_type()==STRING_RESULT && str->append('\''))))||
|
||||
|
||||
str->append(STRING_WITH_LEN(" ON ")) ||
|
||||
str->append(name, strlen(name)));
|
||||
}
|
||||
|
@@ -140,7 +140,7 @@ public:
|
||||
{
|
||||
public:
|
||||
Json_table_column::enum_on_response m_response;
|
||||
LEX_CSTRING m_default;
|
||||
Item *m_default;
|
||||
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; }
|
||||
@@ -154,7 +154,6 @@ public:
|
||||
Create_field *m_field;
|
||||
Json_table_nested_path *m_nest;
|
||||
CHARSET_INFO *m_explicit_cs;
|
||||
CHARSET_INFO *m_defaults_cs;
|
||||
|
||||
void set(enum_type ctype)
|
||||
{
|
||||
|
@@ -1328,7 +1328,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
|
||||
TEXT_STRING
|
||||
NCHAR_STRING
|
||||
json_text_literal
|
||||
json_text_literal_or_num
|
||||
|
||||
%type <lex_str_ptr>
|
||||
opt_table_alias_clause
|
||||
@@ -1512,6 +1511,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
|
||||
simple_target_specification
|
||||
condition_number
|
||||
opt_versioning_interval_start
|
||||
json_default_literal
|
||||
|
||||
%type <item_param> param_marker
|
||||
|
||||
@@ -11595,26 +11595,6 @@ json_text_literal:
|
||||
}
|
||||
;
|
||||
|
||||
json_text_literal_or_num:
|
||||
json_text_literal
|
||||
| NUM
|
||||
{
|
||||
Lex->json_table->m_text_literal_cs= NULL;
|
||||
}
|
||||
| LONG_NUM
|
||||
{
|
||||
Lex->json_table->m_text_literal_cs= NULL;
|
||||
}
|
||||
| DECIMAL_NUM
|
||||
{
|
||||
Lex->json_table->m_text_literal_cs= NULL;
|
||||
}
|
||||
| FLOAT_NUM
|
||||
{
|
||||
Lex->json_table->m_text_literal_cs= NULL;
|
||||
}
|
||||
;
|
||||
|
||||
join_table_list:
|
||||
derived_table_list { MYSQL_YYABORT_UNLESS($$=$1); }
|
||||
;
|
||||
@@ -11720,6 +11700,12 @@ json_opt_on_empty_or_error:
|
||||
| json_on_empty_response json_on_error_response
|
||||
;
|
||||
|
||||
json_default_literal:
|
||||
literal
|
||||
| signed_literal
|
||||
;
|
||||
|
||||
|
||||
json_on_response:
|
||||
ERROR_SYM
|
||||
{
|
||||
@@ -11729,12 +11715,10 @@ json_on_response:
|
||||
{
|
||||
$$.m_response= Json_table_column::RESPONSE_NULL;
|
||||
}
|
||||
| DEFAULT json_text_literal_or_num
|
||||
| DEFAULT json_default_literal
|
||||
{
|
||||
$$.m_response= Json_table_column::RESPONSE_DEFAULT;
|
||||
$$.m_default= $2;
|
||||
Lex->json_table->m_cur_json_table_column->m_defaults_cs=
|
||||
thd->variables.collation_connection;
|
||||
}
|
||||
;
|
||||
|
||||
|
Reference in New Issue
Block a user