36
mysql_handle_derived(LEX *lex, bool (*processor)(THD*, LEX*, TABLE_LIST*))
35
bool mysql_handle_derived(LEX *lex, bool (*processor)(Session*, LEX*, TableList*))
39
38
if (lex->derived_tables)
41
lex->thd->derived_tables_processing= true;
42
for (SELECT_LEX *sl= lex->all_selects_list;
44
sl= sl->next_select_in_list())
40
lex->session->derived_tables_processing= true;
41
for (Select_Lex *sl= lex->all_selects_list; sl; sl= sl->next_select_in_list())
46
for (TABLE_LIST *cursor= sl->get_table_list();
48
cursor= cursor->next_local)
43
for (TableList *cursor= sl->get_table_list(); cursor; cursor= cursor->next_local)
50
if ((res= (*processor)(lex->thd, lex, cursor)))
45
if ((res= (*processor)(lex->session, lex, cursor)))
56
Force join->join_tmp creation, because we will use this JOIN
57
twice for EXPLAIN and we have to have unchanged join for EXPLAINing
59
sl->uncacheable|= UNCACHEABLE_EXPLAIN;
60
sl->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN;
51
Force join->join_tmp creation, because we will use this JOIN
52
twice for EXPLAIN and we have to have unchanged join for EXPLAINing
54
sl->uncacheable|= UNCACHEABLE_EXPLAIN;
55
sl->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN;
65
lex->thd->derived_tables_processing= false;
60
lex->session->derived_tables_processing= false;
71
65
Create temporary table structure (but do not fill it)
74
68
mysql_derived_prepare()
76
70
lex LEX for this thread
77
orig_table_list TABLE_LIST for the upper SELECT
71
orig_table_list TableList for the upper SELECT
80
74
Derived table is resolved with temporary table.
82
After table creation, the above TABLE_LIST is updated with a new table.
76
After table creation, the above TableList is updated with a new table.
84
78
This function is called before any command containing derived table
87
Derived tables is stored in thd->derived_tables and freed in
81
Derived tables is stored in session->derived_tables and freed in
88
82
close_thread_tables()
95
bool mysql_derived_prepare(THD *thd, LEX *lex __attribute__((unused)),
96
TABLE_LIST *orig_table_list)
88
bool mysql_derived_prepare(Session *session, LEX *, TableList *orig_table_list)
98
SELECT_LEX_UNIT *unit= orig_table_list->derived;
90
Select_Lex_Unit *unit= orig_table_list->derived;
99
91
uint64_t create_options;
103
SELECT_LEX *first_select= unit->first_select();
95
Select_Lex *first_select= unit->first_select();
105
97
select_union *derived_result;
107
99
/* prevent name resolving out of derived table */
108
for (SELECT_LEX *sl= first_select; sl; sl= sl->next_select())
100
for (Select_Lex *sl= first_select; sl; sl= sl->next_select())
109
101
sl->context.outer_context= 0;
111
103
if (!(derived_result= new select_union))
112
104
return(true); // out of memory
114
// st_select_lex_unit::prepare correctly work for single select
115
if ((res= unit->prepare(thd, derived_result, 0)))
106
// Select_Lex_Unit::prepare correctly work for single select
107
if ((res= unit->prepare(session, derived_result, 0)))
118
create_options= (first_select->options | thd->options |
119
TMP_TABLE_ALL_COLUMNS);
110
create_options= (first_select->options | session->options | TMP_TABLE_ALL_COLUMNS);
121
Temp table is created so that it hounours if UNION without ALL is to be
112
Temp table is created so that it hounours if UNION without ALL is to be
124
115
As 'distinct' parameter we always pass false (0), because underlying
147
free_tmp_table(thd, table);
138
table->free_tmp_table(session);
148
139
delete derived_result;
152
if (!thd->fill_derived_tables())
143
if (! session->fill_derived_tables())
154
delete derived_result;
155
derived_result= NULL;
145
delete derived_result;
146
derived_result= NULL;
157
148
orig_table_list->derived_result= derived_result;
158
149
orig_table_list->table= table;
159
150
orig_table_list->table_name= table->s->table_name.str;
160
151
orig_table_list->table_name_length= table->s->table_name.length;
161
152
table->derived_select_number= first_select->select_number;
162
table->s->tmp_table= NON_TRANSACTIONAL_TMP_TABLE;
153
table->s->tmp_table= TEMP_TABLE;
163
154
orig_table_list->db= (char *)"";
164
155
orig_table_list->db_length= 0;
165
// Force read of table stats in the optimizer
166
table->file->info(HA_STATUS_VARIABLE);
156
/* Force read of table stats in the optimizer */
157
table->cursor->info(HA_STATUS_VARIABLE);
167
158
/* Add new temporary table to list of open derived tables */
168
table->next= thd->derived_tables;
169
thd->derived_tables= table;
159
table->next= session->derived_tables;
160
session->derived_tables= table;
178
168
fill derived table
181
171
mysql_derived_filling()
172
session Thread handle
183
173
lex LEX for this thread
184
174
unit node that contains all SELECT's for derived tables
185
orig_table_list TABLE_LIST for the upper SELECT
175
orig_table_list TableList for the upper SELECT
188
178
Derived table is resolved with temporary table. It is created based on the
200
bool mysql_derived_filling(THD *thd, LEX *lex, TABLE_LIST *orig_table_list)
189
bool mysql_derived_filling(Session *session, LEX *lex, TableList *orig_table_list)
202
TABLE *table= orig_table_list->table;
203
SELECT_LEX_UNIT *unit= orig_table_list->derived;
191
Table *table= orig_table_list->table;
192
Select_Lex_Unit *unit= orig_table_list->derived;
206
195
/*check that table creation pass without problem and it is derived table */
207
196
if (table && unit)
209
SELECT_LEX *first_select= unit->first_select();
198
Select_Lex *first_select= unit->first_select();
210
199
select_union *derived_result= orig_table_list->derived_result;
211
SELECT_LEX *save_current_select= lex->current_select;
200
Select_Lex *save_current_select= lex->current_select;
212
201
if (unit->is_union())
214
// execute union without clean up
203
/* execute union without clean up */
215
204
res= unit->exec();
219
208
unit->set_limit(first_select);
220
209
if (unit->select_limit_cnt == HA_POS_ERROR)
221
first_select->options&= ~OPTION_FOUND_ROWS;
210
first_select->options&= ~OPTION_FOUND_ROWS;
223
212
lex->current_select= first_select;
224
res= mysql_select(thd, &first_select->ref_pointer_array,
225
(TABLE_LIST*) first_select->table_list.first,
226
first_select->with_wild,
227
first_select->item_list, first_select->where,
228
(first_select->order_list.elements+
229
first_select->group_list.elements),
230
(ORDER *) first_select->order_list.first,
231
(ORDER *) first_select->group_list.first,
232
first_select->having, (ORDER*) NULL,
233
(first_select->options | thd->options |
235
derived_result, unit, first_select);
213
res= mysql_select(session, &first_select->ref_pointer_array,
214
(TableList*) first_select->table_list.first,
215
first_select->with_wild,
216
first_select->item_list, first_select->where,
217
(first_select->order_list.elements+
218
first_select->group_list.elements),
219
(order_st *) first_select->order_list.first,
220
(order_st *) first_select->group_list.first,
221
first_select->having,
222
(first_select->options | session->options | SELECT_NO_UNLOCK),
223
derived_result, unit, first_select);
241
Here we entirely fix both TABLE_LIST and list of SELECT's as
229
Here we entirely fix both TableList and list of SELECT's as
242
230
there were no derived tables
244
232
if (derived_result->flush())