summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorDaniel Black <daniel@mariadb.org>2021-02-25 13:16:10 +1100
committerDaniel Black <daniel@mariadb.org>2021-02-25 13:16:10 +1100
commit36810342d51d9394f4739fac85618d44766aaeed (patch)
tree915ec1b0473cf155d44f7874d7b1792de659f5a7 /sql
parentd1eeb4b83932660f8c8170a861734076bb6af546 (diff)
parent3e2afcb3f409802d3cd7a713aea0dab0bfde6f48 (diff)
downloadmariadb-git-36810342d51d9394f4739fac85618d44766aaeed.tar.gz
Merge branch '10.3' into 10.4
Diffstat (limited to 'sql')
-rw-r--r--sql/sql_lex.cc23
-rw-r--r--sql/sql_lex.h2
-rw-r--r--sql/sql_tvc.cc67
3 files changed, 64 insertions, 28 deletions
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 6aec301bedc..73cbcf569f5 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -2530,6 +2530,8 @@ void st_select_lex_node::add_slave(st_select_lex_node *slave_arg)
{
slave= slave_arg;
slave_arg->master= this;
+ slave->prev= &master->slave;
+ slave->next= 0;
}
}
@@ -2552,6 +2554,27 @@ void st_select_lex_node::link_chain_down(st_select_lex_node *first)
}
/*
+ @brief
+ Substitute this node in select tree for a newly creates node
+
+ @param subst the node to substitute for
+
+ @details
+ The function substitute this node in the select tree for a newly
+ created node subst. This node is just removed from the tree but all
+ its link fields and the attached sub-tree remain untouched.
+*/
+
+void st_select_lex_node::substitute_in_tree(st_select_lex_node *subst)
+{
+ if ((subst->next= next))
+ next->prev= &subst->next;
+ subst->prev= prev;
+ (*prev)= subst;
+ subst->master= master;
+}
+
+/*
include on level down (but do not link)
SYNOPSYS
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 7dce0bf6016..d3b316d6a8d 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -764,7 +764,7 @@ public:
link_next= NULL;
link_prev= NULL;
}
-
+ void substitute_in_tree(st_select_lex_node *subst);
void set_slave(st_select_lex_node *slave_arg) { slave= slave_arg; }
void move_node(st_select_lex_node *where_to_move)
diff --git a/sql/sql_tvc.cc b/sql/sql_tvc.cc
index 4b10ef4ecb4..7f26256df09 100644
--- a/sql/sql_tvc.cc
+++ b/sql/sql_tvc.cc
@@ -653,44 +653,61 @@ st_select_lex *wrap_tvc(THD *thd, st_select_lex *tvc_sl,
Query_arena backup;
Query_arena *arena= thd->activate_stmt_arena_if_needed(&backup);
+
+ Item *item;
+ SELECT_LEX *wrapper_sl;
+ SELECT_LEX_UNIT *derived_unit;
+
/*
- Create SELECT_LEX of the select used in the result of transformation
+ Create SELECT_LEX wrapper_sl of the select used in the result
+ of the transformation
*/
- lex->current_select= tvc_sl;
- if (mysql_new_select(lex, 0, NULL))
+ if (!(wrapper_sl= new (thd->mem_root) SELECT_LEX()))
goto err;
- mysql_init_select(lex);
- /* Create item list as '*' for the subquery SQ */
- Item *item;
- SELECT_LEX *wrapper_sl;
- wrapper_sl= lex->current_select;
+ wrapper_sl->select_number= ++thd->lex->stmt_lex->current_select_number;
+ wrapper_sl->parent_lex= lex; /* Used in init_query. */
+ wrapper_sl->init_query();
+ wrapper_sl->init_select();
+
+ wrapper_sl->nest_level= tvc_sl->nest_level;
+ wrapper_sl->parsing_place= tvc_sl->parsing_place;
wrapper_sl->set_linkage(tvc_sl->get_linkage());
- wrapper_sl->parsing_place= SELECT_LIST;
+
+ lex->current_select= wrapper_sl;
item= new (thd->mem_root) Item_field(thd, &wrapper_sl->context,
NULL, NULL, &star_clex_str);
if (item == NULL || add_item_to_list(thd, item))
goto err;
(wrapper_sl->with_wild)++;
-
- /* Exclude SELECT with TVC */
- tvc_sl->exclude();
+
+ /* Include the newly created select into the global list of selects */
+ wrapper_sl->include_global((st_select_lex_node**)&lex->all_selects_list);
+
+ /* Substitute select node used of TVC for the newly created select */
+ tvc_sl->substitute_in_tree(wrapper_sl);
+
/*
- Create derived table DT that will wrap TVC in the result of transformation
+ Create a unit for the substituted select used for TVC and attach it
+ to the the wrapper select wrapper_sl as the only unit. The created
+ unit is the unit for the derived table tvc_x of the transformation.
*/
- SELECT_LEX *tvc_select; // select for tvc
- SELECT_LEX_UNIT *derived_unit; // unit for tvc_select
- if (mysql_new_select(lex, 1, tvc_sl))
+ if (!(derived_unit= new (thd->mem_root) SELECT_LEX_UNIT()))
goto err;
- tvc_select= lex->current_select;
- derived_unit= tvc_select->master_unit();
- tvc_select->set_linkage(DERIVED_TABLE_TYPE);
+ derived_unit->init_query();
+ derived_unit->thd= thd;
+ derived_unit->include_down(wrapper_sl);
- lex->current_select= wrapper_sl;
+ /*
+ Attach the select used of TVC as the only slave to the unit for
+ the derived table tvc_x of the transformation
+ */
+ derived_unit->add_slave(tvc_sl);
+ tvc_sl->set_linkage(DERIVED_TABLE_TYPE);
/*
- Create the name of the wrapping derived table and
- add it to the FROM list of the wrapper
- */
+ Generate the name of the derived table created for TVC and
+ add it to the FROM list of the wrapping select
+ */
Table_ident *ti;
LEX_CSTRING alias;
TABLE_LIST *derived_tab;
@@ -709,10 +726,6 @@ st_select_lex *wrap_tvc(THD *thd, st_select_lex *tvc_sl,
wrapper_sl->table_list.first->derived_type= DTYPE_TABLE | DTYPE_MATERIALIZE;
lex->derived_tables|= DERIVED_SUBQUERY;
- wrapper_sl->where= 0;
- wrapper_sl->set_braces(false);
- derived_unit->set_with_clause(0);
-
if (arena)
thd->restore_active_arena(arena, &backup);
thd->lex->result= save_result;