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
140
table->free_tmp_table(session);
141
delete derived_result;
145
if (! session->fill_derived_tables())
147
delete derived_result;
148
derived_result= NULL;
150
orig_table_list->derived_result= derived_result;
151
orig_table_list->table= table;
152
orig_table_list->table_name= table->s->table_name.str;
153
orig_table_list->table_name_length= table->s->table_name.length;
154
table->derived_select_number= first_select->select_number;
155
table->s->tmp_table= TEMP_TABLE;
156
orig_table_list->db= (char *)"";
157
orig_table_list->db_length= 0;
158
/* Force read of table stats in the optimizer */
159
table->cursor->info(HA_STATUS_VARIABLE);
160
/* Add new temporary table to list of open derived tables */
161
table->next= session->derived_tables;
162
session->derived_tables= table;
173
mysql_derived_filling()
174
session Thread handle
175
lex LEX for this thread
176
unit node that contains all SELECT's for derived tables
177
orig_table_list TableList for the upper SELECT
180
Derived table is resolved with temporary table. It is created based on the
181
queries defined. After temporary table is filled, if this is not EXPLAIN,
182
then the entire unit / node is deleted. unit is deleted if UNION is used
183
for derived table and node is deleted is it is a simple SELECT.
184
If you use this function, make sure it's not called at prepare.
185
Due to evaluation of LIMIT clause it can not be used at prepared stage.
191
bool mysql_derived_filling(Session *session, LEX *lex, TableList *orig_table_list)
193
Table *table= orig_table_list->table;
194
Select_Lex_Unit *unit= orig_table_list->derived;
197
/*check that table creation pass without problem and it is derived table */
200
Select_Lex *first_select= unit->first_select();
201
select_union *derived_result= orig_table_list->derived_result;
202
Select_Lex *save_current_select= lex->current_select;
203
if (unit->is_union())
205
/* execute union without clean up */
210
unit->set_limit(first_select);
211
if (unit->select_limit_cnt == HA_POS_ERROR)
212
first_select->options&= ~OPTION_FOUND_ROWS;
214
lex->current_select= first_select;
215
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);
231
Here we entirely fix both TableList and list of SELECT's as
232
there were no derived tables
234
if (derived_result->flush())
242
lex->current_select= save_current_select;
247
} /* namespace drizzled */