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
2656709a
Commit
2656709a
authored
Sep 02, 2009
by
Sergey Petrunya
Browse files
Options
Browse Files
Download
Plain Diff
Merge
parents
34d901c0
24c2fea6
Changes
10
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
1267 additions
and
921 deletions
+1267
-921
include/my_global.h
include/my_global.h
+1
-2
sql-bench/test-table-elimination.sh
sql-bench/test-table-elimination.sh
+0
-4
sql/item.cc
sql/item.cc
+2
-2
sql/item.h
sql/item.h
+21
-6
sql/item_cmpfunc.cc
sql/item_cmpfunc.cc
+1
-27
sql/item_subselect.cc
sql/item_subselect.cc
+2
-2
sql/item_subselect.h
sql/item_subselect.h
+1
-1
sql/opt_table_elimination.cc
sql/opt_table_elimination.cc
+1165
-871
sql/sql_list.h
sql/sql_list.h
+37
-0
sql/sql_select.cc
sql/sql_select.cc
+37
-6
No files found.
include/my_global.h
View file @
2656709a
...
...
@@ -950,8 +950,7 @@ typedef long long my_ptrdiff_t;
#define MY_ALIGN(A,L) (((A) + (L) - 1) & ~((L) - 1))
#define ALIGN_SIZE(A) MY_ALIGN((A),sizeof(double))
/* Size to make adressable obj. */
#define ALIGN_PTR(A, t) ((t*) MY_ALIGN((A),sizeof(t)))
/* Offset of field f in structure t */
#define ALIGN_PTR(A, t) ((t*) MY_ALIGN((A), sizeof(double)))
#define OFFSET(t, f) ((size_t)(char *)&((t *)0)->f)
#define ADD_TO_PTR(ptr,size,type) (type) ((uchar*) (ptr)+size)
#define PTR_BYTE_DIFF(A,B) (my_ptrdiff_t) ((uchar*) (A) - (uchar*) (B))
...
...
sql-bench/test-table-elimination.sh
View file @
2656709a
...
...
@@ -290,10 +290,6 @@ print "time for select_one_attribute ($count:$rows): " .
timestr
(
timediff
(
$end_time
,
$loop_time
)
,
"all"
)
.
"
\n
"
;
###
### TODO...
###
;
####
...
...
sql/item.cc
View file @
2656709a
...
...
@@ -1916,10 +1916,10 @@ void Item_field::reset_field(Field *f)
}
bool
Item_field
::
check_column_usage
_processor
(
uchar
*
arg
)
bool
Item_field
::
enumerate_field_refs
_processor
(
uchar
*
arg
)
{
Field_enumerator
*
fe
=
(
Field_enumerator
*
)
arg
;
fe
->
see
_field
(
field
);
fe
->
visit
_field
(
field
);
return
FALSE
;
}
...
...
sql/item.h
View file @
2656709a
...
...
@@ -734,7 +734,7 @@ public:
/*
Bitmap of tables used by item
(note: if you need to check dependencies on individual columns, check out
c
heck_column_usage_process
or)
c
lass Field_enumerat
or)
*/
virtual
table_map
used_tables
()
const
{
return
(
table_map
)
0L
;
}
/*
...
...
@@ -892,7 +892,7 @@ public:
virtual
bool
reset_query_id_processor
(
uchar
*
query_id_arg
)
{
return
0
;
}
virtual
bool
is_expensive_processor
(
uchar
*
arg
)
{
return
0
;
}
virtual
bool
register_field_in_read_map
(
uchar
*
arg
)
{
return
0
;
}
virtual
bool
check_column_usage
_processor
(
uchar
*
arg
)
{
return
0
;
}
virtual
bool
enumerate_field_refs
_processor
(
uchar
*
arg
)
{
return
0
;
}
virtual
bool
mark_as_eliminated_processor
(
uchar
*
arg
)
{
return
0
;
}
/*
Check if a partition function is allowed
...
...
@@ -1018,14 +1018,29 @@ public:
};
/* Data for Item::check_column_usage_processor */
/*
Class to be used to enumerate all field references in an item tree.
Suggested usage:
class My_enumerator : public Field_enumerator
{
virtual void visit_field() { ... your actions ...}
}
My_enumerator enumerator;
item->walk(Item::enumerate_field_refs_processor, ...,(uchar*)&enumerator);
This is similar to Visitor pattern.
*/
class
Field_enumerator
{
public:
virtual
void
see
_field
(
Field
*
field
)
=
0
;
virtual
~
Field_enumerator
()
{};
/*
Shut up compiler warning
*/
virtual
void
visit
_field
(
Field
*
field
)
=
0
;
virtual
~
Field_enumerator
()
{};
/*
purecov: inspected
*/
};
class
sp_head
;
...
...
@@ -1491,7 +1506,7 @@ public:
bool
find_item_in_field_list_processor
(
uchar
*
arg
);
bool
register_field_in_read_map
(
uchar
*
arg
);
bool
check_partition_func_processor
(
uchar
*
int_arg
)
{
return
FALSE
;}
bool
check_column_usage
_processor
(
uchar
*
arg
);
bool
enumerate_field_refs
_processor
(
uchar
*
arg
);
void
cleanup
();
bool
result_as_longlong
()
{
...
...
sql/item_cmpfunc.cc
View file @
2656709a
...
...
@@ -5168,33 +5168,7 @@ void Item_equal::merge(Item_equal *item)
void
Item_equal
::
sort
(
Item_field_cmpfunc
cmp
,
void
*
arg
)
{
bool
swap
;
List_iterator
<
Item_field
>
it
(
fields
);
do
{
Item_field
*
item1
=
it
++
;
Item_field
**
ref1
=
it
.
ref
();
Item_field
*
item2
;
swap
=
FALSE
;
while
((
item2
=
it
++
))
{
Item_field
**
ref2
=
it
.
ref
();
if
(
cmp
(
item1
,
item2
,
arg
)
<
0
)
{
Item_field
*
item
=
*
ref1
;
*
ref1
=
*
ref2
;
*
ref2
=
item
;
swap
=
TRUE
;
}
else
{
item1
=
item2
;
ref1
=
ref2
;
}
}
it
.
rewind
();
}
while
(
swap
);
exchange_sort
<
Item_field
>
(
&
fields
,
cmp
,
arg
);
}
...
...
sql/item_subselect.cc
View file @
2656709a
...
...
@@ -215,13 +215,13 @@ err:
}
bool
Item_subselect
::
check_column_usage
_processor
(
uchar
*
arg
)
bool
Item_subselect
::
enumerate_field_refs
_processor
(
uchar
*
arg
)
{
List_iterator
<
Item
>
it
(
refers_to
);
Item
*
item
;
while
((
item
=
it
++
))
{
if
(
item
->
walk
(
&
Item
::
check_column_usage_processor
,
FALSE
,
arg
))
if
(
item
->
walk
(
&
Item
::
enumerate_field_refs_processor
,
FALSE
,
arg
))
return
TRUE
;
}
return
FALSE
;
...
...
sql/item_subselect.h
View file @
2656709a
...
...
@@ -135,7 +135,7 @@ public:
enum_parsing_place
place
()
{
return
parsing_place
;
}
bool
walk
(
Item_processor
processor
,
bool
walk_subquery
,
uchar
*
arg
);
bool
mark_as_eliminated_processor
(
uchar
*
arg
);
bool
check_column_usage
_processor
(
uchar
*
arg
);
bool
enumerate_field_refs
_processor
(
uchar
*
arg
);
/**
Get the SELECT_LEX structure associated with this Item.
...
...
sql/opt_table_elimination.cc
View file @
2656709a
This diff is collapsed.
Click to expand it.
sql/sql_list.h
View file @
2656709a
...
...
@@ -442,6 +442,43 @@ public:
};
/*
Exchange sort algorithm for List<T>.
*/
template
<
class
T
>
inline
void
exchange_sort
(
List
<
T
>
*
list_to_sort
,
int
(
*
sort_func
)(
T
*
a
,
T
*
b
,
void
*
arg
),
void
*
arg
)
{
bool
swap
;
List_iterator
<
T
>
it
(
*
list_to_sort
);
do
{
T
*
item1
=
it
++
;
T
**
ref1
=
it
.
ref
();
T
*
item2
;
swap
=
FALSE
;
while
((
item2
=
it
++
))
{
T
**
ref2
=
it
.
ref
();
if
(
sort_func
(
item1
,
item2
,
arg
)
<
0
)
{
T
*
item
=
*
ref1
;
*
ref1
=
*
ref2
;
*
ref2
=
item
;
swap
=
TRUE
;
}
else
{
item1
=
item2
;
ref1
=
ref2
;
}
}
it
.
rewind
();
}
while
(
swap
);
}
/*
A simple intrusive list which automaticly removes element from list
on delete (for THD element)
...
...
sql/sql_select.cc
View file @
2656709a
...
...
@@ -2991,22 +2991,33 @@ typedef struct key_field_t {
elements that would correspond to "$LEFT_PART OR $RIGHT_PART".
The rules for combining elements are as follows:
(keyfieldA1 AND keyfieldA2 AND ...) OR (keyfieldB1 AND keyfieldB2 AND ...)=
AND_ij (keyfieldA_i OR keyfieldB_j)
= AND_ij (keyfieldA_i OR keyfieldB_j)
We discard all (keyfieldA_i OR keyfieldB_j) that refer to different
fields. For those referring to the same field, the logic is as follows:
t.keycol=
t.keycol=expr1 OR t.keycol=expr2 -> (since expr1 and expr2 are different
we can't produce a single equality,
so produce nothing)
t.keycol=expr1 OR t.keycol=expr1 -> t.keycol=expr1
t.keycol=expr1 OR t.keycol IS NULL -> t.keycol=expr1, and also set
KEY_OPTIMIZE_REF_OR_NULL flag
T
o be able to do 'ref_or_null' we merge a comparison of a column
and 'column IS NULL' to one test. This is useful for sub select queries
t
hat are internally transformed to something like:.
T
he last one is for ref_or_null access. We have handling for this special
because it's needed for evaluating IN subqueries that are internally
t
ransformed into
@code
SELECT * FROM t1 WHERE t1.key=outer_ref_field or t1.key IS NULL
EXISTS(SELECT * FROM t1 WHERE t1.key=outer_ref_field or t1.key IS NULL)
@endcode
See add_key_fields() for discussion of what is and_level.
KEY_FIELD::null_rejecting is processed as follows: @n
result has null_rejecting=true if it is set for both ORed references.
for example:
...
...
@@ -3346,6 +3357,26 @@ add_key_equal_fields(KEY_FIELD **key_fields, uint and_level,
}
}
/*
In this and other functions, and_level is a number that is ever-growing
and is different for the contents of every AND or OR clause. For example,
when processing clause
(a AND b AND c) OR (x AND y)
we'll have
* KEY_FIELD elements for (a AND b AND c) are assigned and_level=1
* KEY_FIELD elements for (x AND y) are assigned and_level=2
* OR operation is performed, and whatever elements are left after it are
assigned and_level=3.
The primary reason for having and_level attribute is the OR operation which
uses and_level to mark KEY_FIELDs that should get into the result of the OR
operation
*/
static
void
add_key_fields
(
JOIN
*
join
,
KEY_FIELD
**
key_fields
,
uint
*
and_level
,
COND
*
cond
,
table_map
usable_tables
,
...
...
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