diff --git a/mysql-test/suite/json/r/json_table.result b/mysql-test/suite/json/r/json_table.result index 20e1a4b1225..2260b8c1f55 100644 --- a/mysql-test/suite/json/r/json_table.result +++ b/mysql-test/suite/json/r/json_table.result @@ -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 # diff --git a/mysql-test/suite/json/r/json_table_mysql.result b/mysql-test/suite/json/r/json_table_mysql.result index 699d5a8b4f3..5f9c437ee6b 100644 --- a/mysql-test/suite/json/r/json_table_mysql.result +++ b/mysql-test/suite/json/r/json_table_mysql.result @@ -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 # diff --git a/mysql-test/suite/json/t/json_table.test b/mysql-test/suite/json/t/json_table.test index 580a8507c8f..ae8deffc0fe 100644 --- a/mysql-test/suite/json/t/json_table.test +++ b/mysql-test/suite/json/t/json_table.test @@ -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 # diff --git a/mysql-test/suite/json/t/json_table_mysql.test b/mysql-test/suite/json/t/json_table_mysql.test index 9f77ad964f3..8595c0e15e8 100644 --- a/mysql-test/suite/json/t/json_table_mysql.test +++ b/mysql-test/suite/json/t/json_table_mysql.test @@ -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' diff --git a/sql/json_table.cc b/sql/json_table.cc index d4ba9f88a78..86f565aa561 100644 --- a/sql/json_table.cc +++ b/sql/json_table.cc @@ -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))); } diff --git a/sql/json_table.h b/sql/json_table.h index 7316edd4ee6..545dfb0aa90 100644 --- a/sql/json_table.h +++ b/sql/json_table.h @@ -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) { diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index ed2bcd5deb9..50a115a3201 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -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 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 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; } ;