Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
545ce857
Commit
545ce857
authored
May 16, 2006
by
unknown
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
BUG#19618: post-review fixes: better comments
parent
e5838e16
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
39 additions
and
21 deletions
+39
-21
sql/opt_range.cc
sql/opt_range.cc
+39
-21
No files found.
sql/opt_range.cc
View file @
545ce857
...
@@ -3503,17 +3503,46 @@ static SEL_TREE *get_func_mm_tree(PARAM *param, Item_func *cond_func,
...
@@ -3503,17 +3503,46 @@ static SEL_TREE *get_func_mm_tree(PARAM *param, Item_func *cond_func,
if
(
inv
)
if
(
inv
)
{
{
/*
We get here for conditions like "t.keypart NOT IN (....)".
If the IN-list contains only constants (and func->array is an ordered
array of them), we construct the appropriate SEL_ARG tree manually,
because constructing it using the range analyzer (as
AND_i( t.keypart != c_i)) will cause lots of memory to be consumed
(see BUG#15872).
*/
if
(
func
->
array
&&
func
->
cmp_type
!=
ROW_RESULT
)
if
(
func
->
array
&&
func
->
cmp_type
!=
ROW_RESULT
)
{
{
/*
We get here for conditions in form "t.key NOT IN (c1, c2, ...)"
(where c{i} are constants).
Our goal is to produce a SEL_ARG graph that represents intervals:
($MIN<t.key<c1) OR (c1<t.key<c2) OR (c2<t.key<c3) OR ... (*)
where $MIN is either "-inf" or NULL.
The most straightforward way to handle NOT IN would be to convert
it to "(t.key != c1) AND (t.key != c2) AND ..." and let the range
optimizer to build SEL_ARG graph from that. However that will cause
the range optimizer to use O(N^2) memory (it's a bug, not filed),
and people do use big NOT IN lists (see BUG#15872). Also, for big
NOT IN lists constructing/using graph (*) does not make the query
faster.
So, we will handle NOT IN manually in the following way:
* if the number of entries in the NOT IN list is less then
NOT_IN_IGNORE_THRESHOLD, we will construct SEL_ARG graph (*)
manually.
* Otherwise, we will construct a smaller graph: for
"t.key NOT IN (c1,...cN)" we construct a graph representing
($MIN < t.key) OR (cN < t.key) // here sequence of c_i is
// ordered.
A note about partially-covering indexes: for those (e.g. for
"a CHAR(10), KEY(a(5))") the handling is correct (albeit not very
efficient):
Instead of "t.key < c1" we get "t.key <= prefix-val(c1)".
Combining the intervals in (*) together, we get:
(-inf<=t.key<=c1) OR (c1<=t.key<=c2) OR (c2<=t.key<=c3) OR ...
i.e. actually we get intervals combined into one interval:
(-inf<=t.key<=+inf). This doesn't make much sense but it doesn't
cause any problems.
*/
MEM_ROOT
*
tmp_root
=
param
->
mem_root
;
param
->
thd
->
mem_root
=
param
->
old_root
;
/*
/*
Create one Item_type constant object. We'll need it as
Create one Item_type constant object. We'll need it as
get_mm_parts only accepts constant values wrapped in Item_Type
get_mm_parts only accepts constant values wrapped in Item_Type
...
@@ -3522,24 +3551,13 @@ static SEL_TREE *get_func_mm_tree(PARAM *param, Item_func *cond_func,
...
@@ -3522,24 +3551,13 @@ static SEL_TREE *get_func_mm_tree(PARAM *param, Item_func *cond_func,
per-statement mem_root (while thd->mem_root is currently pointing
per-statement mem_root (while thd->mem_root is currently pointing
to mem_root local to range optimizer).
to mem_root local to range optimizer).
*/
*/
MEM_ROOT
*
tmp_root
=
param
->
mem_root
;
param
->
thd
->
mem_root
=
param
->
old_root
;
Item
*
value_item
=
func
->
array
->
create_item
();
Item
*
value_item
=
func
->
array
->
create_item
();
param
->
thd
->
mem_root
=
tmp_root
;
param
->
thd
->
mem_root
=
tmp_root
;
if
(
!
value_item
)
if
(
!
value_item
)
break
;
break
;
/*
/* Get a SEL_TREE for "(-inf|NULL) < X < c_0" interval. */
Get a SEL_TREE for "(-inf|NULL) < X < c_0" interval.
Note: for partially-covering keys the returned tree may represent
a half-closed interval (-inf < X <= c_0). In that case the for the
whole NOT IN statement the (-inf < X < +inf) interval will be
constructed. It doesn't make sense to consider range access over
such intervals, but we don't eliminate them here as 1) they are
handled correctly by all parts of the code, and 2) the case where
such intervals are constructed is rare.
*/
uint
i
=
0
;
uint
i
=
0
;
do
do
{
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment