1
/* Copyright (C) 2002-2003 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
18
These were introduced by Sinisa <sinisa@mysql.com>
21
#include "drizzled/sql_select.h"
27
Call given derived table processor (preparing or filling tables)
30
mysql_handle_derived()
31
lex LEX for this thread
32
processor procedure of derived table processing
38
bool mysql_handle_derived(LEX *lex, bool (*processor)(Session*, LEX*, TableList*))
41
if (lex->derived_tables)
43
lex->session->derived_tables_processing= true;
44
for (Select_Lex *sl= lex->all_selects_list; sl; sl= sl->next_select_in_list())
46
for (TableList *cursor= sl->get_table_list(); cursor; cursor= cursor->next_local)
48
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;
63
lex->session->derived_tables_processing= false;
68
Create temporary table structure (but do not fill it)
71
mysql_derived_prepare()
73
lex LEX for this thread
74
orig_table_list TableList for the upper SELECT
77
Derived table is resolved with temporary table.
79
After table creation, the above TableList is updated with a new table.
81
This function is called before any command containing derived table
84
Derived tables is stored in session->derived_tables and freed in
91
bool mysql_derived_prepare(Session *session, LEX *, TableList *orig_table_list)
93
Select_Lex_Unit *unit= orig_table_list->derived;
94
uint64_t create_options;
98
Select_Lex *first_select= unit->first_select();
100
select_union *derived_result;
102
/* prevent name resolving out of derived table */
103
for (Select_Lex *sl= first_select; sl; sl= sl->next_select())
104
sl->context.outer_context= 0;
106
if (!(derived_result= new select_union))
107
return(true); // out of memory
109
// Select_Lex_Unit::prepare correctly work for single select
110
if ((res= unit->prepare(session, derived_result, 0)))
113
create_options= (first_select->options | session->options | TMP_TABLE_ALL_COLUMNS);
115
Temp table is created so that it hounours if UNION without ALL is to be
118
As 'distinct' parameter we always pass false (0), because underlying
119
query will control distinct condition by itself. Correct test of
120
distinct underlying query will be is_union &&
121
!unit->union_distinct->next_select() (i.e. it is union and last distinct
122
SELECT is last SELECT of UNION).
124
if ((res= derived_result->create_result_table(session, &unit->types, false,
126
orig_table_list->alias)))
129
table= derived_result->table;
133
if it is preparation PS only or commands that need only VIEW structure
134
then we do not need real data and we can skip execution (and parameters
143
delete derived_result;
147
if (! session->fill_derived_tables())
149
delete derived_result;
150
derived_result= NULL;
152
orig_table_list->derived_result= derived_result;
153
orig_table_list->table= table;
154
orig_table_list->table_name= const_cast<char *>(table->getShare()->getTableName());
155
orig_table_list->table_name_length= table->getShare()->getTableNameSize();
156
table->derived_select_number= first_select->select_number;
157
orig_table_list->db= (char *)"";
158
orig_table_list->db_length= 0;
159
/* Force read of table stats in the optimizer */
160
table->cursor->info(HA_STATUS_VARIABLE);
161
/* Add new temporary table to list of open derived tables */
162
table->setNext(session->derived_tables);
163
session->derived_tables= table;
174
mysql_derived_filling()
175
session Thread handle
176
lex LEX for this thread
177
unit node that contains all SELECT's for derived tables
178
orig_table_list TableList for the upper SELECT
181
Derived table is resolved with temporary table. It is created based on the
182
queries defined. After temporary table is filled, if this is not EXPLAIN,
183
then the entire unit / node is deleted. unit is deleted if UNION is used
184
for derived table and node is deleted is it is a simple SELECT.
185
If you use this function, make sure it's not called at prepare.
186
Due to evaluation of LIMIT clause it can not be used at prepared stage.
192
bool mysql_derived_filling(Session *session, LEX *lex, TableList *orig_table_list)
194
Table *table= orig_table_list->table;
195
Select_Lex_Unit *unit= orig_table_list->derived;
198
/*check that table creation pass without problem and it is derived table */
201
Select_Lex *first_select= unit->first_select();
202
select_union *derived_result= orig_table_list->derived_result;
203
Select_Lex *save_current_select= lex->current_select;
204
if (unit->is_union())
206
/* execute union without clean up */
211
unit->set_limit(first_select);
212
if (unit->select_limit_cnt == HA_POS_ERROR)
213
first_select->options&= ~OPTION_FOUND_ROWS;
215
lex->current_select= first_select;
216
res= mysql_select(session, &first_select->ref_pointer_array,
217
(TableList*) first_select->table_list.first,
218
first_select->with_wild,
219
first_select->item_list, first_select->where,
220
(first_select->order_list.elements+
221
first_select->group_list.elements),
222
(order_st *) first_select->order_list.first,
223
(order_st *) first_select->group_list.first,
224
first_select->having,
225
(first_select->options | session->options | SELECT_NO_UNLOCK),
226
derived_result, unit, first_select);
232
Here we entirely fix both TableList and list of SELECT's as
233
there were no derived tables
235
if (derived_result->flush())
243
lex->current_select= save_current_select;
248
} /* namespace drizzled */