26
26
This file contains:
29
A module that accepts a condition, index (or partitioning) description,
30
and builds lists of intervals (in index/partitioning space), such that
31
all possible records that match the condition are contained within the
29
A module that accepts a condition, index (or partitioning) description,
30
and builds lists of intervals (in index/partitioning space), such that
31
all possible records that match the condition are contained within the
33
33
The entry point for the range analysis module is get_mm_tree() function.
35
35
The lists are returned in form of complicated structure of interlinked
36
36
SEL_TREE/SEL_IMERGE/SEL_ARG objects.
37
See quick_range_seq_next, find_used_partitions for examples of how to walk
37
See quick_range_seq_next, find_used_partitions for examples of how to walk
39
39
All direct "users" of this module are located within this file, too.
65
65
The code in this file (and elsewhere) makes operations on key value tuples.
66
66
Those tuples are stored in the following format:
68
68
The tuple is a sequence of key part values. The length of key part value
69
69
depends only on its type (and not depends on the what value is stored)
71
71
KeyTuple: keypart1-data, keypart2-data, ...
73
73
The value of each keypart is stored in the following format:
75
75
keypart_data: [isnull_byte] keypart-value-bytes
77
77
If a keypart may have a NULL value (key_part->field->real_maybe_null() can
78
be used to check this), then the first byte is a NULL indicator with the
78
be used to check this), then the first byte is a NULL indicator with the
79
79
following valid values:
80
80
1 - keypart has NULL value.
81
81
0 - keypart has non-NULL value.
99
99
See key_copy() and key_restore() for code to move data between index tuple
102
CAUTION: the above description is only sergefp's understanding of the
102
CAUTION: the above description is only sergefp's understanding of the
103
103
subject and may omit some details.
106
106
#include <drizzled/server_includes.h>
107
107
#include <drizzled/sql_select.h>
110
#define test_rb_tree(A,B) {}
111
#define test_use_count(A) {}
108
#include <drizzled/error.h>
109
#include <drizzled/cost_vect.h>
110
#include <drizzled/item/cmpfunc.h>
111
#include <drizzled/field/num.h>
112
#include <drizzled/check_stack_overrun.h>
114
#include "drizzled/temporal.h" /* Needed in get_mm_leaf() for timestamp -> datetime comparisons */
115
121
Convert double value to #rows. Currently this does floor(), and we
116
122
might consider using round() instead.
118
#define double2rows(x) ((ha_rows)(x))
124
static inline ha_rows double2rows(double x)
126
return static_cast<ha_rows>(x);
120
129
static int sel_cmp(Field *f,unsigned char *a,unsigned char *b,uint8_t a_flag,uint8_t b_flag);
161
170
+-------+ $ $ +--------+
163
172
... $ $ +--------+
165
174
The entire graph is partitioned into "interval lists".
167
176
An interval list is a sequence of ordered disjoint intervals over the same
168
177
key part. SEL_ARG are linked via "next" and "prev" pointers. Additionally,
169
all intervals in the list form an RB-tree, linked via left/right/parent
178
all intervals in the list form an RB-tree, linked via left/right/parent
170
179
pointers. The RB-tree root SEL_ARG object will be further called "root of the
173
In the example pic, there are 4 interval lists:
182
In the example pic, there are 4 interval lists:
174
183
"kp<1 OR kp1=2 OR kp1=3", "kp2=5", "kp3=10 OR kp3=12", "kp3=11 OR kp3=13".
175
184
The vertical lines represent SEL_ARG::next/prev pointers.
177
186
In an interval list, each member X may have SEL_ARG::next_key_part pointer
178
187
pointing to the root of another interval list Y. The pointed interval list
179
188
must cover a key part with greater number (i.e. Y->part > X->part).
181
190
In the example pic, the next_key_part pointers are represented by
182
191
horisontal lines.
208
217
and create QUICK_RANGE_SELECT object that will
209
218
read records within these intervals.
211
4. SPACE COMPLEXITY NOTES
220
4. SPACE COMPLEXITY NOTES
213
222
SEL_ARG graph is a representation of an ordered disjoint sequence of
214
223
intervals over the ordered set of index tuple values.
216
225
For multi-part keys, one can construct a WHERE expression such that its
217
226
list of intervals will be of combinatorial size. Here is an example:
219
(keypart1 IN (1,2, ..., n1)) AND
220
(keypart2 IN (1,2, ..., n2)) AND
228
(keypart1 IN (1,2, ..., n1)) AND
229
(keypart2 IN (1,2, ..., n2)) AND
221
230
(keypart3 IN (1,2, ..., n3))
223
232
For this WHERE clause the list of intervals will have n1*n2*n3 intervals
226
235
(keypart1, keypart2, keypart3) = (k1, k2, k3), where 1 <= k{i} <= n{i}
228
237
SEL_ARG graph structure aims to reduce the amount of required space by
229
238
"sharing" the elementary intervals when possible (the pic at the
230
beginning of this comment has examples of such sharing). The sharing may
239
beginning of this comment has examples of such sharing). The sharing may
231
240
prevent combinatorial blowup:
233
242
There are WHERE clauses that have combinatorial-size interval lists but
234
243
will be represented by a compact SEL_ARG graph.
236
(keypartN IN (1,2, ..., n1)) AND
245
(keypartN IN (1,2, ..., n1)) AND
238
(keypart2 IN (1,2, ..., n2)) AND
247
(keypart2 IN (1,2, ..., n2)) AND
239
248
(keypart1 IN (1,2, ..., n3))
241
250
but not in all cases:
255
264
By induction: Let's take any interval on some keypart in the middle:
259
268
Then let's AND it with this interval 'structure' from preceding and
260
269
following keyparts:
262
271
(kp14=c1 AND kp16=c3) OR keypart14=c2) (*)
264
273
We will obtain this SEL_ARG graph:
266
275
kp14 $ kp15 $ kp16
268
277
+---------+ $ +---------+ $ +---------+
269
278
| kp14=c1 |--$-->| kp15=c0 |--$-->| kp16=c3 |
270
279
+---------+ $ +---------+ $ +---------+
272
+---------+ $ +---------+ $
273
| kp14=c2 |--$-->| kp15=c0 | $
274
+---------+ $ +---------+ $
281
+---------+ $ +---------+ $
282
| kp14=c2 |--$-->| kp15=c0 | $
283
+---------+ $ +---------+ $
277
286
Note that we had to duplicate "kp15=c0" and there was no way to avoid
279
288
The induction step: AND the obtained expression with another "wrapping"
280
289
expression like (*).
281
When the process ends because of the limit on max. number of keyparts
290
When the process ends because of the limit on max. number of keyparts
284
293
WHERE clause length is O(3*#max_keyparts)
1071
bool SQL_SELECT::check_quick(Session *session, bool force_quick_range,
1076
return test_quick_select(session, tmp, 0, limit,
1077
force_quick_range, false) < 0;
1081
bool SQL_SELECT::skip_record()
1083
return cond ? cond->val_int() == 0 : 0;
1061
1087
QUICK_SELECT_I::QUICK_SELECT_I()
1062
1088
:max_used_key_length(0),
1063
1089
used_key_parts(0)
1066
QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, Table *table, uint32_t key_nr,
1092
QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(Session *session, Table *table, uint32_t key_nr,
1067
1093
bool no_alloc, MEM_ROOT *parent_alloc,
1068
1094
bool *create_error)
1069
1095
:free_file(0),cur_range(NULL),last_range(0),dont_free(0)
1077
1103
key_part_info= head->key_info[index].key_part;
1078
1104
my_init_dynamic_array(&ranges, sizeof(QUICK_RANGE*), 16, 16);
1080
/* 'thd' is not accessible in QUICK_RANGE_SELECT::reset(). */
1081
mrr_buf_size= thd->variables.read_rnd_buff_size;
1106
/* 'session' is not accessible in QUICK_RANGE_SELECT::reset(). */
1107
mrr_buf_size= session->variables.read_rnd_buff_size;
1082
1108
mrr_buf_desc= NULL;
1084
1110
if (!no_alloc && !parent_alloc)
1086
1112
// Allocates everything through the internal memroot
1087
init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
1088
thd->mem_root= &alloc;
1113
init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
1114
session->mem_root= &alloc;
1091
1117
memset(&alloc, 0, sizeof(alloc));
1206
QUICK_ROR_INTERSECT_SELECT::QUICK_ROR_INTERSECT_SELECT(THD *thd_param,
1231
QUICK_ROR_INTERSECT_SELECT::QUICK_ROR_INTERSECT_SELECT(Session *session_param,
1208
1233
bool retrieve_full_rows,
1209
1234
MEM_ROOT *parent_alloc)
1210
: cpk_quick(NULL), thd(thd_param), need_to_fetch_row(retrieve_full_rows),
1235
: cpk_quick(NULL), session(session_param), need_to_fetch_row(retrieve_full_rows),
1211
1236
scans_inited(false)
1213
1238
index= MAX_KEY;
1215
1240
record= head->record[0];
1216
1241
if (!parent_alloc)
1217
init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
1242
init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
1219
1244
memset(&alloc, 0, sizeof(MEM_ROOT));
1220
1245
last_rowid= (unsigned char*) alloc_root(parent_alloc? parent_alloc : &alloc,
1283
1308
/* already have own 'handler' object. */
1288
if (!(file= head->file->clone(thd->mem_root)))
1312
session= head->in_use;
1313
if (!(file= head->file->clone(session->mem_root)))
1291
1316
Manually set the error flag. Note: there seems to be quite a few
1292
1317
places where a failure could cause the server to "hang" the client by
1293
sending no response to a query. ATM those are not real errors because
1294
the storage engine calls in question happen to never fail with the
1295
existing storage engines.
1318
sending no response to a query. ATM those are not real errors because
1319
the storage engine calls in question happen to never fail with the
1320
existing storage engines.
1297
1322
my_error(ER_OUT_OF_RESOURCES, MYF(0)); /* purecov: inspected */
1298
1323
/* Caller will free the memory */
1445
QUICK_ROR_UNION_SELECT::QUICK_ROR_UNION_SELECT(THD *thd_param,
1476
QUICK_ROR_UNION_SELECT::QUICK_ROR_UNION_SELECT(Session *session_param,
1447
: thd(thd_param), scans_inited(false)
1478
: session(session_param), scans_inited(false)
1449
1480
index= MAX_KEY;
1451
1482
rowid_length= table->file->ref_length;
1452
1483
record= head->record[0];
1453
init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
1454
thd_param->mem_root= &alloc;
1484
init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
1485
session_param->mem_root= &alloc;
1489
* Function object that is used as the comparison function
1490
* for the priority queue in the QUICK_ROR_UNION_SELECT
1493
class compare_functor
1495
QUICK_ROR_UNION_SELECT *self;
1497
compare_functor(QUICK_ROR_UNION_SELECT *in_arg)
1499
inline bool operator()(const QUICK_SELECT_I *i, const QUICK_SELECT_I *j) const
1501
int val= self->head->file->cmp_ref(i->last_rowid,
1459
1508
Do post-constructor initialization.
1882
1928
/* Table read plans are allocated on MEM_ROOT and are never deleted */
1883
1929
static void *operator new(size_t size, MEM_ROOT *mem_root)
1884
{ return (void*) alloc_root(mem_root, (uint) size); }
1885
static void operator delete(void *ptr __attribute__((unused)),
1886
size_t size __attribute__((unused)))
1930
{ return (void*) alloc_root(mem_root, (uint32_t) size); }
1931
static void operator delete(void *, size_t)
1887
1932
{ TRASH(ptr, size); }
1888
static void operator delete(void *ptr __attribute__((unused)),
1889
MEM_ROOT *mem_root __attribute__((unused)))
1933
static void operator delete(void *, MEM_ROOT *)
1890
1934
{ /* Never called */ }
1891
1935
virtual ~TABLE_READ_PLAN() {} /* Remove gcc warning */
2107
2149
quick_condition_rows value is obtained as follows:
2109
2151
It is a minimum of E(#output rows) for all considered table access
2110
2152
methods (range and index_merge accesses over various indexes).
2112
2154
The obtained value is not a true E(#rows that satisfy table condition)
2113
2155
but rather a pessimistic estimate. To obtain a true E(#...) one would
2114
2156
need to combine estimates of various access methods, taking into account
2115
2157
correlations between sets of rows they will return.
2117
2159
For example, if values of tbl.key1 and tbl.key2 are independent (a right
2118
2160
assumption if we have no information about their correlation) then the
2119
2161
correct estimate will be:
2121
E(#rows("tbl.key1 < c1 AND tbl.key2 < c2")) =
2163
E(#rows("tbl.key1 < c1 AND tbl.key2 < c2")) =
2122
2164
= E(#rows(tbl.key1 < c1)) / total_rows(tbl) * E(#rows(tbl.key2 < c2)
2124
which is smaller than
2166
which is smaller than
2126
2168
MIN(E(#rows(tbl.key1 < c1), E(#rows(tbl.key2 < c2)))
2128
2170
which is currently produced.
2131
2173
* Change the value returned in quick_condition_rows from a pessimistic
2132
estimate to true E(#rows that satisfy table condition).
2133
(we can re-use some of E(#rows) calcuation code from index_merge/intersection
2174
estimate to true E(#rows that satisfy table condition).
2175
(we can re-use some of E(#rows) calcuation code from index_merge/intersection
2136
2178
* Check if this function really needs to modify keys_to_use, and change the
2137
2179
code to pass it by reference if it doesn't.
2192
2234
param.table=head;
2194
2236
param.mem_root= &alloc;
2195
param.old_root= thd->mem_root;
2237
param.old_root= session->mem_root;
2196
2238
param.needed_reg= &needed_reg;
2197
2239
param.imerge_cost_buff_size= 0;
2198
2240
param.using_real_indexes= true;
2199
2241
param.remove_jump_scans= true;
2200
2242
param.force_default_mrr= ordered_output;
2202
thd->no_errors=1; // Don't warn about NULL
2203
init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
2244
session->no_errors=1; // Don't warn about NULL
2245
init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
2204
2246
if (!(param.key_parts= (KEY_PART*) alloc_root(&alloc,
2205
2247
sizeof(KEY_PART)*
2206
2248
head->s->key_parts)) ||
2207
2249
fill_used_fields_bitmap(¶m))
2251
session->no_errors=0;
2210
2252
free_root(&alloc,MYF(0)); // Return memory & allocator
2211
return(0); // Can't use range
2253
return 0; // Can't use range
2213
2255
key_parts= param.key_parts;
2214
thd->mem_root= &alloc;
2256
session->mem_root= &alloc;
2217
2259
Make an array with description of all key parts of all table keys.
2558
2600
unique_calc_buff_size=
2559
2601
Unique::get_cost_calc_buff_size((ulong)non_cpk_scan_records,
2560
2602
param->table->file->ref_length,
2561
param->thd->variables.sortbuff_size);
2603
param->session->variables.sortbuff_size);
2562
2604
if (param->imerge_cost_buff_size < unique_calc_buff_size)
2564
2606
if (!(param->imerge_cost_buff= (uint*)alloc_root(param->mem_root,
2565
2607
unique_calc_buff_size)))
2567
2609
param->imerge_cost_buff_size= unique_calc_buff_size;
2571
Unique::get_use_cost(param->imerge_cost_buff, (uint)non_cpk_scan_records,
2613
Unique::get_use_cost(param->imerge_cost_buff, (uint32_t)non_cpk_scan_records,
2572
2614
param->table->file->ref_length,
2573
param->thd->variables.sortbuff_size);
2615
param->session->variables.sortbuff_size);
2574
2616
if (imerge_cost < read_time)
2576
2618
if ((imerge_trp= new (param->mem_root)TRP_INDEX_MERGE))
3841
3879
#define NOT_IN_IGNORE_THRESHOLD 1000
3842
3880
MEM_ROOT *tmp_root= param->mem_root;
3843
param->thd->mem_root= param->old_root;
3881
param->session->mem_root= param->old_root;
3845
3883
Create one Item_type constant object. We'll need it as
3846
3884
get_mm_parts only accepts constant values wrapped in Item_Type
3848
3886
We create the Item on param->mem_root which points to
3849
per-statement mem_root (while thd->mem_root is currently pointing
3887
per-statement mem_root (while session->mem_root is currently pointing
3850
3888
to mem_root local to range optimizer).
3852
3890
Item *value_item= func->array->create_item();
3853
param->thd->mem_root= tmp_root;
3891
param->session->mem_root= tmp_root;
3855
3893
if (func->array->count > NOT_IN_IGNORE_THRESHOLD || !value_item)
3858
3896
/* Get a SEL_TREE for "(-inf|NULL) < X < c_0" interval. */
3862
3900
func->array->value_to_item(i, value_item);
3863
3901
tree= get_mm_parts(param, cond_func, field, Item_func::LT_FUNC,
4010
4048
Yet a predicate of the form (c BETWEEN f1i AND f2i) is processed
4011
4049
differently. It is considered as a conjuction of two SARGable
4012
4050
predicates (f1i <= c) and (f2i <=c) and the function get_full_func_mm_tree
4013
is called for each of them separately producing trees for
4014
AND j (f1j <=c ) and AND j (f2j <= c)
4051
is called for each of them separately producing trees for
4052
AND j (f1j <=c ) and AND j (f2j <= c)
4015
4053
After this these two trees are united in one conjunctive tree.
4016
4054
It's easy to see that the same tree is obtained for
4017
4055
AND j,k (f1j <=c AND f2k<=c)
4018
which is equivalent to
4056
which is equivalent to
4019
4057
AND j,k (c BETWEEN f1j AND f2k).
4020
4058
The validity of the processing of the predicate (c NOT BETWEEN f1i AND f2i)
4021
4059
which equivalent to (f1i > c OR f2i < c) is not so obvious. Here the
4022
4060
function get_full_func_mm_tree is called for (f1i > c) and (f2i < c)
4023
4061
producing trees for AND j (f1j > c) and AND j (f2j < c). Then this two
4024
trees are united in one OR-tree. The expression
4062
trees are united in one OR-tree. The expression
4025
4063
(AND j (f1j > c) OR AND j (f2j < c)
4026
4064
is equivalent to the expression
4027
AND j,k (f1j > c OR f2k < c)
4028
which is just a translation of
4065
AND j,k (f1j > c OR f2k < c)
4066
which is just a translation of
4029
4067
AND j,k (c NOT BETWEEN f1j AND f2k)
4031
4069
In the cases when one of the items f1, f2 is a constant c1 we do not create
4038
4076
As to IN predicates only ones of the form (f IN (c1,...,cn)),
4039
4077
where f1 is a field and c1,...,cn are constant, are considered as
4040
4078
SARGable. We never try to narrow the index scan using predicates of
4041
the form (c IN (c1,...,f,...,cn)).
4079
the form (c IN (c1,...,f,...,cn)).
4044
4082
Pointer to the tree representing the built conjunction of SEL_TREEs
4047
4085
static SEL_TREE *get_full_func_mm_tree(RANGE_OPT_PARAM *param,
4048
4086
Item_func *cond_func,
4049
Item_field *field_item, Item *value,
4087
Item_field *field_item, Item *value,
4052
4090
SEL_TREE *tree= 0;
4137
4175
if (cond->const_item())
4140
During the cond->val_int() evaluation we can come across a subselect
4141
item which may allocate memory on the thd->mem_root and assumes
4142
all the memory allocated has the same life span as the subselect
4178
During the cond->val_int() evaluation we can come across a subselect
4179
item which may allocate memory on the session->mem_root and assumes
4180
all the memory allocated has the same life span as the subselect
4143
4181
item itself. So we have to restore the thread's mem_root here.
4145
4183
MEM_ROOT *tmp_root= param->mem_root;
4146
param->thd->mem_root= param->old_root;
4184
param->session->mem_root= param->old_root;
4147
4185
tree= cond->val_int() ? new(tmp_root) SEL_TREE(SEL_TREE::ALWAYS) :
4148
4186
new(tmp_root) SEL_TREE(SEL_TREE::IMPOSSIBLE);
4149
param->thd->mem_root= tmp_root;
4187
param->session->mem_root= tmp_root;
4259
4297
static SEL_TREE *
4260
4298
get_mm_parts(RANGE_OPT_PARAM *param, COND *cond_func, Field *field,
4261
4299
Item_func::Functype type,
4263
Item_result cmp_type __attribute__((unused)))
4300
Item *value, Item_result)
4265
4302
if (field->table != param->table)
4268
4305
KEY_PART *key_part = param->key_parts;
4269
4306
KEY_PART *end = param->key_parts_end;
4270
4307
SEL_TREE *tree=0;
4272
4309
value->used_tables() & ~(param->prev_tables | param->read_tables))
4274
4311
for (; key_part != end ; key_part++)
4276
4313
if (field->eq(key_part->field))
4278
4315
SEL_ARG *sel_arg=0;
4279
4316
if (!tree && !(tree=new SEL_TREE()))
4281
4318
if (!value || !(value->used_tables() & ~param->read_tables))
4283
4320
sel_arg=get_mm_leaf(param,cond_func,
4465
4501
value->result_type() != STRING_RESULT &&
4466
4502
field->cmp_type() != value->result_type())
4468
/* For comparison purposes allow invalid dates like 2000-01-32 */
4469
orig_sql_mode= field->table->in_use->variables.sql_mode;
4470
if (value->real_item()->type() == Item::STRING_ITEM &&
4471
(field->type() == DRIZZLE_TYPE_NEWDATE ||
4472
field->type() == DRIZZLE_TYPE_DATETIME))
4473
field->table->in_use->variables.sql_mode|= MODE_INVALID_DATES;
4474
err= value->save_in_field_no_warnings(field, 1);
4506
* Some notes from Jay...
4508
* OK, so previously, and in MySQL, what the optimizer does here is
4509
* override the sql_mode variable to ignore out-of-range or bad date-
4510
* time values. It does this because the optimizer is populating the
4511
* field variable with the incoming value from the comparison field,
4512
* and the value may exceed the bounds of a proper column type.
4514
* For instance, assume the following:
4516
* CREATE TABLE t1 (ts TIMESTAMP);
4517
* INSERT INTO t1 ('2009-03-04 00:00:00');
4518
* CREATE TABLE t2 (dt1 DATETIME, dt2 DATETIME);
4519
* INSERT INT t2 ('2003-12-31 00:00:00','2999-12-31 00:00:00');
4521
* If we issue this query:
4523
* SELECT * FROM t1, t2 WHERE t1.ts BETWEEN t2.dt1 AND t2.dt2;
4525
* We will come into bounds issues. Field_timestamp::store() will be
4526
* called with a datetime value of "2999-12-31 00:00:00" and will throw
4527
* an error for out-of-bounds. MySQL solves this via a hack with sql_mode
4528
* but Drizzle always throws errors on bad data storage in a Field class.
4530
* Therefore, to get around the problem of the Field class being used for
4531
* "storage" here without actually storing anything...we must check to see
4532
* if the value being stored in a Field_timestamp here is out of range. If
4533
* it is, then we must convert to the highest Timestamp value (or lowest,
4534
* depending on whether the datetime is before or after the epoch.
4536
if (field->type() == DRIZZLE_TYPE_TIMESTAMP)
4539
* The left-side of the range comparison is a timestamp field. Therefore,
4540
* we must check to see if the value in the right-hand side is outside the
4541
* range of the UNIX epoch, and cut to the epoch bounds if it is.
4543
/* Datetime and date columns are Item::FIELD_ITEM ... and have a result type of STRING_RESULT */
4544
if (value->real_item()->type() == Item::FIELD_ITEM
4545
&& value->result_type() == STRING_RESULT)
4547
char buff[MAX_DATETIME_FULL_WIDTH];
4548
String tmp(buff, sizeof(buff), &my_charset_bin);
4549
String *res= value->val_str(&tmp);
4556
* Create a datetime from the string and compare to fixed timestamp
4557
* instances representing the epoch boundaries.
4559
drizzled::DateTime value_datetime;
4561
if (! value_datetime.from_string(res->c_ptr(), (size_t) res->length()))
4564
drizzled::Timestamp max_timestamp;
4565
drizzled::Timestamp min_timestamp;
4567
(void) max_timestamp.from_time_t((time_t) INT32_MAX);
4568
(void) min_timestamp.from_time_t((time_t) 0);
4570
/* We rely on Temporal class operator overloads to do our comparisons. */
4571
if (value_datetime < min_timestamp)
4574
* Datetime in right-hand side column is before UNIX epoch, so adjust to
4577
char new_value_buff[MAX_DATETIME_FULL_WIDTH];
4578
size_t new_value_length;
4579
String new_value_string(new_value_buff, sizeof(new_value_buff), &my_charset_bin);
4581
min_timestamp.to_string(new_value_string.c_ptr(), &new_value_length);
4582
new_value_string.length(new_value_length);
4583
err= value->save_str_value_in_field(field, &new_value_string);
4585
else if (value_datetime > max_timestamp)
4588
* Datetime in right hand side column is after UNIX epoch, so adjust
4589
* to the higher bound of the epoch.
4591
char new_value_buff[MAX_DATETIME_FULL_WIDTH];
4592
size_t new_value_length;
4593
String new_value_string(new_value_buff, sizeof(new_value_buff), &my_charset_bin);
4595
max_timestamp.to_string(new_value_string.c_ptr(), &new_value_length);
4596
new_value_string.length(new_value_length);
4597
err= value->save_str_value_in_field(field, &new_value_string);
4600
err= value->save_in_field(field, 1);
4603
else /* Not a datetime -> timestamp comparison */
4604
err= value->save_in_field(field, 1);
4606
else /* Not a timestamp comparison */
4607
err= value->save_in_field(field, 1);
4477
4611
if (field->cmp_type() != value->result_type())
4793
4925
call tree_and(tree1, tree2) -- this joins SEL_ARGs into a usable SEL_ARG
4796
4928
There is an exception though: when we construct index_merge SEL_TREE,
4797
4929
any SEL_ARG* tree that cannot be used to construct quick range select can
4798
4930
be removed, because current range analysis code doesn't provide any way
4799
4931
that tree could be later combined with another tree.
4800
4932
Consider an example: we should not construct
4802
merges = SEL_IMERGE {
4803
SEL_TREE(t.key1part1 = 1),
4934
merges = SEL_IMERGE {
4935
SEL_TREE(t.key1part1 = 1),
4804
4936
SEL_TREE(t.key2part2 = 2) -- (*)
4808
- (*) cannot be used to construct quick range select,
4809
- There is no execution path that would cause (*) to be converted to
4940
- (*) cannot be used to construct quick range select,
4941
- There is no execution path that would cause (*) to be converted to
4810
4942
a tree that could be used.
4812
4944
The latter is easy to verify: first, notice that the only way to convert
4813
4945
(*) into a usable tree is to call tree_and(something, (*)).
4815
4947
Second look at what tree_and/tree_or function would do when passed a
4816
SEL_TREE that has the structure like st1 tree has, and conlcude that
4948
SEL_TREE that has the structure like st1 tree has, and conlcude that
4817
4949
tree_and(something, (*)) will not be called.
5729
5866
return 0; // Found end of tree
5730
5867
if (element->parent != parent)
5732
sql_print_error("Wrong tree: Parent doesn't point at parent");
5869
errmsg_printf(ERRMSG_LVL_ERROR, "Wrong tree: Parent doesn't point at parent");
5735
5872
if (element->color == SEL_ARG::RED &&
5736
5873
(element->left->color == SEL_ARG::RED ||
5737
5874
element->right->color == SEL_ARG::RED))
5739
sql_print_error("Wrong tree: Found two red in a row");
5876
errmsg_printf(ERRMSG_LVL_ERROR, "Wrong tree: Found two red in a row");
5742
5879
if (element->left == element->right && element->left != &null_element)
5743
5880
{ // Dummy test
5744
sql_print_error("Wrong tree: Found right == left");
5881
errmsg_printf(ERRMSG_LVL_ERROR, "Wrong tree: Found right == left");
5747
5884
count_l=test_rb_tree(element->left,element);
5772
5909
This function counts how many times the node "key" is referred (via
5773
SEL_ARG::next_key_part) by
5774
- intervals of RB-tree pointed by "root",
5775
- intervals of RB-trees that are pointed by SEL_ARG::next_key_part from
5910
SEL_ARG::next_key_part) by
5911
- intervals of RB-tree pointed by "root",
5912
- intervals of RB-trees that are pointed by SEL_ARG::next_key_part from
5776
5913
intervals of RB-tree pointed by "root",
5779
Here is an example (horizontal links represent next_key_part pointers,
5780
vertical links - next/prev prev pointers):
5916
Here is an example (horizontal links represent next_key_part pointers,
5917
vertical links - next/prev prev pointers):
5783
5920
|root|-----------------+
5870
6007
****************************************************************************/
5872
6009
/* MRR range sequence, SEL_ARG* implementation: stack entry */
5873
typedef struct st_range_seq_entry
6010
typedef struct st_range_seq_entry
5876
6013
Pointers in min and max keys. They point to right-after-end of key
5877
6014
images. The 0-th entry has these pointing to key tuple start.
5879
6016
unsigned char *min_key, *max_key;
5882
6019
Flags, for {keypart0, keypart1, ... this_keypart} subtuple.
5883
6020
min_key_flag may have NULL_RANGE set.
5885
6022
uint32_t min_key_flag, max_key_flag;
5887
6024
/* Number of key parts */
5888
6025
uint32_t min_key_parts, max_key_parts;
5889
6026
SEL_ARG *key_tree;
6085
6220
/* Ok got a tuple */
6086
6221
RANGE_SEQ_ENTRY *cur= &seq->stack[seq->i];
6088
6223
range->ptr= (char*)(int)(key_tree->part);
6090
6225
range->range_flag= cur->min_key_flag | cur->max_key_flag;
6092
6227
range->start_key.key= seq->param->min_key;
6093
6228
range->start_key.length= cur->min_key - seq->param->min_key;
6094
6229
range->start_key.keypart_map= make_prev_keypart_map(cur->min_key_parts);
6095
range->start_key.flag= (cur->min_key_flag & NEAR_MIN ? HA_READ_AFTER_KEY :
6230
range->start_key.flag= (cur->min_key_flag & NEAR_MIN ? HA_READ_AFTER_KEY :
6096
6231
HA_READ_KEY_EXACT);
6098
6233
range->end_key.key= seq->param->max_key;
6099
6234
range->end_key.length= cur->max_key - seq->param->max_key;
6100
range->end_key.flag= (cur->max_key_flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
6235
range->end_key.flag= (cur->max_key_flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
6101
6236
HA_READ_AFTER_KEY);
6102
6237
range->end_key.keypart_map= make_prev_keypart_map(cur->max_key_parts);
6104
6239
if (!(cur->min_key_flag & ~NULL_RANGE) && !cur->max_key_flag &&
6105
(uint)key_tree->part+1 == seq->param->table->key_info[seq->real_keyno].key_parts &&
6240
(uint32_t)key_tree->part+1 == seq->param->table->key_info[seq->real_keyno].key_parts &&
6106
6241
(seq->param->table->key_info[seq->real_keyno].flags & (HA_NOSAME)) ==
6108
6243
range->start_key.length == range->end_key.length &&
6109
6244
!memcmp(seq->param->min_key,seq->param->max_key,range->start_key.length))
6110
6245
range->range_flag= UNIQUE_RANGE | (cur->min_key_flag & NULL_RANGE);
6112
6247
if (seq->param->is_ror_scan)
6190
6325
param->is_ror_scan= true;
6191
6326
if (file->index_flags(keynr, 0, true) & HA_KEY_SCAN_NOT_ROR)
6192
6327
param->is_ror_scan= false;
6194
6329
*mrr_flags= param->force_default_mrr? HA_MRR_USE_DEFAULT_IMPL: 0;
6195
6330
*mrr_flags|= HA_MRR_NO_ASSOCIATION;
6197
6332
bool pk_is_clustered= file->primary_key_is_clustered();
6199
6334
(file->index_flags(keynr, param->max_key_part, 1) & HA_KEYREAD_ONLY) &&
6200
6335
!(pk_is_clustered && keynr == param->table->s->primary_key))
6201
6336
*mrr_flags |= HA_MRR_INDEX_ONLY;
6203
if (current_thd->lex->sql_command != SQLCOM_SELECT)
6338
if (current_session->lex->sql_command != SQLCOM_SELECT)
6204
6339
*mrr_flags |= HA_MRR_USE_DEFAULT_IMPL;
6206
*bufsize= param->thd->variables.read_rnd_buff_size;
6341
*bufsize= param->session->variables.read_rnd_buff_size;
6207
6342
rows= file->multi_range_read_info_const(keynr, &seq_if, (void*)&seq, 0,
6208
6343
bufsize, mrr_flags, cost);
6209
6344
if (rows != HA_POS_ERROR)
6264
6399
where the index is defined on (key1_1, ..., key1_N [,a_1, ..., a_n])
6266
and the table has a clustered Primary Key defined as
6267
PRIMARY KEY(a_1, ..., a_n, b1, ..., b_k)
6269
i.e. the first key parts of it are identical to uncovered parts ot the
6401
and the table has a clustered Primary Key defined as
6402
PRIMARY KEY(a_1, ..., a_n, b1, ..., b_k)
6404
i.e. the first key parts of it are identical to uncovered parts ot the
6270
6405
key being scanned. This function assumes that the index flags do not
6271
6406
include HA_KEY_SCAN_NOT_ROR flag (that is checked elsewhere).
6467
6602
/* Get range for retrieving rows in QUICK_SELECT::get_next */
6468
6603
if (!(range= new QUICK_RANGE(param->min_key,
6469
(uint) (tmp_min_key - param->min_key),
6604
(uint32_t) (tmp_min_key - param->min_key),
6470
6605
min_part >=0 ? make_keypart_map(min_part) : 0,
6471
6606
param->max_key,
6472
(uint) (tmp_max_key - param->max_key),
6607
(uint32_t) (tmp_max_key - param->max_key),
6473
6608
max_part >=0 ? make_keypart_map(max_part) : 0,
6475
6610
return 1; // out of memory
6477
set_if_bigger(quick->max_used_key_length, range->min_length);
6478
set_if_bigger(quick->max_used_key_length, range->max_length);
6479
set_if_bigger(quick->used_key_parts, (uint) key_tree->part+1);
6612
set_if_bigger(quick->max_used_key_length, (uint32_t)range->min_length);
6613
set_if_bigger(quick->max_used_key_length, (uint32_t)range->max_length);
6614
set_if_bigger(quick->used_key_parts, (uint32_t) key_tree->part+1);
6480
6615
if (insert_dynamic(&quick->ranges, (unsigned char*) &range))
6609
6744
bool create_err= false;
6610
6745
COST_VECT cost;
6612
old_root= thd->mem_root;
6613
/* The following call may change thd->mem_root */
6614
quick= new QUICK_RANGE_SELECT(thd, table, ref->key, 0, 0, &create_err);
6747
old_root= session->mem_root;
6748
/* The following call may change session->mem_root */
6749
quick= new QUICK_RANGE_SELECT(session, table, ref->key, 0, 0, &create_err);
6615
6750
/* save mem_root set by QUICK_RANGE_SELECT constructor */
6616
alloc= thd->mem_root;
6751
alloc= session->mem_root;
6618
return back default mem_root (thd->mem_root) changed by
6753
return back default mem_root (session->mem_root) changed by
6619
6754
QUICK_RANGE_SELECT constructor
6621
thd->mem_root= old_root;
6756
session->mem_root= old_root;
6623
6758
if (!quick || create_err)
6624
6759
return 0; /* no ranges found */
6678
6813
/* Call multi_range_read_info() to get the MRR flags and buffer size */
6679
quick->mrr_flags= HA_MRR_NO_ASSOCIATION |
6814
quick->mrr_flags= HA_MRR_NO_ASSOCIATION |
6680
6815
(table->key_read ? HA_MRR_INDEX_ONLY : 0);
6681
if (thd->lex->sql_command != SQLCOM_SELECT)
6816
if (session->lex->sql_command != SQLCOM_SELECT)
6682
6817
quick->mrr_flags |= HA_MRR_USE_DEFAULT_IMPL;
6684
quick->mrr_buf_size= thd->variables.read_rnd_buff_size;
6685
if (table->file->multi_range_read_info(quick->index, 1, (uint)records,
6819
quick->mrr_buf_size= session->variables.read_rnd_buff_size;
6820
if (table->file->multi_range_read_info(quick->index, 1, (uint32_t)records,
6686
6821
&quick->mrr_buf_size,
6687
6822
&quick->mrr_flags, &cost))
7029
7165
Range sequence interface implementation for array<QUICK_RANGE>: initialize
7032
7168
quick_range_seq_init()
7033
7169
init_param Caller-opaque paramenter: QUICK_RANGE_SELECT* pointer
7034
7170
n_ranges Number of ranges in the sequence (ignored)
7035
flags MRR flags (currently not used)
7171
flags MRR flags (currently not used)
7038
7174
Opaque value to be passed to quick_range_seq_next
7041
range_seq_t quick_range_seq_init(void *init_param,
7042
uint32_t n_ranges __attribute__((unused)),
7043
uint32_t flags __attribute__((unused)))
7177
range_seq_t quick_range_seq_init(void *init_param, uint32_t, uint32_t)
7045
7179
QUICK_RANGE_SELECT *quick= (QUICK_RANGE_SELECT*)init_param;
7046
7180
quick->qr_traversal_ctx.first= (QUICK_RANGE**)quick->ranges.buffer;
7855
7986
/* Perform few 'cheap' tests whether this access method is applicable. */
7857
return(NULL); /* This is not a select statement. */
7988
return NULL; /* This is not a select statement. */
7858
7989
if ((join->tables != 1) || /* The query must reference one table. */
7859
7990
((!join->group_list) && /* Neither GROUP BY nor a DISTINCT query. */
7860
7991
(!join->select_distinct)) ||
7861
7992
(join->select_lex->olap == ROLLUP_TYPE)) /* Check (B3) for ROLLUP */
7863
7994
if (table->s->keys == 0) /* There are no indexes to use. */
7866
7997
/* Analyze the query in more detail. */
7867
7998
List_iterator<Item> select_items_it(join->fields_list);
7869
8000
/* Check (SA1,SA4) and store the only MIN/MAX argument - the C attribute.*/
7870
8001
if (join->make_sum_func_list(join->all_fields, join->fields_list, 1))
7872
8003
if (join->sum_funcs[0])
7874
8005
Item_sum *min_max_item;
8392
get_constant_key_infix(KEY *index_info __attribute__((unused)),
8393
SEL_ARG *index_range_tree,
8523
get_constant_key_infix(KEY *, SEL_ARG *index_range_tree,
8394
8524
KEY_PART_INFO *first_non_group_part,
8395
8525
KEY_PART_INFO *min_max_arg_part,
8396
8526
KEY_PART_INFO *last_part,
8397
THD *thd __attribute__((unused)),
8398
unsigned char *key_infix, uint32_t *key_infix_len,
8527
Session *, unsigned char *key_infix, uint32_t *key_infix_len,
8399
8528
KEY_PART_INFO **first_non_infix_part)
8401
8530
SEL_ARG *cur_range;
8609
8737
keys_per_block= (table->file->stats.block_size / 2 /
8610
8738
(index_info->key_length + table->file->ref_length)
8612
num_blocks= (uint)(table_records / keys_per_block) + 1;
8740
num_blocks= (uint32_t)(table_records / keys_per_block) + 1;
8614
8742
/* Compute the number of keys in a group. */
8615
8743
keys_per_group= index_info->rec_per_key[group_key_parts - 1];
8616
8744
if (keys_per_group == 0) /* If there is no statistics try to guess */
8617
8745
/* each group contains 10% of all records */
8618
keys_per_group= (uint)(table_records / 10) + 1;
8619
num_groups= (uint)(table_records / keys_per_group) + 1;
8746
keys_per_group= (uint32_t)(table_records / 10) + 1;
8747
num_groups= (uint32_t)(table_records / keys_per_group) + 1;
8621
8749
/* Apply the selectivity of the quick select for group prefixes. */
8622
8750
if (range_tree && (quick_prefix_records != HA_POS_ERROR))
8624
8752
quick_prefix_selectivity= (double) quick_prefix_records /
8625
8753
(double) table_records;
8626
num_groups= (uint) rint(num_groups * quick_prefix_selectivity);
8627
set_if_bigger(num_groups, 1);
8754
num_groups= (uint32_t) rint(num_groups * quick_prefix_selectivity);
8755
set_if_bigger(num_groups, 1U);
8630
8758
if (used_key_parts > group_key_parts)
8686
8813
QUICK_SELECT_I *
8687
TRP_GROUP_MIN_MAX::make_quick(PARAM *param,
8688
bool retrieve_full_rows __attribute__((unused)),
8689
MEM_ROOT *parent_alloc)
8814
TRP_GROUP_MIN_MAX::make_quick(PARAM *param, bool, MEM_ROOT *parent_alloc)
8691
8816
QUICK_GROUP_MIN_MAX_SELECT *quick;
8693
8818
quick= new QUICK_GROUP_MIN_MAX_SELECT(param->table,
8694
param->thd->lex->current_select->join,
8819
param->session->lex->current_select->join,
8695
8820
have_min, have_max, min_max_arg_part,
8696
8821
group_prefix_len, group_key_parts,
8697
8822
used_key_parts, index_info, index,
8698
8823
read_cost, records, key_infix_len,
8699
8824
key_infix, parent_alloc);
8703
8828
if (quick->init())
8709
8834
if (range_tree)
9510
9637
if ( !(cur_range->flag & NO_MAX_RANGE) )
9512
9639
/* Compose the MAX key for the range. */
9513
unsigned char *max_key= (unsigned char*) my_alloca(real_prefix_len + min_max_arg_len);
9514
memcpy(max_key, group_prefix, real_prefix_len);
9515
memcpy(max_key + real_prefix_len, cur_range->max_key,
9516
cur_range->max_length);
9641
max_key.append(group_prefix, real_prefix_len);
9642
max_key.append(cur_range->max_key, cur_range->max_length);
9517
9643
/* Compare the found key with max_key. */
9518
int cmp_res= key_cmp(index_info->key_part, max_key,
9644
int cmp_res= key_cmp(index_info->key_part,
9519
9646
real_prefix_len + min_max_arg_len);
9520
9647
if ((!((cur_range->flag & NEAR_MAX) && (cmp_res == -1)) || (cmp_res <= 0)))
9627
9756
if ( !(cur_range->flag & NO_MIN_RANGE) )
9629
9758
/* Compose the MIN key for the range. */
9630
unsigned char *min_key= (unsigned char*) my_alloca(real_prefix_len + min_max_arg_len);
9631
memcpy(min_key, group_prefix, real_prefix_len);
9632
memcpy(min_key + real_prefix_len, cur_range->min_key,
9633
cur_range->min_length);
9760
min_key.append(group_prefix, real_prefix_len);
9761
min_key.append(cur_range->min_key, cur_range->min_length);
9634
9763
/* Compare the found key with min_key. */
9635
int cmp_res= key_cmp(index_info->key_part, min_key,
9764
int cmp_res= key_cmp(index_info->key_part,
9636
9766
real_prefix_len + min_max_arg_len);
9637
9767
if ((!((cur_range->flag & NEAR_MIN) && (cmp_res == 1)) ||
9638
9768
(cmp_res >= 0)))