38
bool mysql_handle_derived(LEX *lex, bool (*processor)(Session*, LEX*, TableList*))
36
mysql_handle_derived(LEX *lex, bool (*processor)(Session*, LEX*, TableList*))
41
39
if (lex->derived_tables)
43
41
lex->session->derived_tables_processing= true;
44
for (Select_Lex *sl= lex->all_selects_list; sl; sl= sl->next_select_in_list())
42
for (SELECT_LEX *sl= lex->all_selects_list;
44
sl= sl->next_select_in_list())
46
for (TableList *cursor= sl->get_table_list(); cursor; cursor= cursor->next_local)
46
for (TableList *cursor= sl->get_table_list();
48
cursor= cursor->next_local)
48
if ((res= (*processor)(lex->session, lex, cursor)))
50
if ((res= (*processor)(lex->session, lex, cursor)))
54
Force join->join_tmp creation, because we will use this JOIN
55
twice for EXPLAIN and we have to have unchanged join for EXPLAINing
57
sl->uncacheable|= UNCACHEABLE_EXPLAIN;
58
sl->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN;
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;
91
bool mysql_derived_prepare(Session *session, LEX *, TableList *orig_table_list)
95
bool mysql_derived_prepare(Session *session, LEX *,
96
TableList *orig_table_list)
93
Select_Lex_Unit *unit= orig_table_list->derived;
98
SELECT_LEX_UNIT *unit= orig_table_list->derived;
94
99
uint64_t create_options;
98
Select_Lex *first_select= unit->first_select();
103
SELECT_LEX *first_select= unit->first_select();
100
105
select_union *derived_result;
102
107
/* prevent name resolving out of derived table */
103
for (Select_Lex *sl= first_select; sl; sl= sl->next_select())
108
for (SELECT_LEX *sl= first_select; sl; sl= sl->next_select())
104
109
sl->context.outer_context= 0;
106
111
if (!(derived_result= new select_union))
107
112
return(true); // out of memory
109
// Select_Lex_Unit::prepare correctly work for single select
114
// st_select_lex_unit::prepare correctly work for single select
110
115
if ((res= unit->prepare(session, derived_result, 0)))
113
create_options= (first_select->options | session->options | TMP_TABLE_ALL_COLUMNS);
118
create_options= (first_select->options | session->options |
119
TMP_TABLE_ALL_COLUMNS);
115
121
Temp table is created so that it hounours if UNION without ALL is to be
140
table->free_tmp_table(session);
147
table->free_tmp_table(session);
141
148
delete derived_result;
145
if (! session->fill_derived_tables())
152
if (!session->fill_derived_tables())
147
delete derived_result;
148
derived_result= NULL;
154
delete derived_result;
155
derived_result= NULL;
150
157
orig_table_list->derived_result= derived_result;
151
158
orig_table_list->table= table;
152
159
orig_table_list->table_name= table->s->table_name.str;
153
160
orig_table_list->table_name_length= table->s->table_name.length;
154
161
table->derived_select_number= first_select->select_number;
155
table->s->tmp_table= message::Table::TEMPORARY;
162
table->s->tmp_table= NON_TRANSACTIONAL_TMP_TABLE;
156
163
orig_table_list->db= (char *)"";
157
164
orig_table_list->db_length= 0;
158
/* Force read of table stats in the optimizer */
159
table->cursor->info(HA_STATUS_VARIABLE);
165
// Force read of table stats in the optimizer
166
table->file->info(HA_STATUS_VARIABLE);
160
167
/* Add new temporary table to list of open derived tables */
161
168
table->next= session->derived_tables;
162
169
session->derived_tables= table;
191
200
bool mysql_derived_filling(Session *session, LEX *lex, TableList *orig_table_list)
193
202
Table *table= orig_table_list->table;
194
Select_Lex_Unit *unit= orig_table_list->derived;
203
SELECT_LEX_UNIT *unit= orig_table_list->derived;
197
206
/*check that table creation pass without problem and it is derived table */
198
207
if (table && unit)
200
Select_Lex *first_select= unit->first_select();
209
SELECT_LEX *first_select= unit->first_select();
201
210
select_union *derived_result= orig_table_list->derived_result;
202
Select_Lex *save_current_select= lex->current_select;
211
SELECT_LEX *save_current_select= lex->current_select;
203
212
if (unit->is_union())
205
/* execute union without clean up */
214
// execute union without clean up
206
215
res= unit->exec();
210
219
unit->set_limit(first_select);
211
220
if (unit->select_limit_cnt == HA_POS_ERROR)
212
first_select->options&= ~OPTION_FOUND_ROWS;
221
first_select->options&= ~OPTION_FOUND_ROWS;
214
223
lex->current_select= first_select;
215
224
res= mysql_select(session, &first_select->ref_pointer_array,
216
(TableList*) first_select->table_list.first,
217
first_select->with_wild,
218
first_select->item_list, first_select->where,
219
(first_select->order_list.elements+
220
first_select->group_list.elements),
221
(order_st *) first_select->order_list.first,
222
(order_st *) first_select->group_list.first,
223
first_select->having,
224
(first_select->options | session->options | SELECT_NO_UNLOCK),
225
derived_result, unit, first_select);
225
(TableList*) 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_st *) first_select->order_list.first,
231
(order_st *) first_select->group_list.first,
232
first_select->having, (order_st*) NULL,
233
(first_select->options | session->options |
235
derived_result, unit, first_select);
231
241
Here we entirely fix both TableList and list of SELECT's as