diff --git a/mysql-test/suite/versioning/r/select.result b/mysql-test/suite/versioning/r/select.result index 7ffff3b3bdc..23d4202a5a4 100644 --- a/mysql-test/suite/versioning/r/select.result +++ b/mysql-test/suite/versioning/r/select.result @@ -320,7 +320,7 @@ select * from t1 where (a, 2) in ((1, 1), (2, 2)) and b = 1; a b drop view v1; drop table t1, t2; -call innodb_verify_vtq(29); +call innodb_verify_vtq(30); No A B C D 1 1 1 1 1 2 1 1 1 1 diff --git a/mysql-test/suite/versioning/t/select.test b/mysql-test/suite/versioning/t/select.test index 2bf0e1d7f0f..f06fca1dbe4 100644 --- a/mysql-test/suite/versioning/t/select.test +++ b/mysql-test/suite/versioning/t/select.test @@ -216,6 +216,6 @@ select * from t1 where (a, 2) in ((1, 1), (2, 2)) and b = 1; drop view v1; drop table t1, t2; -call innodb_verify_vtq(29); +call innodb_verify_vtq(30); -- source suite/versioning/common_finish.inc diff --git a/sql/item.cc b/sql/item.cc index 25d57105654..88cd7305fdd 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -10379,7 +10379,7 @@ Item_field::excl_dep_on_grouping_fields(st_select_lex *sel) return find_matching_grouping_field(this, sel) != NULL; } -Item *Item_field::vers_optimized_fields_transformer(THD *thd, uchar *) +Item *Item_field::vers_transformer(THD *thd, uchar *) { if (!field) return this; diff --git a/sql/item.h b/sql/item.h index 7e8c0c86ac0..b81af3db4de 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1768,7 +1768,7 @@ public: virtual Item_field *field_for_view_update() { return 0; } - virtual Item *vers_optimized_fields_transformer(THD *thd, uchar *) + virtual Item *vers_transformer(THD *thd, uchar *) { return this; } virtual bool vers_trx_id() const { return false; } @@ -2916,7 +2916,7 @@ public: uint32 max_display_length() const { return field->max_display_length(); } Item_field *field_for_view_update() { return this; } int fix_outer_field(THD *thd, Field **field, Item **reference); - virtual Item *vers_optimized_fields_transformer(THD *thd, uchar *); + virtual Item *vers_transformer(THD *thd, uchar *); virtual bool vers_trx_id() const; virtual Item *update_value_transformer(THD *thd, uchar *select_arg); Item *derived_field_transformer_for_having(THD *thd, uchar *arg); diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index aec30da1894..2c5f109e2ed 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -314,7 +314,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, DBUG_ASSERT(table); DBUG_ASSERT(!conds); - if (vers_setup_select(thd, table_list, &conds, select_lex)) + if (select_lex->vers_setup_conds(thd, table_list, &conds)) DBUG_RETURN(TRUE); // trx_sees() in InnoDB reads sys_trx_start diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index f059ff93ec8..6f79d443345 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -2228,7 +2228,6 @@ void st_select_lex::init_query() join= 0; having= prep_having= where= prep_where= 0; cond_pushed_into_where= cond_pushed_into_having= 0; - saved_where= 0; olap= UNSPECIFIED_OLAP_TYPE; having_fix_field= 0; context.select_lex= this; @@ -2311,8 +2310,10 @@ void st_select_lex::init_select() in_funcs.empty(); curr_tvc_name= 0; in_tvc= false; - vers_import_outer= false; + vers_saved_where= NULL; vers_export_outer.empty(); + vers_import_outer= false; + versioned_tables= 0; } /* diff --git a/sql/sql_lex.h b/sql/sql_lex.h index c20d0d5aa18..a58bd9725ea 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -836,7 +836,6 @@ public: Item *prep_having;/* saved HAVING clause for prepared statement processing */ Item *cond_pushed_into_where; /* condition pushed into the select's WHERE */ Item *cond_pushed_into_having; /* condition pushed into the select's HAVING */ - Item *saved_where; /* Saved values of the WHERE and HAVING clauses*/ Item::cond_result cond_value, having_value; /* point on lex in which it was created, used in view subquery detection */ @@ -1038,9 +1037,14 @@ public: table_value_constr *tvc; bool in_tvc; - /* System Versioning */ + /** System Versioning */ +private: + Item *vers_saved_where; +public: vers_select_conds_t vers_export_outer; bool vers_import_outer; + uint versioned_tables; + int vers_setup_conds(THD *thd, TABLE_LIST *tables, COND **where_expr); /* push new Item_field into item_list */ bool vers_push_field(THD *thd, TABLE_LIST *table, const LEX_CSTRING field_name); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 36d9d01e1ec..87c56b3e3f5 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -690,14 +690,40 @@ bool vers_select_conds_t::init_from_sysvar(THD *thd) return false; } -int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr, - SELECT_LEX *slex) +inline +void JOIN::vers_check_items() { - DBUG_ENTER("vers_setup_select"); + Item_transformer transformer= &Item::vers_transformer; + + if (conds) + { + conds= conds->transform(thd, transformer, NULL); + } + + for (ORDER *ord= order; ord; ord= ord->next) + { + ord->item_ptr= (*ord->item)->transform(thd, transformer, NULL); + *ord->item= ord->item_ptr; + } + + for (ORDER *ord= group_list; ord; ord= ord->next) + { + ord->item_ptr= (*ord->item)->transform(thd, transformer, NULL); + *ord->item= ord->item_ptr; + } + + if (having) + { + having= having->transform(thd, transformer, NULL); + } +} + +int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables, COND **where_expr) +{ + DBUG_ENTER("SELECT_LEX::vers_setup_cond"); #define newx new (thd->mem_root) TABLE_LIST *table; - int versioned_tables= 0; if (!thd->stmt_arena->is_conventional() && !thd->stmt_arena->is_stmt_prepare() && !thd->stmt_arena->is_sp_execute()) @@ -706,14 +732,17 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr, DBUG_RETURN(0); } - for (table= tables; table; table= table->next_local) + if (!versioned_tables) { - if (table->table && table->table->versioned()) - versioned_tables++; - else if (table->vers_conditions) + for (table= tables; table; table= table->next_local) { - my_error(ER_VERSIONING_REQUIRED, MYF(0), table->alias); - DBUG_RETURN(-1); + if (table->table && table->table->versioned()) + versioned_tables++; + else if (table->vers_conditions) + { + my_error(ER_VERSIONING_REQUIRED, MYF(0), table->alias); + DBUG_RETURN(-1); + } } } @@ -724,11 +753,11 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr, because they must outlive execution phase for multiple executions. */ Query_arena_stmt on_stmt_arena(thd); - if (slex->saved_where) + if (vers_saved_where) { DBUG_ASSERT(thd->stmt_arena->is_sp_execute()); /* 2. this copy_andor_structure() is also required by the same reason */ - *where_expr= slex->saved_where->copy_andor_structure(thd); + *where_expr= vers_saved_where->copy_andor_structure(thd); } else if (thd->stmt_arena->is_sp_execute()) { @@ -737,7 +766,7 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr, else if (*where_expr) // SP executed first time (STMT_INITIALIZED_FOR_SP) /* 1. copy_andor_structure() is required since this andor tree is modified later (and on shorter arena) */ - slex->saved_where= (*where_expr)->copy_andor_structure(thd); + vers_saved_where= (*where_expr)->copy_andor_structure(thd); } /* We have to save also non-versioned on_expr since we may have @@ -749,7 +778,7 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr, if (!table->table) continue; - if (table->saved_on_expr) // same logic as saved_where + if (table->saved_on_expr) // same logic as vers_saved_where { if (table->on_expr) table->on_expr= table->saved_on_expr->copy_andor_structure(thd); @@ -767,15 +796,15 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr, } } - SELECT_LEX *outer_slex= slex->next_select_in_list(); + SELECT_LEX *outer_slex= next_select_in_list(); // propagate derived conditions to outer SELECT_LEX - if (outer_slex && slex->vers_export_outer) + if (outer_slex && vers_export_outer) { for (table= outer_slex->table_list.first; table; table= table->next_local) { if (table->vers_conditions) { - if (!slex->is_linkage_set() && !table->vers_conditions.from_inner) + if (!is_linkage_set() && !table->vers_conditions.from_inner) { my_error(ER_VERS_SYSTEM_TIME_CLASH, MYF(0), table->alias); DBUG_RETURN(-1); @@ -783,7 +812,7 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr, } else { - table->vers_conditions= slex->vers_export_outer; + table->vers_conditions= vers_export_outer; table->vers_conditions.from_inner= true; } } @@ -796,9 +825,9 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr, vers_select_conds_t &vers_conditions= table->vers_conditions; // propagate system_time from nearest outer SELECT_LEX - if (!vers_conditions && outer_slex && slex->vers_import_outer) + if (!vers_conditions && outer_slex && vers_import_outer) { - TABLE_LIST* derived= slex->master_unit()->derived; + TABLE_LIST* derived= master_unit()->derived; // inner SELECT may not be a derived table (derived == NULL) while (derived && outer_slex && (!derived->vers_conditions || derived->vers_conditions.from_inner)) { @@ -821,7 +850,7 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr, if (vers_conditions) { - switch (slex->lock_type) + switch (this->lock_type) { case TL_WRITE_ALLOW_WRITE: case TL_WRITE_CONCURRENT_INSERT: @@ -856,9 +885,9 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr, const LEX_CSTRING *fend= &table->table->vers_end_field()->field_name; Item *row_start= - newx Item_field(thd, &slex->context, table->db, table->alias, fstart); + newx Item_field(thd, &this->context, table->db, table->alias, fstart); Item *row_end= - newx Item_field(thd, &slex->context, table->db, table->alias, fend); + newx Item_field(thd, &this->context, table->db, table->alias, fend); Item *row_end2= row_end; bool tmp_from_ib= @@ -985,8 +1014,8 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr, else thd->change_item_tree(dst_cond, cond1); - slex->where= *dst_cond; - slex->where->top_level_item(); + this->where= *dst_cond; + this->where->top_level_item(); } } // if (... table->table->versioned()) } // for (table= tables; ...) @@ -1072,7 +1101,7 @@ JOIN::prepare(TABLE_LIST *tables_init, } /* System Versioning: handle FOR SYSTEM_TIME clause. */ - if (vers_setup_select(thd, tables_list, &conds, select_lex) < 0) + if (select_lex->vers_setup_conds(thd, tables_list, &conds) < 0) DBUG_RETURN(-1); /* @@ -1358,44 +1387,9 @@ JOIN::prepare(TABLE_LIST *tables_init, if (!procedure && result && result->prepare(fields_list, unit_arg)) goto err; /* purecov: inspected */ - if (!thd->stmt_arena->is_stmt_prepare()) + if (!thd->stmt_arena->is_stmt_prepare() && select_lex->versioned_tables > 0) { - bool have_versioned_tables= false; - for (TABLE_LIST *table= tables_list; table; table= table->next_local) - { - if (table->table && table->table->versioned()) - { - have_versioned_tables= true; - break; - } - } - - if (have_versioned_tables) - { - Item_transformer transformer= &Item::vers_optimized_fields_transformer; - - if (conds) - { - conds= conds->transform(thd, transformer, NULL); - } - - for (ORDER *ord= order; ord; ord= ord->next) - { - ord->item_ptr= (*ord->item)->transform(thd, transformer, NULL); - *ord->item= ord->item_ptr; - } - - for (ORDER *ord= group_list; ord; ord= ord->next) - { - ord->item_ptr= (*ord->item)->transform(thd, transformer, NULL); - *ord->item= ord->item_ptr; - } - - if (having) - { - having= having->transform(thd, transformer, NULL); - } - } + vers_check_items(); } unit= unit_arg; @@ -3994,7 +3988,7 @@ void JOIN::exec_inner() List_iterator it(*columns_list); while (Item *item= it++) { - Item_transformer transformer= &Item::vers_optimized_fields_transformer; + Item_transformer transformer= &Item::vers_transformer; it.replace(item->transform(thd, transformer, NULL)); } } diff --git a/sql/sql_select.h b/sql/sql_select.h index 0c8c3c1a40c..36b1669b49f 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -1713,6 +1713,7 @@ private: bool add_having_as_table_cond(JOIN_TAB *tab); bool make_aggr_tables_info(); + void vers_check_items(); }; enum enum_with_bush_roots { WITH_BUSH_ROOTS, WITHOUT_BUSH_ROOTS}; @@ -2334,7 +2335,4 @@ int create_sort_index(THD *thd, JOIN *join, JOIN_TAB *tab, Filesort *fsort); JOIN_TAB *first_explain_order_tab(JOIN* join); JOIN_TAB *next_explain_order_tab(JOIN* join, JOIN_TAB* tab); -int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr, - SELECT_LEX *slex); - #endif /* SQL_SELECT_INCLUDED */ diff --git a/sql/vtmd.cc b/sql/vtmd.cc index b66d8ba0d18..ebab4bc4c92 100644 --- a/sql/vtmd.cc +++ b/sql/vtmd.cc @@ -539,7 +539,7 @@ VTMD_table::find_archive_name(THD *thd, String &out) vtmd.table->map= 1; vtmd.vers_conditions= about.vers_conditions; - if ((error= vers_setup_select(thd, &vtmd, &conds, &select_lex)) || + if ((error= select_lex.vers_setup_conds(thd, &vtmd, &conds)) || (error= setup_conds(thd, &vtmd, dummy, &conds))) goto err;