[Commits] 03a162bc51a: MDEV-25154: JSON_TABLE: Queries involving ordinality columns are unsafe...
revision-id: 03a162bc51aadb8fd71a60bb24806ffea3b828cf (mariadb-10.5.2-589-g03a162bc51a) parent(s): 36c3be336616cb95443c5164a0e082862c6270d0 author: Sergei Petrunia committer: Sergei Petrunia timestamp: 2021-04-20 14:29:36 +0300 message: MDEV-25154: JSON_TABLE: Queries involving ordinality columns are unsafe... Actually the functions are safe for the current version. Still, we will mark the function as SBR-unsafe to be more future-proof. --- mysql-test/suite/json/r/json_table_binlog.result | 26 ++++++++++++++++++++++++ mysql-test/suite/json/t/json_table_binlog.test | 25 +++++++++++++++++++++++ sql/json_table.cc | 16 +++++++++++++++ sql/json_table.h | 7 +------ sql/sql_yacc.yy | 2 +- 5 files changed, 69 insertions(+), 7 deletions(-) diff --git a/mysql-test/suite/json/r/json_table_binlog.result b/mysql-test/suite/json/r/json_table_binlog.result new file mode 100644 index 00000000000..472f7395648 --- /dev/null +++ b/mysql-test/suite/json/r/json_table_binlog.result @@ -0,0 +1,26 @@ +# +# MDEV-25154: JSON_TABLE: Queries involving ordinality columns are unsafe for statement binlog and should be marked as such +# +create table t1 (a int); +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +set binlog_format='statement'; +insert into t1 +select * +from json_table('[1,2,3]', '$[*]' columns (a for ordinality)) as T ; +Warnings: +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system function that may return a different value on the slave +set binlog_format='mixed'; +insert into t1 +select * +from json_table('[1,2,3]', '$[*]' columns (a for ordinality)) as T ; +# This must show Annotate_rows, Write_rows_v1 events. Not the statement event +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Annotate_rows # # insert into t1 +select * +from json_table('[1,2,3]', '$[*]' columns (a for ordinality)) as T +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # COMMIT +drop table t1; diff --git a/mysql-test/suite/json/t/json_table_binlog.test b/mysql-test/suite/json/t/json_table_binlog.test new file mode 100644 index 00000000000..dcc05fb855d --- /dev/null +++ b/mysql-test/suite/json/t/json_table_binlog.test @@ -0,0 +1,25 @@ +--source include/have_binlog_format_mixed.inc + +--echo # +--echo # MDEV-25154: JSON_TABLE: Queries involving ordinality columns are unsafe for statement binlog and should be marked as such +--echo # + +create table t1 (a int); + +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +set binlog_format='statement'; +insert into t1 +select * +from json_table('[1,2,3]', '$[*]' columns (a for ordinality)) as T ; + +set binlog_format='mixed'; +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +let $binlog_file= LAST; + +insert into t1 +select * +from json_table('[1,2,3]', '$[*]' columns (a for ordinality)) as T ; + +--echo # This must show Annotate_rows, Write_rows_v1 events. Not the statement event +--source include/show_binlog_events.inc +drop table t1; diff --git a/sql/json_table.cc b/sql/json_table.cc index a16adc25f08..c07c96e1b7a 100644 --- a/sql/json_table.cc +++ b/sql/json_table.cc @@ -978,6 +978,22 @@ int Json_table_column::On_response::print(const char *name, String *str) const str->append(name)); } +Table_function_json_table::Table_function_json_table(THD *thd, Item *json) : + m_json(json) +{ + cur_parent= &m_nested_path; + last_sibling_hook= &m_nested_path.m_nested; + /* + Currently, the evaluation of JSON_TABLE is deterministic (passing the same + input string will produce the same set of rows in the same order). + In order to be future-proof and to be able to make changes like + - sort array arguments by name (like MySQL does) + - change the way duplicate object members are handled + we mark the function as SBR-unsafe. (If we re-consider, making the function + SBR-safe is easier than making it unsafe) + */ + thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION); +} void Table_function_json_table::start_nested_path(Json_table_nested_path *np) { diff --git a/sql/json_table.h b/sql/json_table.h index 09e4295d80c..f1ae5d5c577 100644 --- a/sql/json_table.h +++ b/sql/json_table.h @@ -225,12 +225,7 @@ class Table_function_json_table : public Sql_alloc String *str, enum_query_type query_type); /*** Construction interface to be used from the parser ***/ - Table_function_json_table(Item *json): - m_json(json) - { - cur_parent= &m_nested_path; - last_sibling_hook= &m_nested_path.m_nested; - } + Table_function_json_table(THD *thd, Item *json); void start_nested_path(Json_table_nested_path *np); void end_nested_path(); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index b92a83665ea..fab17ff7a25 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -11685,7 +11685,7 @@ table_function: expr ',' { Table_function_json_table *jt= - new (thd->mem_root) Table_function_json_table($4); + new (thd->mem_root) Table_function_json_table(thd, $4); if (unlikely(!jt)) MYSQL_YYABORT; Lex->json_table= jt;
participants (1)
-
psergey