1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
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; either version 2 of the License, or
|
|
9 |
* (at your option) any later version.
|
|
10 |
*
|
|
11 |
* This program is distributed in the hope that it will be useful,
|
|
12 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14 |
* GNU General Public License for more details.
|
|
15 |
*
|
|
16 |
* You should have received a copy of the GNU General Public License
|
|
17 |
* along with this program; if not, write to the Free Software
|
|
18 |
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
19 |
*/
|
|
1
by brian
clean slate |
20 |
|
21 |
/**
|
|
22 |
@file
|
|
23 |
||
24 |
Optimising of MIN(), MAX() and COUNT(*) queries without 'group by' clause
|
|
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
25 |
by replacing the aggregate expression with a constant.
|
1
by brian
clean slate |
26 |
|
27 |
Given a table with a compound key on columns (a,b,c), the following
|
|
28 |
types of queries are optimised (assuming the table handler supports
|
|
29 |
the required methods)
|
|
30 |
||
31 |
@verbatim
|
|
32 |
SELECT COUNT(*) FROM t1[,t2,t3,...]
|
|
33 |
SELECT MIN(b) FROM t1 WHERE a=const
|
|
34 |
SELECT MAX(c) FROM t1 WHERE a=const AND b=const
|
|
35 |
SELECT MAX(b) FROM t1 WHERE a=const AND b<const
|
|
36 |
SELECT MIN(b) FROM t1 WHERE a=const AND b>const
|
|
37 |
SELECT MIN(b) FROM t1 WHERE a=const AND b BETWEEN const AND const
|
|
38 |
SELECT MAX(b) FROM t1 WHERE a=const AND b BETWEEN const AND const
|
|
39 |
@endverbatim
|
|
40 |
||
41 |
Instead of '<' one can use '<=', '>', '>=' and '=' as well.
|
|
42 |
Instead of 'a=const' the condition 'a IS NULL' can be used.
|
|
43 |
||
44 |
If all selected fields are replaced then we will also remove all
|
|
45 |
involved tables and return the answer without any join. Thus, the
|
|
46 |
following query will be replaced with a row of two constants:
|
|
47 |
@verbatim
|
|
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
48 |
SELECT MAX(b), MIN(d) FROM t1,t2
|
1
by brian
clean slate |
49 |
WHERE a=const AND b<const AND d>const
|
50 |
@endverbatim
|
|
51 |
(assuming a index for column d of table t2 is defined)
|
|
52 |
*/
|
|
53 |
||
1241.9.36
by Monty Taylor
ZOMG. I deleted drizzled/server_includes.h. |
54 |
#include "config.h" |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
55 |
#include "drizzled/sql_select.h" |
56 |
#include "drizzled/item/sum.h" |
|
57 |
#include "drizzled/item/cmpfunc.h" |
|
58 |
#include "drizzled/optimizer/sum.h" |
|
59 |
||
60 |
namespace drizzled |
|
61 |
{
|
|
62 |
||
1240.3.1
by Brian Aker
Merge Padraig. |
63 |
static bool find_key_for_maxmin(bool max_fl, |
64 |
table_reference_st *ref, |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
65 |
Field* field, |
1240.3.1
by Brian Aker
Merge Padraig. |
66 |
COND *cond, |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
67 |
uint32_t *range_fl, |
482
by Brian Aker
Remove uint. |
68 |
uint32_t *key_prefix_length); |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
69 |
|
1240.3.1
by Brian Aker
Merge Padraig. |
70 |
static int reckey_in_range(bool max_fl, |
71 |
table_reference_st *ref, |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
72 |
Field* field, |
1240.3.1
by Brian Aker
Merge Padraig. |
73 |
COND *cond, |
74 |
uint32_t range_fl, |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
75 |
uint32_t prefix_len); |
76 |
||
1237.13.5
by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files. |
77 |
static int maxmin_in_range(bool max_fl, Field *field, COND *cond); |
1
by brian
clean slate |
78 |
|
79 |
||
80 |
/*
|
|
81 |
Get exact count of rows in all tables
|
|
82 |
||
83 |
SYNOPSIS
|
|
84 |
get_exact_records()
|
|
85 |
tables List of tables
|
|
86 |
||
87 |
NOTES
|
|
88 |
When this is called, we know all table handlers supports HA_HAS_RECORDS
|
|
89 |
or HA_STATS_RECORDS_IS_EXACT
|
|
90 |
||
91 |
RETURN
|
|
163
by Brian Aker
Merge Monty's code. |
92 |
UINT64_MAX Error: Could not calculate number of rows
|
1
by brian
clean slate |
93 |
# Multiplication of number of rows in all tables
|
94 |
*/
|
|
327.2.4
by Brian Aker
Refactoring table.h |
95 |
static uint64_t get_exact_record_count(TableList *tables) |
1
by brian
clean slate |
96 |
{
|
151
by Brian Aker
Ulonglong to uint64_t |
97 |
uint64_t count= 1; |
327.2.4
by Brian Aker
Refactoring table.h |
98 |
for (TableList *tl= tables; tl; tl= tl->next_leaf) |
1
by brian
clean slate |
99 |
{
|
1208.3.2
by brian
Update for Cursor renaming. |
100 |
ha_rows tmp= tl->table->cursor->records(); |
1
by brian
clean slate |
101 |
if ((tmp == HA_POS_ERROR)) |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
102 |
{
|
163
by Brian Aker
Merge Monty's code. |
103 |
return UINT64_MAX; |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
104 |
}
|
1
by brian
clean slate |
105 |
count*= tmp; |
106 |
}
|
|
107 |
return count; |
|
108 |
}
|
|
109 |
||
110 |
||
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
111 |
int optimizer::sum_query(TableList *tables, List<Item> &all_fields, COND *conds) |
1
by brian
clean slate |
112 |
{
|
113 |
List_iterator_fast<Item> it(all_fields); |
|
114 |
int const_result= 1; |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
115 |
bool recalc_const_item= false; |
151
by Brian Aker
Ulonglong to uint64_t |
116 |
uint64_t count= 1; |
1240.3.1
by Brian Aker
Merge Padraig. |
117 |
bool is_exact_count= true; |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
118 |
bool maybe_exact_count= true; |
119 |
table_map removed_tables= 0; |
|
120 |
table_map outer_tables= 0; |
|
121 |
table_map used_tables= 0; |
|
1
by brian
clean slate |
122 |
table_map where_tables= 0; |
1237.13.5
by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files. |
123 |
Item *item= NULL; |
1
by brian
clean slate |
124 |
int error; |
125 |
||
126 |
if (conds) |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
127 |
{
|
1
by brian
clean slate |
128 |
where_tables= conds->used_tables(); |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
129 |
}
|
1
by brian
clean slate |
130 |
|
131 |
/*
|
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
132 |
Analyze outer join dependencies, and, if possible, compute the number
|
133 |
of returned rows.
|
|
134 |
*/
|
|
327.2.4
by Brian Aker
Refactoring table.h |
135 |
for (TableList *tl= tables; tl; tl= tl->next_leaf) |
1
by brian
clean slate |
136 |
{
|
1237.13.5
by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files. |
137 |
TableList *embedded= NULL; |
1637.2.7
by Vijay Samuel
Merge encapsulate TableList-2. |
138 |
for (embedded= tl; embedded; embedded= embedded->getEmbedding()) |
1
by brian
clean slate |
139 |
{
|
140 |
if (embedded->on_expr) |
|
141 |
break; |
|
142 |
}
|
|
143 |
if (embedded) |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
144 |
/* Don't replace expression on a table that is part of an outer join */
|
1
by brian
clean slate |
145 |
{
|
146 |
outer_tables|= tl->table->map; |
|
147 |
||
148 |
/*
|
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
149 |
We can't optimise LEFT JOIN in cases where the WHERE condition
|
150 |
restricts the table that is used, like in:
|
|
151 |
SELECT MAX(t1.a) FROM t1 LEFT JOIN t2 join-condition
|
|
152 |
WHERE t2.field IS NULL;
|
|
153 |
*/
|
|
1
by brian
clean slate |
154 |
if (tl->table->map & where_tables) |
155 |
return 0; |
|
156 |
}
|
|
157 |
else
|
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
158 |
{
|
1
by brian
clean slate |
159 |
used_tables|= tl->table->map; |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
160 |
}
|
1
by brian
clean slate |
161 |
|
162 |
/*
|
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
163 |
If the storage manager of 'tl' gives exact row count as part of
|
164 |
statistics (cheap), compute the total number of rows. If there are
|
|
165 |
no outer table dependencies, this count may be used as the real count.
|
|
166 |
Schema tables are filled after this function is invoked, so we can't
|
|
167 |
get row count
|
|
168 |
*/
|
|
169 |
if (! (tl->table->cursor->getEngine()->check_flag(HTON_BIT_STATS_RECORDS_IS_EXACT))) |
|
1
by brian
clean slate |
170 |
{
|
1234.1.3
by Brian Aker
Merge in removal of table_flags. |
171 |
maybe_exact_count&= test(tl->table->cursor->getEngine()->check_flag(HTON_BIT_HAS_RECORDS)); |
51.1.35
by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE |
172 |
is_exact_count= false; |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
173 |
count= 1; // ensure count != 0 |
1
by brian
clean slate |
174 |
}
|
175 |
else
|
|
176 |
{
|
|
1208.3.2
by brian
Update for Cursor renaming. |
177 |
error= tl->table->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); |
1
by brian
clean slate |
178 |
if(error) |
179 |
{
|
|
1216.1.1
by Brian Aker
Move print_error up to Engine. |
180 |
tl->table->print_error(error, MYF(ME_FATALERROR)); |
1
by brian
clean slate |
181 |
return error; |
182 |
}
|
|
1208.3.2
by brian
Update for Cursor renaming. |
183 |
count*= tl->table->cursor->stats.records; |
1
by brian
clean slate |
184 |
}
|
185 |
}
|
|
186 |
||
187 |
/*
|
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
188 |
Iterate through all items in the SELECT clause and replace
|
189 |
COUNT(), MIN() and MAX() with constants (if possible).
|
|
190 |
*/
|
|
1
by brian
clean slate |
191 |
|
192 |
while ((item= it++)) |
|
193 |
{
|
|
194 |
if (item->type() == Item::SUM_FUNC_ITEM) |
|
195 |
{
|
|
196 |
Item_sum *item_sum= (((Item_sum*) item)); |
|
1240.3.1
by Brian Aker
Merge Padraig. |
197 |
switch (item_sum->sum_func()) |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
198 |
{
|
199 |
case Item_sum::COUNT_FUNC: |
|
200 |
/*
|
|
201 |
If the expr in COUNT(expr) can never be null we can change this
|
|
202 |
to the number of rows in the tables if this number is exact and
|
|
203 |
there are no outer joins.
|
|
204 |
*/
|
|
205 |
if (! conds && ! ((Item_sum_count*) item)->args[0]->maybe_null && |
|
206 |
! outer_tables && maybe_exact_count) |
|
207 |
{
|
|
208 |
if (! is_exact_count) |
|
209 |
{
|
|
210 |
if ((count= get_exact_record_count(tables)) == UINT64_MAX) |
|
211 |
{
|
|
212 |
/* Error from handler in counting rows. Don't optimize count() */
|
|
213 |
const_result= 0; |
|
214 |
continue; |
|
215 |
}
|
|
216 |
is_exact_count= 1; // count is now exact |
|
217 |
}
|
|
218 |
((Item_sum_count*) item)->make_const_count((int64_t) count); |
|
219 |
recalc_const_item= 1; |
|
220 |
}
|
|
221 |
else
|
|
222 |
{
|
|
223 |
const_result= 0; |
|
224 |
}
|
|
225 |
break; |
|
226 |
case Item_sum::MIN_FUNC: |
|
227 |
{
|
|
228 |
/*
|
|
229 |
If MIN(expr) is the first part of a key or if all previous
|
|
230 |
parts of the key is found in the COND, then we can use
|
|
231 |
indexes to find the key.
|
|
232 |
*/
|
|
233 |
Item *expr=item_sum->args[0]; |
|
234 |
if (expr->real_item()->type() == Item::FIELD_ITEM) |
|
235 |
{
|
|
236 |
unsigned char key_buff[MAX_KEY_LENGTH]; |
|
237 |
table_reference_st ref; |
|
238 |
uint32_t range_fl, prefix_len; |
|
239 |
||
240 |
ref.key_buff= key_buff; |
|
241 |
Item_field *item_field= (Item_field*) (expr->real_item()); |
|
1660.1.3
by Brian Aker
Encapsulate Table in field |
242 |
Table *table= item_field->field->getTable(); |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
243 |
|
244 |
/*
|
|
245 |
Look for a partial key that can be used for optimization.
|
|
246 |
If we succeed, ref.key_length will contain the length of
|
|
247 |
this key, while prefix_len will contain the length of
|
|
248 |
the beginning of this key without field used in MIN().
|
|
249 |
Type of range for the key part for this field will be
|
|
250 |
returned in range_fl.
|
|
251 |
*/
|
|
1240.3.1
by Brian Aker
Merge Padraig. |
252 |
if (table->cursor->inited || |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
253 |
(outer_tables & table->map) || |
1240.3.1
by Brian Aker
Merge Padraig. |
254 |
! find_key_for_maxmin(0, |
255 |
&ref, |
|
256 |
item_field->field, |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
257 |
conds, |
1240.3.1
by Brian Aker
Merge Padraig. |
258 |
&range_fl, |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
259 |
&prefix_len)) |
260 |
{
|
|
261 |
const_result= 0; |
|
262 |
break; |
|
263 |
}
|
|
1491.1.6
by Jay Pipes
Cursor::ha_index_init() -> Cursor::startIndexScan(). Cursor::ha_index_end() -> Cursor::endIndexScan() |
264 |
error= table->cursor->startIndexScan(static_cast<uint32_t>(ref.key), 1); |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
265 |
|
266 |
if (! ref.key_length) |
|
267 |
{
|
|
268 |
error= table->cursor->index_first(table->record[0]); |
|
269 |
}
|
|
270 |
else
|
|
271 |
{
|
|
272 |
/*
|
|
273 |
Use index to replace MIN/MAX functions with their values
|
|
274 |
according to the following rules:
|
|
275 |
||
276 |
1) Insert the minimum non-null values where the WHERE clause still
|
|
277 |
matches, or
|
|
278 |
2) a NULL value if there are only NULL values for key_part_k.
|
|
279 |
3) Fail, producing a row of nulls
|
|
280 |
||
281 |
Implementation: Read the smallest value using the search key. If
|
|
282 |
the interval is open, read the next value after the search
|
|
283 |
key. If read fails, and we're looking for a MIN() value for a
|
|
284 |
nullable column, test if there is an exact match for the key.
|
|
285 |
*/
|
|
286 |
if (! (range_fl & NEAR_MIN)) |
|
1237.13.5
by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files. |
287 |
{
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
288 |
/*
|
289 |
Closed interval: Either The MIN argument is non-nullable, or
|
|
290 |
we have a >= predicate for the MIN argument.
|
|
291 |
*/
|
|
292 |
error= table->cursor->index_read_map(table->record[0], |
|
293 |
ref.key_buff, |
|
294 |
make_prev_keypart_map(ref.key_parts), |
|
295 |
HA_READ_KEY_OR_NEXT); |
|
1237.13.5
by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files. |
296 |
}
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
297 |
else
|
298 |
{
|
|
299 |
/*
|
|
300 |
Open interval: There are two cases:
|
|
301 |
1) We have only MIN() and the argument column is nullable, or
|
|
302 |
2) there is a > predicate on it, nullability is irrelevant.
|
|
303 |
We need to scan the next bigger record first.
|
|
304 |
*/
|
|
305 |
error= table->cursor->index_read_map(table->record[0], |
|
306 |
ref.key_buff, |
|
307 |
make_prev_keypart_map(ref.key_parts), |
|
308 |
HA_READ_AFTER_KEY); |
|
309 |
/*
|
|
310 |
If the found record is outside the group formed by the search
|
|
311 |
prefix, or there is no such record at all, check if all
|
|
312 |
records in that group have NULL in the MIN argument
|
|
313 |
column. If that is the case return that NULL.
|
|
314 |
||
315 |
Check if case 1 from above holds. If it does, we should read
|
|
316 |
the skipped tuple.
|
|
317 |
*/
|
|
318 |
if (item_field->field->real_maybe_null() && |
|
319 |
ref.key_buff[prefix_len] == 1 && |
|
320 |
/*
|
|
321 |
Last keypart (i.e. the argument to MIN) is set to NULL by
|
|
322 |
find_key_for_maxmin only if all other keyparts are bound
|
|
323 |
to constants in a conjunction of equalities. Hence, we
|
|
324 |
can detect this by checking only if the last keypart is
|
|
325 |
NULL.
|
|
326 |
*/
|
|
327 |
(error == HA_ERR_KEY_NOT_FOUND || |
|
328 |
key_cmp_if_same(table, ref.key_buff, ref.key, prefix_len))) |
|
329 |
{
|
|
330 |
assert(item_field->field->real_maybe_null()); |
|
331 |
error= table->cursor->index_read_map(table->record[0], |
|
332 |
ref.key_buff, |
|
333 |
make_prev_keypart_map(ref.key_parts), |
|
334 |
HA_READ_KEY_EXACT); |
|
335 |
}
|
|
336 |
}
|
|
337 |
}
|
|
338 |
/* Verify that the read tuple indeed matches the search key */
|
|
1240.3.1
by Brian Aker
Merge Padraig. |
339 |
if (! error && |
340 |
reckey_in_range(0, |
|
341 |
&ref, |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
342 |
item_field->field, |
1240.3.1
by Brian Aker
Merge Padraig. |
343 |
conds, |
344 |
range_fl, |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
345 |
prefix_len)) |
346 |
{
|
|
347 |
error= HA_ERR_KEY_NOT_FOUND; |
|
348 |
}
|
|
349 |
if (table->key_read) |
|
350 |
{
|
|
351 |
table->key_read= 0; |
|
352 |
table->cursor->extra(HA_EXTRA_NO_KEYREAD); |
|
353 |
}
|
|
1491.1.6
by Jay Pipes
Cursor::ha_index_init() -> Cursor::startIndexScan(). Cursor::ha_index_end() -> Cursor::endIndexScan() |
354 |
table->cursor->endIndexScan(); |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
355 |
if (error) |
356 |
{
|
|
357 |
if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE) |
|
358 |
{
|
|
359 |
return HA_ERR_KEY_NOT_FOUND; // No rows matching WHERE |
|
360 |
}
|
|
361 |
/* HA_ERR_LOCK_DEADLOCK or some other error */
|
|
362 |
table->print_error(error, MYF(0)); |
|
363 |
return error; |
|
364 |
}
|
|
365 |
removed_tables|= table->map; |
|
366 |
}
|
|
367 |
else if (! expr->const_item() || ! is_exact_count) |
|
368 |
{
|
|
369 |
/*
|
|
370 |
The optimization is not applicable in both cases:
|
|
371 |
(a) 'expr' is a non-constant expression. Then we can't
|
|
372 |
replace 'expr' by a constant.
|
|
373 |
(b) 'expr' is a costant. According to ANSI, MIN/MAX must return
|
|
374 |
NULL if the query does not return any rows. Thus, if we are not
|
|
375 |
able to determine if the query returns any rows, we can't apply
|
|
376 |
the optimization and replace MIN/MAX with a constant.
|
|
377 |
*/
|
|
378 |
const_result= 0; |
|
379 |
break; |
|
380 |
}
|
|
381 |
if (! count) |
|
382 |
{
|
|
383 |
/* If count == 0, then we know that is_exact_count == true. */
|
|
384 |
((Item_sum_min*) item_sum)->clear(); /* Set to NULL. */ |
|
385 |
}
|
|
386 |
else
|
|
387 |
{
|
|
388 |
((Item_sum_min*) item_sum)->reset(); /* Set to the constant value. */ |
|
389 |
}
|
|
390 |
((Item_sum_min*) item_sum)->make_const(); |
|
391 |
recalc_const_item= 1; |
|
392 |
break; |
|
393 |
}
|
|
394 |
case Item_sum::MAX_FUNC: |
|
395 |
{
|
|
396 |
/*
|
|
397 |
If MAX(expr) is the first part of a key or if all previous
|
|
398 |
parts of the key is found in the COND, then we can use
|
|
399 |
indexes to find the key.
|
|
400 |
*/
|
|
401 |
Item *expr= item_sum->args[0]; |
|
402 |
if (expr->real_item()->type() == Item::FIELD_ITEM) |
|
403 |
{
|
|
404 |
unsigned char key_buff[MAX_KEY_LENGTH]; |
|
405 |
table_reference_st ref; |
|
406 |
uint32_t range_fl, prefix_len; |
|
407 |
||
408 |
ref.key_buff= key_buff; |
|
409 |
Item_field *item_field= (Item_field*) (expr->real_item()); |
|
1660.1.3
by Brian Aker
Encapsulate Table in field |
410 |
Table *table= item_field->field->getTable(); |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
411 |
|
412 |
/*
|
|
413 |
Look for a partial key that can be used for optimization.
|
|
414 |
If we succeed, ref.key_length will contain the length of
|
|
415 |
this key, while prefix_len will contain the length of
|
|
416 |
the beginning of this key without field used in MAX().
|
|
417 |
Type of range for the key part for this field will be
|
|
418 |
returned in range_fl.
|
|
419 |
*/
|
|
1240.3.1
by Brian Aker
Merge Padraig. |
420 |
if (table->cursor->inited || |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
421 |
(outer_tables & table->map) || |
1240.3.1
by Brian Aker
Merge Padraig. |
422 |
! find_key_for_maxmin(1, |
423 |
&ref, |
|
424 |
item_field->field, |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
425 |
conds, |
1240.3.1
by Brian Aker
Merge Padraig. |
426 |
&range_fl, |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
427 |
&prefix_len)) |
428 |
{
|
|
429 |
const_result= 0; |
|
430 |
break; |
|
431 |
}
|
|
1491.1.6
by Jay Pipes
Cursor::ha_index_init() -> Cursor::startIndexScan(). Cursor::ha_index_end() -> Cursor::endIndexScan() |
432 |
error= table->cursor->startIndexScan(static_cast<uint32_t>(ref.key), 1); |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
433 |
|
434 |
if (! ref.key_length) |
|
435 |
{
|
|
436 |
error= table->cursor->index_last(table->record[0]); |
|
437 |
}
|
|
438 |
else
|
|
439 |
{
|
|
1240.3.1
by Brian Aker
Merge Padraig. |
440 |
error= table->cursor->index_read_map(table->record[0], |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
441 |
key_buff, |
442 |
make_prev_keypart_map(ref.key_parts), |
|
443 |
range_fl & NEAR_MAX ? |
|
444 |
HA_READ_BEFORE_KEY : |
|
445 |
HA_READ_PREFIX_LAST_OR_PREV); |
|
446 |
}
|
|
1240.3.1
by Brian Aker
Merge Padraig. |
447 |
if (! error && |
448 |
reckey_in_range(1, |
|
449 |
&ref, |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
450 |
item_field->field, |
1240.3.1
by Brian Aker
Merge Padraig. |
451 |
conds, |
452 |
range_fl, |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
453 |
prefix_len)) |
454 |
{
|
|
455 |
error= HA_ERR_KEY_NOT_FOUND; |
|
456 |
}
|
|
457 |
if (table->key_read) |
|
458 |
{
|
|
459 |
table->key_read= 0; |
|
460 |
table->cursor->extra(HA_EXTRA_NO_KEYREAD); |
|
461 |
}
|
|
1491.1.6
by Jay Pipes
Cursor::ha_index_init() -> Cursor::startIndexScan(). Cursor::ha_index_end() -> Cursor::endIndexScan() |
462 |
table->cursor->endIndexScan(); |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
463 |
if (error) |
464 |
{
|
|
465 |
if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE) |
|
466 |
{
|
|
467 |
return HA_ERR_KEY_NOT_FOUND; // No rows matching WHERE |
|
468 |
}
|
|
469 |
/* HA_ERR_LOCK_DEADLOCK or some other error */
|
|
470 |
table->print_error(error, MYF(ME_FATALERROR)); |
|
471 |
return error; |
|
472 |
}
|
|
473 |
removed_tables|= table->map; |
|
474 |
}
|
|
475 |
else if (! expr->const_item() || ! is_exact_count) |
|
476 |
{
|
|
477 |
/*
|
|
478 |
The optimization is not applicable in both cases:
|
|
479 |
(a) 'expr' is a non-constant expression. Then we can't
|
|
480 |
replace 'expr' by a constant.
|
|
481 |
(b) 'expr' is a costant. According to ANSI, MIN/MAX must return
|
|
482 |
NULL if the query does not return any rows. Thus, if we are not
|
|
483 |
able to determine if the query returns any rows, we can't apply
|
|
484 |
the optimization and replace MIN/MAX with a constant.
|
|
485 |
*/
|
|
486 |
const_result= 0; |
|
487 |
break; |
|
488 |
}
|
|
489 |
if (! count) |
|
490 |
{
|
|
491 |
/* If count != 1, then we know that is_exact_count == true. */
|
|
492 |
((Item_sum_max*) item_sum)->clear(); /* Set to NULL. */ |
|
493 |
}
|
|
494 |
else
|
|
495 |
{
|
|
496 |
((Item_sum_max*) item_sum)->reset(); /* Set to the constant value. */ |
|
497 |
}
|
|
498 |
((Item_sum_max*) item_sum)->make_const(); |
|
499 |
recalc_const_item= 1; |
|
500 |
break; |
|
501 |
}
|
|
502 |
default: |
|
503 |
const_result= 0; |
|
504 |
break; |
|
1
by brian
clean slate |
505 |
}
|
506 |
}
|
|
507 |
else if (const_result) |
|
508 |
{
|
|
509 |
if (recalc_const_item) |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
510 |
{
|
1
by brian
clean slate |
511 |
item->update_used_tables(); |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
512 |
}
|
513 |
if (! item->const_item()) |
|
514 |
{
|
|
1
by brian
clean slate |
515 |
const_result= 0; |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
516 |
}
|
1
by brian
clean slate |
517 |
}
|
518 |
}
|
|
519 |
/*
|
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
520 |
If we have a where clause, we can only ignore searching in the
|
521 |
tables if MIN/MAX optimisation replaced all used tables
|
|
522 |
We do not use replaced values in case of:
|
|
523 |
SELECT MIN(key) FROM table_1, empty_table
|
|
524 |
removed_tables is != 0 if we have used MIN() or MAX().
|
|
525 |
*/
|
|
1
by brian
clean slate |
526 |
if (removed_tables && used_tables != removed_tables) |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
527 |
{
|
1
by brian
clean slate |
528 |
const_result= 0; // We didn't remove all tables |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
529 |
}
|
1
by brian
clean slate |
530 |
return const_result; |
531 |
}
|
|
532 |
||
533 |
||
1237.13.5
by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files. |
534 |
bool optimizer::simple_pred(Item_func *func_item, Item **args, bool &inv_order) |
1
by brian
clean slate |
535 |
{
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
536 |
Item *item= NULL; |
1237.13.5
by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files. |
537 |
inv_order= false; |
1240.3.1
by Brian Aker
Merge Padraig. |
538 |
switch (func_item->argument_count()) |
1237.13.5
by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files. |
539 |
{
|
1
by brian
clean slate |
540 |
case 0: |
541 |
/* MULT_EQUAL_FUNC */
|
|
542 |
{
|
|
543 |
Item_equal *item_equal= (Item_equal *) func_item; |
|
544 |
Item_equal_iterator it(*item_equal); |
|
545 |
args[0]= it++; |
|
546 |
if (it++) |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
547 |
{
|
548 |
return 0; |
|
549 |
}
|
|
550 |
if (! (args[1]= item_equal->get_const())) |
|
551 |
{
|
|
552 |
return 0; |
|
553 |
}
|
|
1
by brian
clean slate |
554 |
}
|
555 |
break; |
|
556 |
case 1: |
|
557 |
/* field IS NULL */
|
|
558 |
item= func_item->arguments()[0]; |
|
559 |
if (item->type() != Item::FIELD_ITEM) |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
560 |
{
|
1
by brian
clean slate |
561 |
return 0; |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
562 |
}
|
1
by brian
clean slate |
563 |
args[0]= item; |
564 |
break; |
|
565 |
case 2: |
|
566 |
/* 'field op const' or 'const op field' */
|
|
567 |
item= func_item->arguments()[0]; |
|
568 |
if (item->type() == Item::FIELD_ITEM) |
|
569 |
{
|
|
570 |
args[0]= item; |
|
571 |
item= func_item->arguments()[1]; |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
572 |
if (! item->const_item()) |
573 |
{
|
|
1
by brian
clean slate |
574 |
return 0; |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
575 |
}
|
1
by brian
clean slate |
576 |
args[1]= item; |
577 |
}
|
|
578 |
else if (item->const_item()) |
|
579 |
{
|
|
580 |
args[1]= item; |
|
581 |
item= func_item->arguments()[1]; |
|
582 |
if (item->type() != Item::FIELD_ITEM) |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
583 |
{
|
1
by brian
clean slate |
584 |
return 0; |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
585 |
}
|
1
by brian
clean slate |
586 |
args[0]= item; |
1237.13.5
by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files. |
587 |
inv_order= true; |
1
by brian
clean slate |
588 |
}
|
589 |
else
|
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
590 |
{
|
1
by brian
clean slate |
591 |
return 0; |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
592 |
}
|
1
by brian
clean slate |
593 |
break; |
594 |
case 3: |
|
595 |
/* field BETWEEN const AND const */
|
|
596 |
item= func_item->arguments()[0]; |
|
597 |
if (item->type() == Item::FIELD_ITEM) |
|
598 |
{
|
|
599 |
args[0]= item; |
|
600 |
for (int i= 1 ; i <= 2; i++) |
|
601 |
{
|
|
602 |
item= func_item->arguments()[i]; |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
603 |
if (! item->const_item()) |
604 |
{
|
|
1
by brian
clean slate |
605 |
return 0; |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
606 |
}
|
1
by brian
clean slate |
607 |
args[i]= item; |
608 |
}
|
|
609 |
}
|
|
610 |
else
|
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
611 |
{
|
1
by brian
clean slate |
612 |
return 0; |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
613 |
}
|
1
by brian
clean slate |
614 |
}
|
615 |
return 1; |
|
616 |
}
|
|
617 |
||
618 |
||
619 |
/**
|
|
620 |
Check whether a condition matches a key to get {MAX|MIN}(field):.
|
|
621 |
||
622 |
For the index specified by the keyinfo parameter, index that
|
|
623 |
contains field as its component (field_part), the function
|
|
624 |
checks whether the condition cond is a conjunction and all its
|
|
625 |
conjuncts referring to the columns of the same table as column
|
|
626 |
field are one of the following forms:
|
|
627 |
- f_i= const_i or const_i= f_i or f_i is null,
|
|
628 |
where f_i is part of the index
|
|
629 |
- field {<|<=|>=|>|=} const or const {<|<=|>=|>|=} field
|
|
630 |
- field between const1 and const2
|
|
631 |
||
632 |
@param[in] max_fl Set to 1 if we are optimising MAX()
|
|
633 |
@param[in,out] ref Reference to the structure we store the key
|
|
634 |
value
|
|
635 |
@param[in] keyinfo Reference to the key info
|
|
636 |
@param[in] field_part Pointer to the key part for the field
|
|
637 |
@param[in] cond WHERE condition
|
|
638 |
@param[in,out] key_part_used Map of matchings parts
|
|
639 |
@param[in,out] range_fl Says whether including key will be used
|
|
640 |
@param[out] prefix_len Length of common key part for the range
|
|
641 |
where MAX/MIN is searched for
|
|
642 |
||
643 |
@retval
|
|
644 |
0 Index can't be used.
|
|
645 |
@retval
|
|
646 |
1 We can use index to get MIN/MAX value
|
|
647 |
*/
|
|
1240.3.1
by Brian Aker
Merge Padraig. |
648 |
static bool matching_cond(bool max_fl, |
649 |
table_reference_st *ref, |
|
1535
by Brian Aker
Rename of KEY to KeyInfo |
650 |
KeyInfo *keyinfo, |
1534
by Brian Aker
Remove of KeyPartInfo |
651 |
KeyPartInfo *field_part, |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
652 |
COND *cond, |
1240.3.1
by Brian Aker
Merge Padraig. |
653 |
key_part_map *key_part_used, |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
654 |
uint32_t *range_fl, |
482
by Brian Aker
Remove uint. |
655 |
uint32_t *prefix_len) |
1
by brian
clean slate |
656 |
{
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
657 |
if (! cond) |
658 |
{
|
|
1
by brian
clean slate |
659 |
return 1; |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
660 |
}
|
1
by brian
clean slate |
661 |
Field *field= field_part->field; |
1089.1.3
by Brian Aker
Fix protobuf to release memory. Add in assert() for wrong column usage. Fix |
662 |
|
663 |
field->setWriteSet(); |
|
664 |
||
1660.1.3
by Brian Aker
Encapsulate Table in field |
665 |
if (! (cond->used_tables() & field->getTable()->map)) |
1
by brian
clean slate |
666 |
{
|
667 |
/* Condition doesn't restrict the used table */
|
|
668 |
return 1; |
|
669 |
}
|
|
670 |
if (cond->type() == Item::COND_ITEM) |
|
671 |
{
|
|
672 |
if (((Item_cond*) cond)->functype() == Item_func::COND_OR_FUNC) |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
673 |
{
|
1
by brian
clean slate |
674 |
return 0; |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
675 |
}
|
1
by brian
clean slate |
676 |
|
677 |
/* AND */
|
|
678 |
List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list()); |
|
679 |
Item *item; |
|
680 |
while ((item= li++)) |
|
681 |
{
|
|
1240.3.1
by Brian Aker
Merge Padraig. |
682 |
if (! matching_cond(max_fl, |
683 |
ref, |
|
684 |
keyinfo, |
|
685 |
field_part, |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
686 |
item, |
1240.3.1
by Brian Aker
Merge Padraig. |
687 |
key_part_used, |
688 |
range_fl, |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
689 |
prefix_len)) |
690 |
{
|
|
1
by brian
clean slate |
691 |
return 0; |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
692 |
}
|
1
by brian
clean slate |
693 |
}
|
694 |
return 1; |
|
695 |
}
|
|
696 |
||
697 |
if (cond->type() != Item::FUNC_ITEM) |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
698 |
{
|
699 |
return 0; // Not operator, can't optimize |
|
700 |
}
|
|
701 |
||
702 |
bool eq_type= false; // =, <=> or IS NULL |
|
703 |
bool noeq_type= false; // < or > |
|
704 |
bool less_fl= false; // < or <= |
|
705 |
bool is_null= false; |
|
706 |
bool between= false; |
|
707 |
||
1240.3.1
by Brian Aker
Merge Padraig. |
708 |
switch (((Item_func*) cond)->functype()) |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
709 |
{
|
1
by brian
clean slate |
710 |
case Item_func::ISNULL_FUNC: |
711 |
is_null= 1; /* fall through */ |
|
712 |
case Item_func::EQ_FUNC: |
|
713 |
case Item_func::EQUAL_FUNC: |
|
714 |
eq_type= 1; |
|
715 |
break; |
|
716 |
case Item_func::LT_FUNC: |
|
717 |
noeq_type= 1; /* fall through */ |
|
718 |
case Item_func::LE_FUNC: |
|
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
719 |
less_fl= 1; |
1
by brian
clean slate |
720 |
break; |
721 |
case Item_func::GT_FUNC: |
|
722 |
noeq_type= 1; /* fall through */ |
|
723 |
case Item_func::GE_FUNC: |
|
724 |
break; |
|
725 |
case Item_func::BETWEEN: |
|
726 |
between= 1; |
|
727 |
break; |
|
728 |
case Item_func::MULT_EQUAL_FUNC: |
|
729 |
eq_type= 1; |
|
730 |
break; |
|
731 |
default: |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
732 |
return 0; // Can't optimize function |
1
by brian
clean slate |
733 |
}
|
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
734 |
|
1
by brian
clean slate |
735 |
Item *args[3]; |
736 |
bool inv; |
|
737 |
||
738 |
/* Test if this is a comparison of a field and constant */
|
|
1237.13.5
by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files. |
739 |
if (! optimizer::simple_pred((Item_func*) cond, args, inv)) |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
740 |
{
|
1
by brian
clean slate |
741 |
return 0; |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
742 |
}
|
1
by brian
clean slate |
743 |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
744 |
if (inv && ! eq_type) |
745 |
{
|
|
746 |
less_fl= 1 - less_fl; // Convert '<' -> '>' (etc) |
|
747 |
}
|
|
1
by brian
clean slate |
748 |
|
749 |
/* Check if field is part of the tested partial key */
|
|
481
by Brian Aker
Remove all of uchar. |
750 |
unsigned char *key_ptr= ref->key_buff; |
1534
by Brian Aker
Remove of KeyPartInfo |
751 |
KeyPartInfo *part= NULL; |
1
by brian
clean slate |
752 |
for (part= keyinfo->key_part; ; key_ptr+= part++->store_length) |
753 |
||
754 |
{
|
|
755 |
if (part > field_part) |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
756 |
{
|
1
by brian
clean slate |
757 |
return 0; // Field is beyond the tested parts |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
758 |
}
|
1
by brian
clean slate |
759 |
if (part->field->eq(((Item_field*) args[0])->field)) |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
760 |
{
|
1
by brian
clean slate |
761 |
break; // Found a part of the key for the field |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
762 |
}
|
1
by brian
clean slate |
763 |
}
|
764 |
||
765 |
bool is_field_part= part == field_part; |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
766 |
if (! (is_field_part || eq_type)) |
767 |
{
|
|
1
by brian
clean slate |
768 |
return 0; |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
769 |
}
|
1
by brian
clean slate |
770 |
|
771 |
key_part_map org_key_part_used= *key_part_used; |
|
772 |
if (eq_type || between || max_fl == less_fl) |
|
773 |
{
|
|
482
by Brian Aker
Remove uint. |
774 |
uint32_t length= (key_ptr-ref->key_buff)+part->store_length; |
1
by brian
clean slate |
775 |
if (ref->key_length < length) |
776 |
{
|
|
777 |
/* Ultimately ref->key_length will contain the length of the search key */
|
|
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
778 |
ref->key_length= length; |
1
by brian
clean slate |
779 |
ref->key_parts= (part - keyinfo->key_part) + 1; |
780 |
}
|
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
781 |
if (! *prefix_len && part + 1 == field_part) |
782 |
{
|
|
1
by brian
clean slate |
783 |
*prefix_len= length; |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
784 |
}
|
1
by brian
clean slate |
785 |
if (is_field_part && eq_type) |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
786 |
{
|
1
by brian
clean slate |
787 |
*prefix_len= ref->key_length; |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
788 |
}
|
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
789 |
|
1
by brian
clean slate |
790 |
*key_part_used|= (key_part_map) 1 << (part - keyinfo->key_part); |
791 |
}
|
|
792 |
||
793 |
if (org_key_part_used != *key_part_used || |
|
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
794 |
(is_field_part && |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
795 |
(between || eq_type || max_fl == less_fl) && ! cond->val_int())) |
1
by brian
clean slate |
796 |
{
|
797 |
/*
|
|
798 |
It's the first predicate for this part or a predicate of the
|
|
799 |
following form that moves upper/lower bounds for max/min values:
|
|
800 |
- field BETWEEN const AND const
|
|
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
801 |
- field = const
|
1
by brian
clean slate |
802 |
- field {<|<=} const, when searching for MAX
|
803 |
- field {>|>=} const, when searching for MIN
|
|
804 |
*/
|
|
805 |
||
806 |
if (is_null) |
|
807 |
{
|
|
808 |
part->field->set_null(); |
|
481
by Brian Aker
Remove all of uchar. |
809 |
*key_ptr= (unsigned char) 1; |
1
by brian
clean slate |
810 |
}
|
811 |
else
|
|
812 |
{
|
|
813 |
store_val_in_field(part->field, args[between && max_fl ? 2 : 1], |
|
814 |
CHECK_FIELD_IGNORE); |
|
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
815 |
if (part->null_bit) |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
816 |
{
|
481
by Brian Aker
Remove all of uchar. |
817 |
*key_ptr++= (unsigned char) test(part->field->is_null()); |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
818 |
}
|
1055.2.5
by Jay Pipes
Removal of dead Field::image_type and st_key_part::image_type member variables. Legacy from geometry MyISAM types... |
819 |
part->field->get_key_image(key_ptr, part->length); |
1
by brian
clean slate |
820 |
}
|
821 |
if (is_field_part) |
|
822 |
{
|
|
823 |
if (between || eq_type) |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
824 |
{
|
1
by brian
clean slate |
825 |
*range_fl&= ~(NO_MAX_RANGE | NO_MIN_RANGE); |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
826 |
}
|
1
by brian
clean slate |
827 |
else
|
828 |
{
|
|
829 |
*range_fl&= ~(max_fl ? NO_MAX_RANGE : NO_MIN_RANGE); |
|
830 |
if (noeq_type) |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
831 |
{
|
1
by brian
clean slate |
832 |
*range_fl|= (max_fl ? NEAR_MAX : NEAR_MIN); |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
833 |
}
|
1
by brian
clean slate |
834 |
else
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
835 |
{
|
1
by brian
clean slate |
836 |
*range_fl&= ~(max_fl ? NEAR_MAX : NEAR_MIN); |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
837 |
}
|
1
by brian
clean slate |
838 |
}
|
839 |
}
|
|
840 |
}
|
|
841 |
else if (eq_type) |
|
842 |
{
|
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
843 |
if ((! is_null && !cond->val_int()) || |
1
by brian
clean slate |
844 |
(is_null && !test(part->field->is_null()))) |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
845 |
{
|
1
by brian
clean slate |
846 |
return 0; // Impossible test |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
847 |
}
|
1
by brian
clean slate |
848 |
}
|
849 |
else if (is_field_part) |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
850 |
{
|
1
by brian
clean slate |
851 |
*range_fl&= ~(max_fl ? NO_MIN_RANGE : NO_MAX_RANGE); |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
852 |
}
|
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
853 |
return 1; |
1
by brian
clean slate |
854 |
}
|
855 |
||
856 |
||
857 |
/**
|
|
858 |
Check whether we can get value for {max|min}(field) by using a key.
|
|
859 |
||
860 |
If where-condition is not a conjunction of 0 or more conjuct the
|
|
861 |
function returns false, otherwise it checks whether there is an
|
|
862 |
index including field as its k-th component/part such that:
|
|
863 |
||
864 |
-# for each previous component f_i there is one and only one conjunct
|
|
865 |
of the form: f_i= const_i or const_i= f_i or f_i is null
|
|
866 |
-# references to field occur only in conjucts of the form:
|
|
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
867 |
field {<|<=|>=|>|=} const or const {<|<=|>=|>|=} field or
|
1
by brian
clean slate |
868 |
field BETWEEN const1 AND const2
|
869 |
-# all references to the columns from the same table as column field
|
|
870 |
occur only in conjucts mentioned above.
|
|
871 |
-# each of k first components the index is not partial, i.e. is not
|
|
872 |
defined on a fixed length proper prefix of the field.
|
|
873 |
||
874 |
If such an index exists the function through the ref parameter
|
|
875 |
returns the key value to find max/min for the field using the index,
|
|
876 |
the length of first (k-1) components of the key and flags saying
|
|
877 |
how to apply the key for the search max/min value.
|
|
878 |
(if we have a condition field = const, prefix_len contains the length
|
|
879 |
of the whole search key)
|
|
880 |
||
881 |
@param[in] max_fl 0 for MIN(field) / 1 for MAX(field)
|
|
882 |
@param[in,out] ref Reference to the structure we store the key value
|
|
883 |
@param[in] field Field used inside MIN() / MAX()
|
|
884 |
@param[in] cond WHERE condition
|
|
885 |
@param[out] range_fl Bit flags for how to search if key is ok
|
|
886 |
@param[out] prefix_len Length of prefix for the search range
|
|
887 |
||
888 |
@note
|
|
889 |
This function may set table->key_read to 1, which must be reset after
|
|
890 |
index is used! (This can only happen when function returns 1)
|
|
891 |
||
892 |
@retval
|
|
893 |
0 Index can not be used to optimize MIN(field)/MAX(field)
|
|
894 |
@retval
|
|
895 |
1 Can use key to optimize MIN()/MAX().
|
|
896 |
In this case ref, range_fl and prefix_len are updated
|
|
897 |
*/
|
|
1240.3.1
by Brian Aker
Merge Padraig. |
898 |
static bool find_key_for_maxmin(bool max_fl, |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
899 |
table_reference_st *ref, |
1240.3.1
by Brian Aker
Merge Padraig. |
900 |
Field* field, |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
901 |
COND *cond, |
1240.3.1
by Brian Aker
Merge Padraig. |
902 |
uint32_t *range_fl, |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
903 |
uint32_t *prefix_len) |
1
by brian
clean slate |
904 |
{
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
905 |
if (! (field->flags & PART_KEY_FLAG)) |
906 |
{
|
|
907 |
return 0; // Not key field |
|
908 |
}
|
|
1
by brian
clean slate |
909 |
|
1660.1.3
by Brian Aker
Encapsulate Table in field |
910 |
Table *table= field->getTable(); |
482
by Brian Aker
Remove uint. |
911 |
uint32_t idx= 0; |
1
by brian
clean slate |
912 |
|
1535
by Brian Aker
Rename of KEY to KeyInfo |
913 |
KeyInfo *keyinfo,*keyinfo_end= NULL; |
1578.2.10
by Brian Aker
keys and fields partial encapsulation. |
914 |
for (keyinfo= table->key_info, keyinfo_end= keyinfo+table->getShare()->sizeKeys(); |
1
by brian
clean slate |
915 |
keyinfo != keyinfo_end; |
916 |
keyinfo++,idx++) |
|
917 |
{
|
|
1534
by Brian Aker
Remove of KeyPartInfo |
918 |
KeyPartInfo *part= NULL; |
919 |
KeyPartInfo *part_end= NULL; |
|
1
by brian
clean slate |
920 |
key_part_map key_part_to_use= 0; |
921 |
/*
|
|
327.1.5
by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h |
922 |
Perform a check if index is not disabled by ALTER Table
|
1
by brian
clean slate |
923 |
or IGNORE INDEX.
|
924 |
*/
|
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
925 |
if (! table->keys_in_use_for_query.test(idx)) |
926 |
{
|
|
1
by brian
clean slate |
927 |
continue; |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
928 |
}
|
482
by Brian Aker
Remove uint. |
929 |
uint32_t jdx= 0; |
1
by brian
clean slate |
930 |
*prefix_len= 0; |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
931 |
for (part= keyinfo->key_part, part_end= part+keyinfo->key_parts; |
932 |
part != part_end; |
|
1
by brian
clean slate |
933 |
part++, jdx++, key_part_to_use= (key_part_to_use << 1) | 1) |
934 |
{
|
|
1235.1.14
by Brian Aker
Final move of index flags up to Engine (new interface still needed). |
935 |
if (! (table->index_flags(idx) & HA_READ_ORDER)) |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
936 |
{
|
1
by brian
clean slate |
937 |
return 0; |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
938 |
}
|
1
by brian
clean slate |
939 |
|
940 |
/* Check whether the index component is partial */
|
|
1578.2.16
by Brian Aker
Merge in change to getTable() to private the field objects. |
941 |
Field *part_field= table->getField(part->fieldnr-1); |
1089.1.3
by Brian Aker
Fix protobuf to release memory. Add in assert() for wrong column usage. Fix |
942 |
part_field->setWriteSet(); |
943 |
||
1
by brian
clean slate |
944 |
if ((part_field->flags & BLOB_FLAG) || |
945 |
part->length < part_field->key_length()) |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
946 |
{
|
1
by brian
clean slate |
947 |
break; |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
948 |
}
|
1
by brian
clean slate |
949 |
|
950 |
if (field->eq(part->field)) |
|
951 |
{
|
|
952 |
ref->key= idx; |
|
953 |
ref->key_length= 0; |
|
954 |
ref->key_parts= 0; |
|
955 |
key_part_map key_part_used= 0; |
|
956 |
*range_fl= NO_MIN_RANGE | NO_MAX_RANGE; |
|
1240.3.1
by Brian Aker
Merge Padraig. |
957 |
if (matching_cond(max_fl, |
958 |
ref, |
|
959 |
keyinfo, |
|
960 |
part, |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
961 |
cond, |
1240.3.1
by Brian Aker
Merge Padraig. |
962 |
&key_part_used, |
963 |
range_fl, |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
964 |
prefix_len) && |
965 |
! (key_part_to_use & ~key_part_used)) |
|
1
by brian
clean slate |
966 |
{
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
967 |
if (! max_fl && key_part_used == key_part_to_use && part->null_bit) |
1
by brian
clean slate |
968 |
{
|
969 |
/*
|
|
970 |
The query is on this form:
|
|
971 |
||
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
972 |
SELECT MIN(key_part_k)
|
973 |
FROM t1
|
|
1
by brian
clean slate |
974 |
WHERE key_part_1 = const and ... and key_part_k-1 = const
|
975 |
||
976 |
If key_part_k is nullable, we want to find the first matching row
|
|
977 |
where key_part_k is not null. The key buffer is now {const, ...,
|
|
978 |
NULL}. This will be passed to the handler along with a flag
|
|
979 |
indicating open interval. If a tuple is read that does not match
|
|
980 |
these search criteria, an attempt will be made to read an exact
|
|
981 |
match for the key buffer.
|
|
982 |
*/
|
|
983 |
/* Set the first byte of key_part_k to 1, that means NULL */
|
|
984 |
ref->key_buff[ref->key_length]= 1; |
|
985 |
ref->key_length+= part->store_length; |
|
986 |
ref->key_parts++; |
|
51.1.35
by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE |
987 |
assert(ref->key_parts == jdx+1); |
1
by brian
clean slate |
988 |
*range_fl&= ~NO_MIN_RANGE; |
989 |
*range_fl|= NEAR_MIN; // Open interval |
|
990 |
}
|
|
991 |
/*
|
|
992 |
The following test is false when the key in the key tree is
|
|
993 |
converted (for example to upper case)
|
|
994 |
*/
|
|
1005.2.6
by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<> |
995 |
if (field->part_of_key.test(idx)) |
1
by brian
clean slate |
996 |
{
|
997 |
table->key_read= 1; |
|
1208.3.2
by brian
Update for Cursor renaming. |
998 |
table->cursor->extra(HA_EXTRA_KEYREAD); |
1
by brian
clean slate |
999 |
}
|
1000 |
return 1; |
|
1001 |
}
|
|
1002 |
}
|
|
1003 |
}
|
|
1004 |
}
|
|
1005 |
return 0; |
|
1006 |
}
|
|
1007 |
||
1008 |
||
1009 |
/**
|
|
1010 |
Check whether found key is in range specified by conditions.
|
|
1011 |
||
1012 |
@param[in] max_fl 0 for MIN(field) / 1 for MAX(field)
|
|
1013 |
@param[in] ref Reference to the key value and info
|
|
1014 |
@param[in] field Field used the MIN/MAX expression
|
|
1015 |
@param[in] cond WHERE condition
|
|
1016 |
@param[in] range_fl Says whether there is a condition to to be checked
|
|
1017 |
@param[in] prefix_len Length of the constant part of the key
|
|
1018 |
||
1019 |
@retval
|
|
1020 |
0 ok
|
|
1021 |
@retval
|
|
1022 |
1 WHERE was not true for the found row
|
|
1023 |
*/
|
|
1240.3.1
by Brian Aker
Merge Padraig. |
1024 |
static int reckey_in_range(bool max_fl, |
1025 |
table_reference_st *ref, |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
1026 |
Field* field, |
1240.3.1
by Brian Aker
Merge Padraig. |
1027 |
COND *cond, |
1028 |
uint32_t range_fl, |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
1029 |
uint32_t prefix_len) |
1
by brian
clean slate |
1030 |
{
|
1660.1.3
by Brian Aker
Encapsulate Table in field |
1031 |
if (key_cmp_if_same(field->getTable(), ref->key_buff, ref->key, prefix_len)) |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
1032 |
{
|
1
by brian
clean slate |
1033 |
return 1; |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
1034 |
}
|
1035 |
if (! cond || (range_fl & (max_fl ? NO_MIN_RANGE : NO_MAX_RANGE))) |
|
1036 |
{
|
|
1
by brian
clean slate |
1037 |
return 0; |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
1038 |
}
|
1
by brian
clean slate |
1039 |
return maxmin_in_range(max_fl, field, cond); |
1040 |
}
|
|
1041 |
||
1042 |
||
1043 |
/**
|
|
1044 |
Check whether {MAX|MIN}(field) is in range specified by conditions.
|
|
1045 |
||
1046 |
@param[in] max_fl 0 for MIN(field) / 1 for MAX(field)
|
|
1047 |
@param[in] field Field used the MIN/MAX expression
|
|
1048 |
@param[in] cond WHERE condition
|
|
1049 |
||
1050 |
@retval
|
|
1051 |
0 ok
|
|
1052 |
@retval
|
|
1053 |
1 WHERE was not true for the found row
|
|
1054 |
*/
|
|
1055 |
static int maxmin_in_range(bool max_fl, Field* field, COND *cond) |
|
1056 |
{
|
|
1057 |
/* If AND/OR condition */
|
|
1058 |
if (cond->type() == Item::COND_ITEM) |
|
1059 |
{
|
|
1060 |
List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list()); |
|
1061 |
Item *item; |
|
1062 |
while ((item= li++)) |
|
1063 |
{
|
|
1064 |
if (maxmin_in_range(max_fl, field, item)) |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
1065 |
{
|
1
by brian
clean slate |
1066 |
return 1; |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
1067 |
}
|
1
by brian
clean slate |
1068 |
}
|
1069 |
return 0; |
|
1070 |
}
|
|
1071 |
||
1660.1.3
by Brian Aker
Encapsulate Table in field |
1072 |
if (cond->used_tables() != field->getTable()->map) |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
1073 |
{
|
1
by brian
clean slate |
1074 |
return 0; |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
1075 |
}
|
1076 |
bool less_fl= false; |
|
1240.3.1
by Brian Aker
Merge Padraig. |
1077 |
switch (((Item_func*) cond)->functype()) |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
1078 |
{
|
1
by brian
clean slate |
1079 |
case Item_func::BETWEEN: |
1080 |
return cond->val_int() == 0; // Return 1 if WHERE is false |
|
1081 |
case Item_func::LT_FUNC: |
|
1082 |
case Item_func::LE_FUNC: |
|
1083 |
less_fl= 1; |
|
1084 |
case Item_func::GT_FUNC: |
|
1085 |
case Item_func::GE_FUNC: |
|
1086 |
{
|
|
1087 |
Item *item= ((Item_func*) cond)->arguments()[1]; |
|
1088 |
/* In case of 'const op item' we have to swap the operator */
|
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
1089 |
if (! item->const_item()) |
1090 |
{
|
|
1
by brian
clean slate |
1091 |
less_fl= 1-less_fl; |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
1092 |
}
|
1
by brian
clean slate |
1093 |
/*
|
1094 |
We only have to check the expression if we are using an expression like
|
|
1095 |
SELECT MAX(b) FROM t1 WHERE a=const AND b>const
|
|
1096 |
not for
|
|
1097 |
SELECT MAX(b) FROM t1 WHERE a=const AND b<const
|
|
1098 |
*/
|
|
1099 |
if (max_fl != less_fl) |
|
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
1100 |
{
|
1
by brian
clean slate |
1101 |
return cond->val_int() == 0; // Return 1 if WHERE is false |
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
1102 |
}
|
1
by brian
clean slate |
1103 |
return 0; |
1104 |
}
|
|
1105 |
case Item_func::EQ_FUNC: |
|
1106 |
case Item_func::EQUAL_FUNC: |
|
1107 |
break; |
|
1108 |
default: // Keep compiler happy |
|
51.1.35
by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE |
1109 |
assert(1); // Impossible |
1
by brian
clean slate |
1110 |
break; |
1111 |
}
|
|
1112 |
return 0; |
|
1113 |
}
|
|
1114 |
||
1237.9.1
by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file |
1115 |
} /* namespace drizzled */ |
1116 |