Commit de2186dd authored by Oleksandr Byelkin's avatar Oleksandr Byelkin

MDEV-20074: Lost connection on update trigger

Instead of checking lex->sql_command which does not corect in case of triggers
mark tables for insert.
parent 6cdde9eb
......@@ -209,4 +209,95 @@ delete s,t1 from t1,s;
ERROR HY000: Storage engine SEQUENCE of the table `test`.`s` doesn't have this option
DROP SEQUENCE s;
DROP TABLE t1;
#
# MDEV-20074: Lost connection on update trigger
#
# INSERT & table
create sequence s1 increment by 1 start with 1;
create table t1 (p_id integer, p_name varchar(128), p_first_name varchar(128));
create table t2 (a_id integer default nextval(s1), a_p_name varchar(128), a_p_first_name varchar(128), t timestamp default current_timestamp);
insert into t1 values
(1, 'Luo','Frank'),(2, 'Xe','Emma'),(3, 'Li','Anna'),(4, 'Lun','Serg'),(5, 'Xu','Nils'),(6, 'Ja','Ute'),(7, 'Jin','Mike'),(8, 'Lio','Carl'),(9, 'Lang','Kevin'),(10, 'Ling','Lisa'),(11, 'Fang','Frank'),(12, 'Feng','Emma'),(13, 'Tuo','Anna'),(14, 'Tua','Serg'),(15, 'Moa','Nils'),(16, 'Hua','Ute'),(17, 'Xufa','Mike'),(18, 'Lulu','Carl'),(19, 'Hoho','Kevin'),(20, 'Tata','Lisa');
CREATE TRIGGER tr_upd
BEFORE UPDATE on t1
FOR EACH ROW
BEGIN
INSERT INTO t2(a_p_name, a_p_first_name) VALUES(old.p_name, old.p_first_name);
END;
$$
update t1 set p_first_name='Yunxi' where p_id=1;
drop sequence s1;
drop table t1,t2;
# INSERT & view
create sequence s1 increment by 1 start with 1;
create table t1 (p_id integer, p_name varchar(128), p_first_name varchar(128));
create table t2 (a_id integer default nextval(s1), a_p_name varchar(128), a_p_first_name varchar(128), t timestamp default current_timestamp);
create view v2 as select * from t2;
insert into t1 values
(1, 'Luo','Frank'),(2, 'Xe','Emma'),(3, 'Li','Anna'),(4, 'Lun','Serg'),(5, 'Xu','Nils'),(6, 'Ja','Ute'),(7, 'Jin','Mike'),(8, 'Lio','Carl'),(9, 'Lang','Kevin'),(10, 'Ling','Lisa'),(11, 'Fang','Frank'),(12, 'Feng','Emma'),(13, 'Tuo','Anna'),(14, 'Tua','Serg'),(15, 'Moa','Nils'),(16, 'Hua','Ute'),(17, 'Xufa','Mike'),(18, 'Lulu','Carl'),(19, 'Hoho','Kevin'),(20, 'Tata','Lisa');
CREATE TRIGGER tr_upd
BEFORE UPDATE on t1
FOR EACH ROW
BEGIN
INSERT INTO v2(a_p_name, a_p_first_name) VALUES(old.p_name, old.p_first_name);
END;
$$
update t1 set p_first_name='Yunxi' where p_id=1;
drop view v2;
drop table t1,t2;
drop sequence s1;
# INSERT SELECT & view
create sequence s1 increment by 1 start with 1;
create table t1 (p_id integer, p_name varchar(128), p_first_name varchar(128));
create table t2 (a_id integer default nextval(s1), a_p_name varchar(128), a_p_first_name varchar(128), t timestamp default current_timestamp);
create view v2 as select * from t2;
insert into t1 values
(1, 'Luo','Frank'),(2, 'Xe','Emma'),(3, 'Li','Anna'),(4, 'Lun','Serg'),(5, 'Xu','Nils'),(6, 'Ja','Ute'),(7, 'Jin','Mike'),(8, 'Lio','Carl'),(9, 'Lang','Kevin'),(10, 'Ling','Lisa'),(11, 'Fang','Frank'),(12, 'Feng','Emma'),(13, 'Tuo','Anna'),(14, 'Tua','Serg'),(15, 'Moa','Nils'),(16, 'Hua','Ute'),(17, 'Xufa','Mike'),(18, 'Lulu','Carl'),(19, 'Hoho','Kevin'),(20, 'Tata','Lisa');
CREATE TRIGGER tr_upd
BEFORE UPDATE on t1
FOR EACH ROW
BEGIN
INSERT INTO v2(a_p_name, a_p_first_name) SELECT old.p_name, old.p_first_name;
END;
$$
update t1 set p_first_name='Yunxi' where p_id=1;
drop view v2;
drop table t1,t2;
drop sequence s1;
# REPLACE & view
create sequence s1 increment by 1 start with 1;
create table t1 (p_id integer, p_name varchar(128), p_first_name varchar(128));
create table t2 (a_id integer default nextval(s1), a_p_name varchar(128), a_p_first_name varchar(128), t timestamp default current_timestamp);
create view v2 as select * from t2;
insert into t1 values
(1, 'Luo','Frank'),(2, 'Xe','Emma'),(3, 'Li','Anna'),(4, 'Lun','Serg'),(5, 'Xu','Nils'),(6, 'Ja','Ute'),(7, 'Jin','Mike'),(8, 'Lio','Carl'),(9, 'Lang','Kevin'),(10, 'Ling','Lisa'),(11, 'Fang','Frank'),(12, 'Feng','Emma'),(13, 'Tuo','Anna'),(14, 'Tua','Serg'),(15, 'Moa','Nils'),(16, 'Hua','Ute'),(17, 'Xufa','Mike'),(18, 'Lulu','Carl'),(19, 'Hoho','Kevin'),(20, 'Tata','Lisa');
CREATE TRIGGER tr_upd
BEFORE UPDATE on t1
FOR EACH ROW
BEGIN
REPLACE INTO v2(a_p_name, a_p_first_name) VALUES(old.p_name, old.p_first_name);
END;
$$
update t1 set p_first_name='Yunxi' where p_id=1;
drop view v2;
drop table t1,t2;
drop sequence s1;
# REPLACE SELECT & view
create sequence s1 increment by 1 start with 1;
create table t1 (p_id integer, p_name varchar(128), p_first_name varchar(128));
create table t2 (a_id integer default nextval(s1), a_p_name varchar(128), a_p_first_name varchar(128), t timestamp default current_timestamp);
create view v2 as select * from t2;
insert into t1 values
(1, 'Luo','Frank'),(2, 'Xe','Emma'),(3, 'Li','Anna'),(4, 'Lun','Serg'),(5, 'Xu','Nils'),(6, 'Ja','Ute'),(7, 'Jin','Mike'),(8, 'Lio','Carl'),(9, 'Lang','Kevin'),(10, 'Ling','Lisa'),(11, 'Fang','Frank'),(12, 'Feng','Emma'),(13, 'Tuo','Anna'),(14, 'Tua','Serg'),(15, 'Moa','Nils'),(16, 'Hua','Ute'),(17, 'Xufa','Mike'),(18, 'Lulu','Carl'),(19, 'Hoho','Kevin'),(20, 'Tata','Lisa');
CREATE TRIGGER tr_upd
BEFORE UPDATE on t1
FOR EACH ROW
BEGIN
REPLACE INTO v2(a_p_name, a_p_first_name) SELECT old.p_name, old.p_first_name;
END;
$$
update t1 set p_first_name='Yunxi' where p_id=1;
drop view v2;
drop table t1,t2;
drop sequence s1;
# End of 10.3 tests
......@@ -179,4 +179,140 @@ DROP SEQUENCE s;
DROP TABLE t1;
--echo #
--echo # MDEV-20074: Lost connection on update trigger
--echo #
--echo # INSERT & table
create sequence s1 increment by 1 start with 1;
create table t1 (p_id integer, p_name varchar(128), p_first_name varchar(128));
create table t2 (a_id integer default nextval(s1), a_p_name varchar(128), a_p_first_name varchar(128), t timestamp default current_timestamp);
insert into t1 values
(1, 'Luo','Frank'),(2, 'Xe','Emma'),(3, 'Li','Anna'),(4, 'Lun','Serg'),(5, 'Xu','Nils'),(6, 'Ja','Ute'),(7, 'Jin','Mike'),(8, 'Lio','Carl'),(9, 'Lang','Kevin'),(10, 'Ling','Lisa'),(11, 'Fang','Frank'),(12, 'Feng','Emma'),(13, 'Tuo','Anna'),(14, 'Tua','Serg'),(15, 'Moa','Nils'),(16, 'Hua','Ute'),(17, 'Xufa','Mike'),(18, 'Lulu','Carl'),(19, 'Hoho','Kevin'),(20, 'Tata','Lisa');
DELIMITER $$;
CREATE TRIGGER tr_upd
BEFORE UPDATE on t1
FOR EACH ROW
BEGIN
INSERT INTO t2(a_p_name, a_p_first_name) VALUES(old.p_name, old.p_first_name);
END;
$$
DELIMITER ;$$
update t1 set p_first_name='Yunxi' where p_id=1;
drop sequence s1;
drop table t1,t2;
--echo # INSERT & view
create sequence s1 increment by 1 start with 1;
create table t1 (p_id integer, p_name varchar(128), p_first_name varchar(128));
create table t2 (a_id integer default nextval(s1), a_p_name varchar(128), a_p_first_name varchar(128), t timestamp default current_timestamp);
create view v2 as select * from t2;
insert into t1 values
(1, 'Luo','Frank'),(2, 'Xe','Emma'),(3, 'Li','Anna'),(4, 'Lun','Serg'),(5, 'Xu','Nils'),(6, 'Ja','Ute'),(7, 'Jin','Mike'),(8, 'Lio','Carl'),(9, 'Lang','Kevin'),(10, 'Ling','Lisa'),(11, 'Fang','Frank'),(12, 'Feng','Emma'),(13, 'Tuo','Anna'),(14, 'Tua','Serg'),(15, 'Moa','Nils'),(16, 'Hua','Ute'),(17, 'Xufa','Mike'),(18, 'Lulu','Carl'),(19, 'Hoho','Kevin'),(20, 'Tata','Lisa');
DELIMITER $$;
CREATE TRIGGER tr_upd
BEFORE UPDATE on t1
FOR EACH ROW
BEGIN
INSERT INTO v2(a_p_name, a_p_first_name) VALUES(old.p_name, old.p_first_name);
END;
$$
DELIMITER ;$$
update t1 set p_first_name='Yunxi' where p_id=1;
drop view v2;
drop table t1,t2;
drop sequence s1;
--echo # INSERT SELECT & view
create sequence s1 increment by 1 start with 1;
create table t1 (p_id integer, p_name varchar(128), p_first_name varchar(128));
create table t2 (a_id integer default nextval(s1), a_p_name varchar(128), a_p_first_name varchar(128), t timestamp default current_timestamp);
create view v2 as select * from t2;
insert into t1 values
(1, 'Luo','Frank'),(2, 'Xe','Emma'),(3, 'Li','Anna'),(4, 'Lun','Serg'),(5, 'Xu','Nils'),(6, 'Ja','Ute'),(7, 'Jin','Mike'),(8, 'Lio','Carl'),(9, 'Lang','Kevin'),(10, 'Ling','Lisa'),(11, 'Fang','Frank'),(12, 'Feng','Emma'),(13, 'Tuo','Anna'),(14, 'Tua','Serg'),(15, 'Moa','Nils'),(16, 'Hua','Ute'),(17, 'Xufa','Mike'),(18, 'Lulu','Carl'),(19, 'Hoho','Kevin'),(20, 'Tata','Lisa');
DELIMITER $$;
CREATE TRIGGER tr_upd
BEFORE UPDATE on t1
FOR EACH ROW
BEGIN
INSERT INTO v2(a_p_name, a_p_first_name) SELECT old.p_name, old.p_first_name;
END;
$$
DELIMITER ;$$
update t1 set p_first_name='Yunxi' where p_id=1;
drop view v2;
drop table t1,t2;
drop sequence s1;
--echo # REPLACE & view
create sequence s1 increment by 1 start with 1;
create table t1 (p_id integer, p_name varchar(128), p_first_name varchar(128));
create table t2 (a_id integer default nextval(s1), a_p_name varchar(128), a_p_first_name varchar(128), t timestamp default current_timestamp);
create view v2 as select * from t2;
insert into t1 values
(1, 'Luo','Frank'),(2, 'Xe','Emma'),(3, 'Li','Anna'),(4, 'Lun','Serg'),(5, 'Xu','Nils'),(6, 'Ja','Ute'),(7, 'Jin','Mike'),(8, 'Lio','Carl'),(9, 'Lang','Kevin'),(10, 'Ling','Lisa'),(11, 'Fang','Frank'),(12, 'Feng','Emma'),(13, 'Tuo','Anna'),(14, 'Tua','Serg'),(15, 'Moa','Nils'),(16, 'Hua','Ute'),(17, 'Xufa','Mike'),(18, 'Lulu','Carl'),(19, 'Hoho','Kevin'),(20, 'Tata','Lisa');
DELIMITER $$;
CREATE TRIGGER tr_upd
BEFORE UPDATE on t1
FOR EACH ROW
BEGIN
REPLACE INTO v2(a_p_name, a_p_first_name) VALUES(old.p_name, old.p_first_name);
END;
$$
DELIMITER ;$$
update t1 set p_first_name='Yunxi' where p_id=1;
drop view v2;
drop table t1,t2;
drop sequence s1;
--echo # REPLACE SELECT & view
create sequence s1 increment by 1 start with 1;
create table t1 (p_id integer, p_name varchar(128), p_first_name varchar(128));
create table t2 (a_id integer default nextval(s1), a_p_name varchar(128), a_p_first_name varchar(128), t timestamp default current_timestamp);
create view v2 as select * from t2;
insert into t1 values
(1, 'Luo','Frank'),(2, 'Xe','Emma'),(3, 'Li','Anna'),(4, 'Lun','Serg'),(5, 'Xu','Nils'),(6, 'Ja','Ute'),(7, 'Jin','Mike'),(8, 'Lio','Carl'),(9, 'Lang','Kevin'),(10, 'Ling','Lisa'),(11, 'Fang','Frank'),(12, 'Feng','Emma'),(13, 'Tuo','Anna'),(14, 'Tua','Serg'),(15, 'Moa','Nils'),(16, 'Hua','Ute'),(17, 'Xufa','Mike'),(18, 'Lulu','Carl'),(19, 'Hoho','Kevin'),(20, 'Tata','Lisa');
DELIMITER $$;
CREATE TRIGGER tr_upd
BEFORE UPDATE on t1
FOR EACH ROW
BEGIN
REPLACE INTO v2(a_p_name, a_p_first_name) SELECT old.p_name, old.p_first_name;
END;
$$
DELIMITER ;$$
update t1 set p_first_name='Yunxi' where p_id=1;
drop view v2;
drop table t1,t2;
drop sequence s1;
--echo # End of 10.3 tests
......@@ -4652,6 +4652,7 @@ typedef struct st_sp_table
uint lock_count;
uint query_lock_count;
uint8 trg_event_map;
my_bool for_insert_data;
} SP_TABLE;
......@@ -4747,6 +4748,7 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check)
if (tab->query_lock_count > tab->lock_count)
tab->lock_count++;
tab->trg_event_map|= table->trg_event_map;
tab->for_insert_data|= table->for_insert_data;
}
else
{
......@@ -4770,6 +4772,7 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check)
tab->lock_type= table->lock_type;
tab->lock_count= tab->query_lock_count= 1;
tab->trg_event_map= table->trg_event_map;
tab->for_insert_data= table->for_insert_data;
if (my_hash_insert(&m_sptabs, (uchar *)tab))
return FALSE;
}
......@@ -4853,7 +4856,8 @@ sp_head::add_used_tables_to_table_list(THD *thd,
TABLE_LIST::PRELOCK_ROUTINE,
belong_to_view,
stab->trg_event_map,
query_tables_last_ptr);
query_tables_last_ptr,
stab->for_insert_data);
tab_buff+= ALIGN_SIZE(sizeof(TABLE_LIST));
result= TRUE;
}
......
......@@ -4420,9 +4420,11 @@ add_internal_tables(THD *thd, Query_tables_list *prelocking_ctx,
TABLE_LIST *tables)
{
TABLE_LIST *global_table_list= prelocking_ctx->query_tables;
DBUG_ENTER("add_internal_tables");
do
{
DBUG_PRINT("info", ("table name: %s", tables->table_name.str));
/*
Skip table if already in the list. Can happen with prepared statements
*/
......@@ -4432,20 +4434,22 @@ add_internal_tables(THD *thd, Query_tables_list *prelocking_ctx,
TABLE_LIST *tl= (TABLE_LIST *) thd->alloc(sizeof(TABLE_LIST));
if (!tl)
return TRUE;
DBUG_RETURN(TRUE);
tl->init_one_table_for_prelocking(&tables->db,
&tables->table_name,
NULL, tables->lock_type,
TABLE_LIST::PRELOCK_NONE,
0, 0,
&prelocking_ctx->query_tables_last);
&prelocking_ctx->query_tables_last,
tables->for_insert_data);
/*
Store link to the new table_list that will be used by open so that
Item_func_nextval() can find it
*/
tables->next_local= tl;
DBUG_PRINT("info", ("table name: %s added", tables->table_name.str));
} while ((tables= tables->next_global));
return FALSE;
DBUG_RETURN(FALSE);
}
......@@ -4476,6 +4480,7 @@ bool DML_prelocking_strategy::
handle_table(THD *thd, Query_tables_list *prelocking_ctx,
TABLE_LIST *table_list, bool *need_prelocking)
{
DBUG_ENTER("handle_table");
TABLE *table= table_list->table;
/* We rely on a caller to check that table is going to be changed. */
DBUG_ASSERT(table_list->lock_type >= TL_WRITE_ALLOW_WRITE ||
......@@ -4506,7 +4511,7 @@ handle_table(THD *thd, Query_tables_list *prelocking_ctx,
{
if (arena)
thd->restore_active_arena(arena, &backup);
return TRUE;
DBUG_RETURN(TRUE);
}
*need_prelocking= TRUE;
......@@ -4534,7 +4539,8 @@ handle_table(THD *thd, Query_tables_list *prelocking_ctx,
NULL, lock_type,
TABLE_LIST::PRELOCK_FK,
table_list->belong_to_view, op,
&prelocking_ctx->query_tables_last);
&prelocking_ctx->query_tables_last,
table_list->for_insert_data);
}
if (arena)
thd->restore_active_arena(arena, &backup);
......@@ -4542,8 +4548,11 @@ handle_table(THD *thd, Query_tables_list *prelocking_ctx,
}
/* Open any tables used by DEFAULT (like sequence tables) */
DBUG_PRINT("info", ("table: %p name: %s db: %s flags: %u",
table_list, table_list->table_name.str,
table_list->db.str, table_list->for_insert_data));
if (table->internal_tables &&
((sql_command_flags[thd->lex->sql_command] & CF_INSERTS_DATA) ||
(table_list->for_insert_data ||
thd->lex->default_used))
{
Query_arena *arena, backup;
......@@ -4556,10 +4565,10 @@ handle_table(THD *thd, Query_tables_list *prelocking_ctx,
if (unlikely(error))
{
*need_prelocking= TRUE;
return TRUE;
DBUG_RETURN(TRUE);
}
}
return FALSE;
DBUG_RETURN(FALSE);
}
......@@ -4576,7 +4585,7 @@ bool open_and_lock_internal_tables(TABLE *table, bool lock_table)
THD *thd= table->in_use;
TABLE_LIST *tl;
MYSQL_LOCK *save_lock,*new_lock;
DBUG_ENTER("open_internal_tables");
DBUG_ENTER("open_and_lock_internal_tables");
/* remove pointer to old select_lex which is already destroyed */
for (tl= table->internal_tables ; tl ; tl= tl->next_global)
......
......@@ -4060,6 +4060,8 @@ struct LEX: public Query_tables_list
}
bool tvc_finalize();
bool tvc_finalize_derived();
void mark_first_table_as_inserting();
};
......
......@@ -3282,6 +3282,10 @@ mysql_execute_command(THD *thd)
#endif
DBUG_ENTER("mysql_execute_command");
// check that we correctly marked first table for data insertion
DBUG_ASSERT(!(sql_command_flags[lex->sql_command] & CF_INSERTS_DATA) ||
first_table->for_insert_data);
DBUG_ASSERT(thd->transaction.stmt.is_empty() || thd->in_sub_stmt);
/*
Each statement or replication event which might produce deadlock
......@@ -10200,3 +10204,14 @@ CHARSET_INFO *find_bin_collation(CHARSET_INFO *cs)
}
return cs;
}
void LEX::mark_first_table_as_inserting()
{
TABLE_LIST *t= select_lex.table_list.first;
DBUG_ENTER("Query_tables_list::mark_tables_with_important_flags");
DBUG_ASSERT(sql_command_flags[sql_command] & CF_INSERTS_DATA);
t->for_insert_data= TRUE;
DBUG_PRINT("info", ("table_list: %p name: %s db: %s command: %u",
t, t->table_name.str,t->db.str, sql_command));
DBUG_VOID_RETURN;
}
......@@ -1490,6 +1490,7 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
privileges of top_view
*/
tbl->grant.want_privilege= SELECT_ACL;
/*
After unfolding the view we lose the list of tables referenced in it
(we will have only a list of underlying tables in case of MERGE
......@@ -1540,6 +1541,18 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
views with subqueries in select list.
*/
view_main_select_tables= lex->select_lex.table_list.first;
/*
Mergeable view can be used for inserting, so we move the flag down
*/
if (table->for_insert_data)
{
for (TABLE_LIST *t= view_main_select_tables;
t;
t= t->next_local)
{
t->for_insert_data= TRUE;
}
}
/*
Let us set proper lock type for tables of the view's main
......
......@@ -7888,6 +7888,7 @@ alter:
MYSQL_YYABORT;
Lex->select_lex.db= (Lex->select_lex.table_list.first)->db;
Lex->create_last_non_select_table= Lex->last_table();
Lex->mark_first_table_as_inserting();
}
alter_commands
{
......@@ -13459,7 +13460,9 @@ insert:
Lex->current_select= &Lex->select_lex;
}
insert_field_spec opt_insert_update
{}
{
Lex->mark_first_table_as_inserting();
}
;
replace:
......@@ -13476,7 +13479,9 @@ replace:
Lex->current_select= &Lex->select_lex;
}
insert_field_spec
{}
{
Lex->mark_first_table_as_inserting();
}
;
insert_lock_option:
......@@ -14859,7 +14864,9 @@ load:
opt_xml_rows_identified_by
opt_field_term opt_line_term opt_ignore_lines opt_field_or_var_spec
opt_load_data_set_spec
{}
{
Lex->mark_first_table_as_inserting();
}
;
data_or_xml:
......
......@@ -7825,6 +7825,7 @@ alter:
MYSQL_YYABORT;
Lex->select_lex.db= (Lex->select_lex.table_list.first)->db;
Lex->create_last_non_select_table= Lex->last_table();
Lex->mark_first_table_as_inserting();
}
alter_commands
{
......@@ -13420,7 +13421,9 @@ insert:
Lex->current_select= &Lex->select_lex;
}
insert_field_spec opt_insert_update
{}
{
Lex->mark_first_table_as_inserting();
}
;
replace:
......@@ -13437,7 +13440,9 @@ replace:
Lex->current_select= &Lex->select_lex;
}
insert_field_spec
{}
{
Lex->mark_first_table_as_inserting();
}
;
insert_lock_option:
......@@ -14826,7 +14831,9 @@ load:
opt_xml_rows_identified_by
opt_field_term opt_line_term opt_ignore_lines opt_field_or_var_spec
opt_load_data_set_spec
{}
{
Lex->mark_first_table_as_inserting();
}
;
data_or_xml:
......
......@@ -1985,7 +1985,8 @@ struct TABLE_LIST
prelocking_types prelocking_type,
TABLE_LIST *belong_to_view_arg,
uint8 trg_event_map_arg,
TABLE_LIST ***last_ptr)
TABLE_LIST ***last_ptr,
my_bool insert_data)
{
init_one_table(db_arg, table_name_arg, alias_arg, lock_type_arg);
......@@ -2000,6 +2001,7 @@ struct TABLE_LIST
**last_ptr= this;
prev_global= *last_ptr;
*last_ptr= &next_global;
for_insert_data= insert_data;
}
......@@ -2411,6 +2413,8 @@ struct TABLE_LIST
/* System Versioning */
vers_select_conds_t vers_conditions;
my_bool for_insert_data;
/**
@brief
Find the bottom in the chain of embedded table VIEWs.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment