1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
1 |
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
|
2 |
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
|
|
3 |
*
|
|
4 |
* Copyright (C) 2008-2009 Sun Microsystems
|
|
5 |
*
|
|
6 |
* This program is free software; you can redistribute it and/or modify
|
|
7 |
* it under the terms of the GNU General Public License as published by
|
|
8 |
* the Free Software Foundation; version 2 of the License.
|
|
9 |
*
|
|
10 |
* This program is distributed in the hope that it will be useful,
|
|
11 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13 |
* GNU General Public License for more details.
|
|
14 |
*
|
|
15 |
* You should have received a copy of the GNU General Public License
|
|
16 |
* along with this program; if not, write to the Free Software
|
|
17 |
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
18 |
*/
|
|
19 |
||
1241.9.36
by Monty Taylor
ZOMG. I deleted drizzled/server_includes.h. |
20 |
#include "config.h" |
1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
21 |
#include "drizzled/session.h" |
22 |
#include "drizzled/item/uint.h" |
|
23 |
#include "drizzled/item/float.h" |
|
24 |
#include "drizzled/optimizer/explain_plan.h" |
|
25 |
#include "drizzled/optimizer/position.h" |
|
1240.7.8
by Padraig O'Sullivan
Resolved some conflicts after merging with build. |
26 |
#include "drizzled/optimizer/quick_ror_intersect_select.h" |
1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
27 |
#include "drizzled/optimizer/range.h" |
28 |
#include "drizzled/sql_select.h" |
|
29 |
#include "drizzled/join.h" |
|
1241.9.64
by Monty Taylor
Moved remaining non-public portions of mysys and mystrings to drizzled/internal. |
30 |
#include "drizzled/internal/m_string.h" |
1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
31 |
|
1502.3.1
by iwamatsu at nigauri
Add cstdio include to files needing it. Fixes the build on some debian |
32 |
#include <cstdio> |
1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
33 |
#include <string> |
1241.9.17
by Monty Taylor
Removed more bits from server_includes. |
34 |
#include <sstream> |
1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
35 |
|
36 |
using namespace std; |
|
1280.1.10
by Monty Taylor
Put everything in drizzled into drizzled namespace. |
37 |
|
38 |
namespace drizzled |
|
39 |
{
|
|
1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
40 |
|
41 |
static const string access_method_str[]= |
|
42 |
{
|
|
43 |
"UNKNOWN", |
|
44 |
"system", |
|
45 |
"const", |
|
46 |
"eq_ref", |
|
47 |
"ref", |
|
48 |
"MAYBE_REF", |
|
49 |
"ALL", |
|
50 |
"range", |
|
51 |
"index", |
|
52 |
"ref_or_null", |
|
53 |
"unique_subquery", |
|
54 |
"index_subquery", |
|
55 |
"index_merge"
|
|
56 |
};
|
|
57 |
||
1237.13.30
by Padraig O'Sullivan
Corrected a valgrind warning due to using std::string in the Select_Lex class whose memory is |
58 |
static const string select_type_str[]= |
59 |
{
|
|
60 |
"PRIMARY", |
|
61 |
"SIMPLE", |
|
62 |
"DERIVED", |
|
63 |
"DEPENDENT SUBQUERY", |
|
64 |
"UNCACHEABLE SUBQUERY", |
|
65 |
"SUBQUERY", |
|
66 |
"DEPENDENT UNION", |
|
67 |
"UNCACHEABLE_UNION", |
|
68 |
"UNION", |
|
69 |
"UNION RESULT"
|
|
70 |
};
|
|
71 |
||
1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
72 |
void optimizer::ExplainPlan::printPlan() |
73 |
{
|
|
74 |
List<Item> field_list; |
|
75 |
List<Item> item_list; |
|
76 |
Session *session= join->session; |
|
77 |
select_result *result= join->result; |
|
78 |
Item *item_null= new Item_null(); |
|
79 |
const CHARSET_INFO * const cs= system_charset_info; |
|
80 |
int quick_type; |
|
81 |
/* Don't log this into the slow query log */
|
|
82 |
session->server_status&= ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED); |
|
83 |
join->unit->offset_limit_cnt= 0; |
|
84 |
||
85 |
/*
|
|
86 |
NOTE: the number/types of items pushed into item_list must be in sync with
|
|
87 |
EXPLAIN column types as they're "defined" in Session::send_explain_fields()
|
|
88 |
*/
|
|
89 |
if (message) |
|
90 |
{
|
|
91 |
item_list.push_back(new Item_int((int32_t) |
|
92 |
join->select_lex->select_number)); |
|
1237.13.30
by Padraig O'Sullivan
Corrected a valgrind warning due to using std::string in the Select_Lex class whose memory is |
93 |
item_list.push_back(new Item_string(select_type_str[join->select_lex->type].c_str(), |
94 |
select_type_str[join->select_lex->type].length(), |
|
1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
95 |
cs)); |
96 |
for (uint32_t i= 0; i < 7; i++) |
|
97 |
item_list.push_back(item_null); |
|
98 |
||
99 |
if (join->session->lex->describe & DESCRIBE_EXTENDED) |
|
100 |
item_list.push_back(item_null); |
|
101 |
||
102 |
item_list.push_back(new Item_string(message,strlen(message),cs)); |
|
103 |
if (result->send_data(item_list)) |
|
104 |
join->error= 1; |
|
105 |
}
|
|
106 |
else if (join->select_lex == join->unit->fake_select_lex) |
|
107 |
{
|
|
108 |
/*
|
|
109 |
here we assume that the query will return at least two rows, so we
|
|
110 |
show "filesort" in EXPLAIN. Of course, sometimes we'll be wrong
|
|
111 |
and no filesort will be actually done, but executing all selects in
|
|
112 |
the UNION to provide precise EXPLAIN information will hardly be
|
|
113 |
appreciated :)
|
|
114 |
*/
|
|
115 |
char table_name_buffer[NAME_LEN]; |
|
116 |
item_list.empty(); |
|
117 |
/* id */
|
|
118 |
item_list.push_back(new Item_null); |
|
119 |
/* select_type */
|
|
1237.13.30
by Padraig O'Sullivan
Corrected a valgrind warning due to using std::string in the Select_Lex class whose memory is |
120 |
item_list.push_back(new Item_string(select_type_str[join->select_lex->type].c_str(), |
121 |
select_type_str[join->select_lex->type].length(), |
|
1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
122 |
cs)); |
123 |
/* table */
|
|
124 |
{
|
|
125 |
Select_Lex *sl= join->unit->first_select(); |
|
126 |
uint32_t len= 6, lastop= 0; |
|
127 |
memcpy(table_name_buffer, STRING_WITH_LEN("<union")); |
|
128 |
for (; sl && len + lastop + 5 < NAME_LEN; sl= sl->next_select()) |
|
129 |
{
|
|
130 |
len+= lastop; |
|
131 |
lastop= snprintf(table_name_buffer + len, NAME_LEN - len, |
|
132 |
"%u,", sl->select_number); |
|
133 |
}
|
|
134 |
if (sl || len + lastop >= NAME_LEN) |
|
135 |
{
|
|
136 |
memcpy(table_name_buffer + len, STRING_WITH_LEN("...>") + 1); |
|
137 |
len+= 4; |
|
138 |
}
|
|
139 |
else
|
|
140 |
{
|
|
141 |
len+= lastop; |
|
142 |
table_name_buffer[len - 1]= '>'; // change ',' to '>' |
|
143 |
}
|
|
144 |
item_list.push_back(new Item_string(table_name_buffer, len, cs)); |
|
145 |
}
|
|
146 |
/* type */
|
|
147 |
item_list.push_back(new Item_string(access_method_str[AM_ALL].c_str(), |
|
148 |
access_method_str[AM_ALL].length(), |
|
149 |
cs)); |
|
150 |
/* possible_keys */
|
|
151 |
item_list.push_back(item_null); |
|
152 |
/* key*/
|
|
153 |
item_list.push_back(item_null); |
|
154 |
/* key_len */
|
|
155 |
item_list.push_back(item_null); |
|
156 |
/* ref */
|
|
157 |
item_list.push_back(item_null); |
|
158 |
/* in_rows */
|
|
159 |
if (join->session->lex->describe & DESCRIBE_EXTENDED) |
|
160 |
item_list.push_back(item_null); |
|
161 |
/* rows */
|
|
162 |
item_list.push_back(item_null); |
|
163 |
/* extra */
|
|
164 |
if (join->unit->global_parameters->order_list.first) |
|
165 |
item_list.push_back(new Item_string("Using filesort", |
|
166 |
14, |
|
167 |
cs)); |
|
168 |
else
|
|
169 |
item_list.push_back(new Item_string("", 0, cs)); |
|
170 |
||
171 |
if (result->send_data(item_list)) |
|
172 |
join->error= 1; |
|
173 |
}
|
|
174 |
else
|
|
175 |
{
|
|
176 |
table_map used_tables= 0; |
|
177 |
for (uint32_t i= 0; i < join->tables; i++) |
|
178 |
{
|
|
179 |
JoinTable *tab= join->join_tab + i; |
|
180 |
Table *table= tab->table; |
|
181 |
char buff[512]; |
|
182 |
char buff1[512], buff2[512], buff3[512]; |
|
183 |
char keylen_str_buf[64]; |
|
184 |
String extra(buff, sizeof(buff),cs); |
|
185 |
char table_name_buffer[NAME_LEN]; |
|
186 |
String tmp1(buff1,sizeof(buff1),cs); |
|
187 |
String tmp2(buff2,sizeof(buff2),cs); |
|
188 |
String tmp3(buff3,sizeof(buff3),cs); |
|
189 |
extra.length(0); |
|
190 |
tmp1.length(0); |
|
191 |
tmp2.length(0); |
|
192 |
tmp3.length(0); |
|
193 |
||
194 |
quick_type= -1; |
|
195 |
item_list.empty(); |
|
196 |
/* id */
|
|
197 |
item_list.push_back(new Item_uint((uint32_t) |
|
198 |
join->select_lex->select_number)); |
|
199 |
/* select_type */
|
|
1237.13.30
by Padraig O'Sullivan
Corrected a valgrind warning due to using std::string in the Select_Lex class whose memory is |
200 |
item_list.push_back(new Item_string(select_type_str[join->select_lex->type].c_str(), |
201 |
select_type_str[join->select_lex->type].length(), |
|
1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
202 |
cs)); |
203 |
if (tab->type == AM_ALL && tab->select && tab->select->quick) |
|
204 |
{
|
|
205 |
quick_type= tab->select->quick->get_type(); |
|
1240.7.6
by Padraig O'Sullivan
Resolved one last conflict after the merge from trunk. |
206 |
if ((quick_type == optimizer::QuickSelectInterface::QS_TYPE_INDEX_MERGE) || |
207 |
(quick_type == optimizer::QuickSelectInterface::QS_TYPE_ROR_INTERSECT) || |
|
208 |
(quick_type == optimizer::QuickSelectInterface::QS_TYPE_ROR_UNION)) |
|
1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
209 |
tab->type = AM_INDEX_MERGE; |
210 |
else
|
|
211 |
tab->type = AM_RANGE; |
|
212 |
}
|
|
213 |
/* table */
|
|
214 |
if (table->derived_select_number) |
|
215 |
{
|
|
216 |
/* Derived table name generation */
|
|
217 |
int len= snprintf(table_name_buffer, |
|
218 |
sizeof(table_name_buffer)-1, |
|
219 |
"<derived%u>", |
|
220 |
table->derived_select_number); |
|
221 |
item_list.push_back(new Item_string(table_name_buffer, len, cs)); |
|
222 |
}
|
|
223 |
else
|
|
224 |
{
|
|
225 |
TableList *real_table= table->pos_in_table_list; |
|
226 |
item_list.push_back(new Item_string(real_table->alias, |
|
1240.7.3
by Padraig O'Sullivan
Used std::string for the type in Select_Lex instead of char *. |
227 |
strlen(real_table->alias), |
228 |
cs)); |
|
1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
229 |
}
|
230 |
/* "type" column */
|
|
231 |
item_list.push_back(new Item_string(access_method_str[tab->type].c_str(), |
|
232 |
access_method_str[tab->type].length(), |
|
233 |
cs)); |
|
234 |
/* Build "possible_keys" value and add it to item_list */
|
|
235 |
if (tab->keys.any()) |
|
236 |
{
|
|
1578.2.10
by Brian Aker
keys and fields partial encapsulation. |
237 |
for (uint32_t j= 0; j < table->getShare()->sizeKeys(); j++) |
1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
238 |
{
|
239 |
if (tab->keys.test(j)) |
|
240 |
{
|
|
241 |
if (tmp1.length()) |
|
242 |
tmp1.append(','); |
|
243 |
tmp1.append(table->key_info[j].name, |
|
244 |
strlen(table->key_info[j].name), |
|
245 |
system_charset_info); |
|
246 |
}
|
|
247 |
}
|
|
248 |
}
|
|
249 |
if (tmp1.length()) |
|
250 |
item_list.push_back(new Item_string(tmp1.ptr(),tmp1.length(),cs)); |
|
251 |
else
|
|
252 |
item_list.push_back(item_null); |
|
253 |
||
254 |
/* Build "key", "key_len", and "ref" values and add them to item_list */
|
|
255 |
if (tab->ref.key_parts) |
|
256 |
{
|
|
1535
by Brian Aker
Rename of KEY to KeyInfo |
257 |
KeyInfo *key_info= table->key_info+ tab->ref.key; |
1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
258 |
item_list.push_back(new Item_string(key_info->name, |
259 |
strlen(key_info->name), |
|
260 |
system_charset_info)); |
|
1280.1.10
by Monty Taylor
Put everything in drizzled into drizzled namespace. |
261 |
uint32_t length= internal::int64_t2str(tab->ref.key_length, keylen_str_buf, 10) - |
1240.7.3
by Padraig O'Sullivan
Used std::string for the type in Select_Lex instead of char *. |
262 |
keylen_str_buf; |
1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
263 |
item_list.push_back(new Item_string(keylen_str_buf, |
264 |
length, |
|
265 |
system_charset_info)); |
|
266 |
for (StoredKey **ref= tab->ref.key_copy; *ref; ref++) |
|
267 |
{
|
|
268 |
if (tmp2.length()) |
|
269 |
tmp2.append(','); |
|
270 |
tmp2.append((*ref)->name(), |
|
271 |
strlen((*ref)->name()), |
|
272 |
system_charset_info); |
|
273 |
}
|
|
274 |
item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs)); |
|
275 |
}
|
|
276 |
else if (tab->type == AM_NEXT) |
|
277 |
{
|
|
1535
by Brian Aker
Rename of KEY to KeyInfo |
278 |
KeyInfo *key_info=table->key_info+ tab->index; |
1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
279 |
item_list.push_back(new Item_string(key_info->name, |
280 |
strlen(key_info->name),cs)); |
|
1280.1.10
by Monty Taylor
Put everything in drizzled into drizzled namespace. |
281 |
uint32_t length= internal::int64_t2str(key_info->key_length, keylen_str_buf, 10) - |
1240.7.3
by Padraig O'Sullivan
Used std::string for the type in Select_Lex instead of char *. |
282 |
keylen_str_buf; |
1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
283 |
item_list.push_back(new Item_string(keylen_str_buf, |
284 |
length, |
|
285 |
system_charset_info)); |
|
286 |
item_list.push_back(item_null); |
|
287 |
}
|
|
288 |
else if (tab->select && tab->select->quick) |
|
289 |
{
|
|
290 |
tab->select->quick->add_keys_and_lengths(&tmp2, &tmp3); |
|
291 |
item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs)); |
|
292 |
item_list.push_back(new Item_string(tmp3.ptr(),tmp3.length(),cs)); |
|
293 |
item_list.push_back(item_null); |
|
294 |
}
|
|
295 |
else
|
|
296 |
{
|
|
297 |
item_list.push_back(item_null); |
|
298 |
item_list.push_back(item_null); |
|
299 |
item_list.push_back(item_null); |
|
300 |
}
|
|
301 |
||
302 |
/* Add "rows" field to item_list. */
|
|
303 |
double examined_rows; |
|
304 |
if (tab->select && tab->select->quick) |
|
1240.7.3
by Padraig O'Sullivan
Used std::string for the type in Select_Lex instead of char *. |
305 |
{
|
1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
306 |
examined_rows= rows2double(tab->select->quick->records); |
1240.7.3
by Padraig O'Sullivan
Used std::string for the type in Select_Lex instead of char *. |
307 |
}
|
1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
308 |
else if (tab->type == AM_NEXT || tab->type == AM_ALL) |
1240.7.3
by Padraig O'Sullivan
Used std::string for the type in Select_Lex instead of char *. |
309 |
{
|
1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
310 |
examined_rows= rows2double(tab->limit ? tab->limit : |
1240.7.3
by Padraig O'Sullivan
Used std::string for the type in Select_Lex instead of char *. |
311 |
tab->table->cursor->records()); |
312 |
}
|
|
1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
313 |
else
|
314 |
{
|
|
315 |
optimizer::Position cur_pos= join->getPosFromOptimalPlan(i); |
|
316 |
examined_rows= cur_pos.getFanout(); |
|
317 |
}
|
|
318 |
||
319 |
item_list.push_back(new Item_int((int64_t) (uint64_t) examined_rows, |
|
1240.7.3
by Padraig O'Sullivan
Used std::string for the type in Select_Lex instead of char *. |
320 |
MY_INT64_NUM_DECIMAL_DIGITS)); |
1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
321 |
|
322 |
/* Add "filtered" field to item_list. */
|
|
323 |
if (join->session->lex->describe & DESCRIBE_EXTENDED) |
|
324 |
{
|
|
325 |
float f= 0.0; |
|
326 |
if (examined_rows) |
|
327 |
{
|
|
328 |
optimizer::Position cur_pos= join->getPosFromOptimalPlan(i); |
|
1240.7.3
by Padraig O'Sullivan
Used std::string for the type in Select_Lex instead of char *. |
329 |
f= static_cast<float>(100.0 * cur_pos.getFanout() / examined_rows); |
1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
330 |
}
|
331 |
item_list.push_back(new Item_float(f, 2)); |
|
332 |
}
|
|
333 |
||
334 |
/* Build "Extra" field and add it to item_list. */
|
|
335 |
bool key_read= table->key_read; |
|
336 |
if ((tab->type == AM_NEXT || tab->type == AM_CONST) && |
|
337 |
table->covering_keys.test(tab->index)) |
|
338 |
key_read= 1; |
|
1240.7.6
by Padraig O'Sullivan
Resolved one last conflict after the merge from trunk. |
339 |
if (quick_type == optimizer::QuickSelectInterface::QS_TYPE_ROR_INTERSECT && |
1240.7.8
by Padraig O'Sullivan
Resolved some conflicts after merging with build. |
340 |
! ((optimizer::QuickRorIntersectSelect *) tab->select->quick)->need_to_fetch_row) |
1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
341 |
key_read= 1; |
342 |
||
343 |
if (tab->info) |
|
344 |
item_list.push_back(new Item_string(tab->info,strlen(tab->info),cs)); |
|
345 |
else if (tab->packed_info & TAB_INFO_HAVE_VALUE) |
|
346 |
{
|
|
347 |
if (tab->packed_info & TAB_INFO_USING_INDEX) |
|
348 |
extra.append(STRING_WITH_LEN("; Using index")); |
|
349 |
if (tab->packed_info & TAB_INFO_USING_WHERE) |
|
350 |
extra.append(STRING_WITH_LEN("; Using where")); |
|
351 |
if (tab->packed_info & TAB_INFO_FULL_SCAN_ON_NULL) |
|
352 |
extra.append(STRING_WITH_LEN("; Full scan on NULL key")); |
|
353 |
/* Skip initial "; "*/
|
|
354 |
const char *str= extra.ptr(); |
|
355 |
uint32_t len= extra.length(); |
|
356 |
if (len) |
|
357 |
{
|
|
358 |
str += 2; |
|
359 |
len -= 2; |
|
360 |
}
|
|
361 |
item_list.push_back(new Item_string(str, len, cs)); |
|
362 |
}
|
|
363 |
else
|
|
364 |
{
|
|
365 |
uint32_t keyno= MAX_KEY; |
|
366 |
if (tab->ref.key_parts) |
|
367 |
keyno= tab->ref.key; |
|
368 |
else if (tab->select && tab->select->quick) |
|
369 |
keyno = tab->select->quick->index; |
|
370 |
||
1240.7.6
by Padraig O'Sullivan
Resolved one last conflict after the merge from trunk. |
371 |
if (quick_type == optimizer::QuickSelectInterface::QS_TYPE_ROR_UNION || |
372 |
quick_type == optimizer::QuickSelectInterface::QS_TYPE_ROR_INTERSECT || |
|
373 |
quick_type == optimizer::QuickSelectInterface::QS_TYPE_INDEX_MERGE) |
|
1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
374 |
{
|
375 |
extra.append(STRING_WITH_LEN("; Using ")); |
|
376 |
tab->select->quick->add_info_string(&extra); |
|
377 |
}
|
|
378 |
if (tab->select) |
|
379 |
{
|
|
380 |
if (tab->use_quick == 2) |
|
381 |
{
|
|
382 |
/*
|
|
383 |
* To print out the bitset in tab->keys, we go through
|
|
384 |
* it 32 bits at a time. We need to do this to ensure
|
|
385 |
* that the to_ulong() method will not throw an
|
|
386 |
* out_of_range exception at runtime which would happen
|
|
387 |
* if the bitset we were working with was larger than 64
|
|
388 |
* bits on a 64-bit platform (for example).
|
|
389 |
*/
|
|
390 |
stringstream s, w; |
|
391 |
string str; |
|
392 |
w << tab->keys; |
|
393 |
w >> str; |
|
394 |
for (uint32_t pos= 0; pos < tab->keys.size(); pos+= 32) |
|
395 |
{
|
|
396 |
bitset<32> tmp(str, pos, 32); |
|
397 |
if (tmp.any()) |
|
398 |
s << uppercase << hex << tmp.to_ulong(); |
|
399 |
}
|
|
400 |
extra.append(STRING_WITH_LEN("; Range checked for each " |
|
401 |
"record (index map: 0x")); |
|
402 |
extra.append(s.str().c_str()); |
|
403 |
extra.append(')'); |
|
404 |
}
|
|
405 |
else if (tab->select->cond) |
|
406 |
{
|
|
407 |
extra.append(STRING_WITH_LEN("; Using where")); |
|
408 |
}
|
|
409 |
}
|
|
410 |
if (key_read) |
|
411 |
{
|
|
1240.7.6
by Padraig O'Sullivan
Resolved one last conflict after the merge from trunk. |
412 |
if (quick_type == optimizer::QuickSelectInterface::QS_TYPE_GROUP_MIN_MAX) |
1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
413 |
extra.append(STRING_WITH_LEN("; Using index for group-by")); |
414 |
else
|
|
415 |
extra.append(STRING_WITH_LEN("; Using index")); |
|
416 |
}
|
|
417 |
if (table->reginfo.not_exists_optimize) |
|
418 |
extra.append(STRING_WITH_LEN("; Not exists")); |
|
419 |
||
420 |
if (need_tmp_table) |
|
421 |
{
|
|
422 |
need_tmp_table=0; |
|
423 |
extra.append(STRING_WITH_LEN("; Using temporary")); |
|
424 |
}
|
|
425 |
if (need_order) |
|
426 |
{
|
|
427 |
need_order=0; |
|
428 |
extra.append(STRING_WITH_LEN("; Using filesort")); |
|
429 |
}
|
|
430 |
if (distinct & test_all_bits(used_tables,session->used_tables)) |
|
431 |
extra.append(STRING_WITH_LEN("; Distinct")); |
|
432 |
||
433 |
if (tab->insideout_match_tab) |
|
434 |
{
|
|
435 |
extra.append(STRING_WITH_LEN("; LooseScan")); |
|
436 |
}
|
|
437 |
||
438 |
for (uint32_t part= 0; part < tab->ref.key_parts; part++) |
|
439 |
{
|
|
440 |
if (tab->ref.cond_guards[part]) |
|
441 |
{
|
|
442 |
extra.append(STRING_WITH_LEN("; Full scan on NULL key")); |
|
443 |
break; |
|
444 |
}
|
|
445 |
}
|
|
446 |
||
447 |
if (i > 0 && tab[-1].next_select == sub_select_cache) |
|
448 |
extra.append(STRING_WITH_LEN("; Using join buffer")); |
|
449 |
||
450 |
/* Skip initial "; "*/
|
|
451 |
const char *str= extra.ptr(); |
|
452 |
uint32_t len= extra.length(); |
|
453 |
if (len) |
|
454 |
{
|
|
455 |
str += 2; |
|
456 |
len -= 2; |
|
457 |
}
|
|
458 |
item_list.push_back(new Item_string(str, len, cs)); |
|
459 |
}
|
|
460 |
// For next iteration
|
|
461 |
used_tables|=table->map; |
|
462 |
if (result->send_data(item_list)) |
|
463 |
join->error= 1; |
|
464 |
}
|
|
465 |
}
|
|
466 |
for (Select_Lex_Unit *unit= join->select_lex->first_inner_unit(); |
|
467 |
unit; |
|
468 |
unit= unit->next_unit()) |
|
469 |
{
|
|
470 |
if (explainUnion(session, unit, result)) |
|
471 |
return; |
|
472 |
}
|
|
473 |
return; |
|
474 |
}
|
|
475 |
||
476 |
bool optimizer::ExplainPlan::explainUnion(Session *session, |
|
477 |
Select_Lex_Unit *unit, |
|
478 |
select_result *result) |
|
479 |
{
|
|
480 |
bool res= false; |
|
481 |
Select_Lex *first= unit->first_select(); |
|
482 |
||
483 |
for (Select_Lex *sl= first; |
|
484 |
sl; |
|
485 |
sl= sl->next_select()) |
|
486 |
{
|
|
487 |
// drop UNCACHEABLE_EXPLAIN, because it is for internal usage only
|
|
488 |
uint8_t uncacheable= (sl->uncacheable & ~UNCACHEABLE_EXPLAIN); |
|
1240.7.2
by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested |
489 |
if (&session->lex->select_lex == sl) |
490 |
{
|
|
491 |
if (sl->first_inner_unit() || sl->next_select()) |
|
492 |
{
|
|
1237.13.30
by Padraig O'Sullivan
Corrected a valgrind warning due to using std::string in the Select_Lex class whose memory is |
493 |
sl->type= optimizer::ST_PRIMARY; |
1240.7.2
by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested |
494 |
}
|
495 |
else
|
|
496 |
{
|
|
1237.13.30
by Padraig O'Sullivan
Corrected a valgrind warning due to using std::string in the Select_Lex class whose memory is |
497 |
sl->type= optimizer::ST_SIMPLE; |
1240.7.2
by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested |
498 |
}
|
499 |
}
|
|
500 |
else
|
|
501 |
{
|
|
502 |
if (sl == first) |
|
503 |
{
|
|
504 |
if (sl->linkage == DERIVED_TABLE_TYPE) |
|
505 |
{
|
|
1237.13.30
by Padraig O'Sullivan
Corrected a valgrind warning due to using std::string in the Select_Lex class whose memory is |
506 |
sl->type= optimizer::ST_DERIVED; |
1240.7.2
by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested |
507 |
}
|
508 |
else
|
|
509 |
{
|
|
510 |
if (uncacheable & UNCACHEABLE_DEPENDENT) |
|
511 |
{
|
|
1237.13.30
by Padraig O'Sullivan
Corrected a valgrind warning due to using std::string in the Select_Lex class whose memory is |
512 |
sl->type= optimizer::ST_DEPENDENT_SUBQUERY; |
1240.7.2
by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested |
513 |
}
|
514 |
else
|
|
515 |
{
|
|
516 |
if (uncacheable) |
|
517 |
{
|
|
1237.13.30
by Padraig O'Sullivan
Corrected a valgrind warning due to using std::string in the Select_Lex class whose memory is |
518 |
sl->type= optimizer::ST_UNCACHEABLE_SUBQUERY; |
1240.7.2
by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested |
519 |
}
|
520 |
else
|
|
521 |
{
|
|
1237.13.30
by Padraig O'Sullivan
Corrected a valgrind warning due to using std::string in the Select_Lex class whose memory is |
522 |
sl->type= optimizer::ST_SUBQUERY; |
1240.7.2
by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested |
523 |
}
|
524 |
}
|
|
525 |
}
|
|
526 |
}
|
|
527 |
else
|
|
528 |
{
|
|
529 |
if (uncacheable & UNCACHEABLE_DEPENDENT) |
|
530 |
{
|
|
1237.13.30
by Padraig O'Sullivan
Corrected a valgrind warning due to using std::string in the Select_Lex class whose memory is |
531 |
sl->type= optimizer::ST_DEPENDENT_UNION; |
1240.7.2
by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested |
532 |
}
|
533 |
else
|
|
534 |
{
|
|
535 |
if (uncacheable) |
|
536 |
{
|
|
1237.13.30
by Padraig O'Sullivan
Corrected a valgrind warning due to using std::string in the Select_Lex class whose memory is |
537 |
sl->type= optimizer::ST_UNCACHEABLE_UNION; |
1240.7.2
by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested |
538 |
}
|
539 |
else
|
|
540 |
{
|
|
1237.13.30
by Padraig O'Sullivan
Corrected a valgrind warning due to using std::string in the Select_Lex class whose memory is |
541 |
sl->type= optimizer::ST_UNION; |
1240.7.2
by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested |
542 |
}
|
543 |
}
|
|
544 |
}
|
|
545 |
}
|
|
1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
546 |
sl->options|= SELECT_DESCRIBE; |
547 |
}
|
|
1240.7.2
by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested |
548 |
|
1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
549 |
if (unit->is_union()) |
550 |
{
|
|
1240.7.2
by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested |
551 |
unit->fake_select_lex->select_number= UINT_MAX; // just for initialization |
1237.13.30
by Padraig O'Sullivan
Corrected a valgrind warning due to using std::string in the Select_Lex class whose memory is |
552 |
unit->fake_select_lex->type= optimizer::ST_UNION_RESULT; |
1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
553 |
unit->fake_select_lex->options|= SELECT_DESCRIBE; |
554 |
if (! (res= unit->prepare(session, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE))) |
|
1240.7.2
by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested |
555 |
{
|
1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
556 |
res= unit->exec(); |
1240.7.2
by Padraig O'Sullivan
Updated the explainUnion method. I'm all for using the ? conditional statement but when it is nested |
557 |
}
|
1240.7.1
by Padraig O'Sullivan
Created an ExplainPlan class in the optimizer namespace. All printing of an explain in drizzle goes |
558 |
res|= unit->cleanup(); |
559 |
}
|
|
560 |
else
|
|
561 |
{
|
|
562 |
session->lex->current_select= first; |
|
563 |
unit->set_limit(unit->global_parameters); |
|
564 |
res= mysql_select(session, |
|
565 |
&first->ref_pointer_array, |
|
566 |
(TableList*) first->table_list.first, |
|
567 |
first->with_wild, |
|
568 |
first->item_list, |
|
569 |
first->where, |
|
570 |
first->order_list.elements + first->group_list.elements, |
|
571 |
(order_st*) first->order_list.first, |
|
572 |
(order_st*) first->group_list.first, |
|
573 |
first->having, |
|
574 |
first->options | session->options | SELECT_DESCRIBE, |
|
575 |
result, |
|
576 |
unit, |
|
577 |
first); |
|
578 |
}
|
|
579 |
return (res || session->is_error()); |
|
580 |
}
|
|
1280.1.10
by Monty Taylor
Put everything in drizzled into drizzled namespace. |
581 |
|
582 |
} /* namespace drizzled */ |