From 01c9d1c97fdfc5b72e967aaac0ebf29a039bd3d5 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Tue, 18 Oct 2016 16:35:52 +0000 Subject: [PATCH] SQL: SP idempotency fix Fixes #52 --- .../suite/versioning/r/auto_increment.result | 38 ++++++++++++++ .../suite/versioning/t/auto_increment.test | 3 +- sql/sql_select.cc | 52 +++++++++++-------- 3 files changed, 70 insertions(+), 23 deletions(-) diff --git a/mysql-test/suite/versioning/r/auto_increment.result b/mysql-test/suite/versioning/r/auto_increment.result index bd1c3f9828e..9dc0075d06d 100644 --- a/mysql-test/suite/versioning/r/auto_increment.result +++ b/mysql-test/suite/versioning/r/auto_increment.result @@ -93,7 +93,45 @@ A x y x y 1 5 15 5 15 1 6 16 6 16 1 7 17 7 17 +call test_01('bigint unsigned', 'innodb', 'commit_ts(sys_end)'); +A x y x y +1 1 11 1 11 +1 2 12 2 12 +1 3 13 3 13 +1 4 14 4 14 +1 5 15 5 15 +1 6 16 6 16 +1 7 17 7 17 +1 8 18 8 18 +1 9 19 9 19 +A x y x y +1 1 11 1 11 +1 3 13 3 13 +1 4 14 4 14 +1 5 15 5 15 +1 6 16 6 16 +1 7 17 7 17 +1 8 18 8 18 +1 9 19 9 19 +A x y x y +1 1 11 1 11 +1 3 13 3 13 +1 4 14 4 14 +1 5 15 5 15 +1 6 16 6 16 +1 7 17 7 17 call verify_vtq; No A B C D +1 1 1 1 1 +2 1 1 1 1 +3 1 1 1 1 +4 1 1 1 1 +5 1 1 1 1 +6 1 1 1 1 +7 1 1 1 1 +8 1 1 1 1 +9 1 1 1 1 +10 1 1 1 1 +11 1 1 1 1 drop procedure test_01; drop procedure verify_vtq; diff --git a/mysql-test/suite/versioning/t/auto_increment.test b/mysql-test/suite/versioning/t/auto_increment.test index 4872428ff7d..dac46caed06 100644 --- a/mysql-test/suite/versioning/t/auto_increment.test +++ b/mysql-test/suite/versioning/t/auto_increment.test @@ -60,8 +60,7 @@ end~~ delimiter ;~~ call test_01('timestamp(6)', 'myisam', 'sys_end'); -# Issue #52 -# call test_01('bigint unsigned', 'innodb', 'commit_ts(sys_end)'); +call test_01('bigint unsigned', 'innodb', 'commit_ts(sys_end)'); call verify_vtq; drop procedure test_01; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index eec6f742d9d..4e7ca4663b1 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -701,44 +701,54 @@ setup_for_system_time(THD *thd, TABLE_LIST *tables, COND **where_expr, SELECT_LE if (select_lex->saved_where) { DBUG_ASSERT(thd->stmt_arena->is_sp_execute()); - *where_expr= select_lex->saved_where; + /* 2. this copy_andor_structure() is also required by the same reason */ + *where_expr= select_lex->saved_where->copy_andor_structure(thd); } else if (thd->stmt_arena->is_sp_execute()) { if (thd->stmt_arena->is_stmt_execute()) // SP executed second time (STMT_EXECUTED) *where_expr= 0; else if (*where_expr) // SP executed first time (STMT_INITIALIZED_FOR_SP) - /* copy_andor_structure() is required since this andor tree + /* 1. copy_andor_structure() is required since this andor tree is modified later (and on shorter arena) */ select_lex->saved_where= (*where_expr)->copy_andor_structure(thd); } + /* We have to save also non-versioned on_expr since we may have + conjuction of versioned + non-versioned */ + if (thd->stmt_arena->is_sp_execute()) + { + for (table= tables; table; table= table->next_local) + { + if (!table->table) + continue; + + if (table->saved_on_expr) // same logic as saved_where + { + if (table->on_expr) + table->on_expr= table->saved_on_expr->copy_andor_structure(thd); + else + // on_expr was moved to WHERE (see below: Add ON expression to the WHERE) + *where_expr= and_items(thd, + *where_expr, + table->saved_on_expr->copy_andor_structure(thd)); + } + else if (table->on_expr && + thd->stmt_arena->state == Query_arena::STMT_INITIALIZED_FOR_SP) + { + table->saved_on_expr= table->on_expr->copy_andor_structure(thd); + } + } + } + for (table= tables; table; table= table->next_local) { if (table->table && table->table->versioned()) { COND** dst_cond= where_expr; - if (table->saved_on_expr) // same logic as saved_where - { - DBUG_ASSERT(thd->stmt_arena->is_sp_execute()); - if (table->on_expr) - { - table->on_expr= table->saved_on_expr; - dst_cond= &table->on_expr; - } - else - { - // on_expr was moved to WHERE (see below: Add ON expression to the WHERE) - *dst_cond= and_items(thd, - *where_expr, - table->saved_on_expr); - } - } - else if (table->on_expr) + if (table->on_expr) { dst_cond= &table->on_expr; - if (thd->stmt_arena->state == Query_arena::STMT_INITIALIZED_FOR_SP) - table->saved_on_expr= table->on_expr->copy_andor_structure(thd); } Field *fstart= table->table->vers_start_field();