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
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
aa300fa7
Commit
aa300fa7
authored
Jun 24, 2005
by
konstantin@mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge bk-internal.mysql.com:/home/bk/mysql-5.0
into mysql.com:/opt/local/work/mysql-5.0-join_free2push
parents
4ab4ee9c
56a37f8e
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
115 additions
and
85 deletions
+115
-85
sql/sql_lex.h
sql/sql_lex.h
+5
-0
sql/sql_select.cc
sql/sql_select.cc
+72
-63
sql/sql_select.h
sql/sql_select.h
+9
-1
sql/sql_union.cc
sql/sql_union.cc
+29
-21
No files found.
sql/sql_lex.h
View file @
aa300fa7
...
...
@@ -642,6 +642,11 @@ class st_select_lex: public st_select_lex_node
static
void
print_order
(
String
*
str
,
ORDER
*
order
);
void
print_limit
(
THD
*
thd
,
String
*
str
);
void
fix_prepare_information
(
THD
*
thd
,
Item
**
conds
);
/*
Destroy the used execution plan (JOIN) of this subtree (this
SELECT_LEX and all nested SELECT_LEXes and SELECT_LEX_UNITs).
*/
bool
cleanup
();
};
typedef
class
st_select_lex
SELECT_LEX
;
...
...
sql/sql_select.cc
View file @
aa300fa7
...
...
@@ -87,10 +87,9 @@ static void update_depend_map(JOIN *join, ORDER *order);
static
ORDER
*
remove_const
(
JOIN
*
join
,
ORDER
*
first_order
,
COND
*
cond
,
bool
change_list
,
bool
*
simple_order
);
static
int
return_zero_rows
(
JOIN
*
join
,
select_result
*
res
,
TABLE_LIST
*
tables
,
List
<
Item
>
&
fields
,
bool
send_row
,
uint
select_options
,
const
char
*
info
,
Item
*
having
,
Procedure
*
proc
,
SELECT_LEX_UNIT
*
unit
);
List
<
Item
>
&
fields
,
bool
send_row
,
uint
select_options
,
const
char
*
info
,
Item
*
having
);
static
COND
*
build_equal_items
(
THD
*
thd
,
COND
*
cond
,
COND_EQUAL
*
inherited
,
List
<
TABLE_LIST
>
*
join_list
,
...
...
@@ -1227,8 +1226,7 @@ JOIN::exec()
send_row_on_empty_set
(),
select_options
,
zero_result_cause
,
having
,
procedure
,
unit
);
having
);
DBUG_VOID_RETURN
;
}
...
...
@@ -1437,7 +1435,7 @@ JOIN::exec()
DBUG_VOID_RETURN
;
}
end_read_record
(
&
curr_join
->
join_tab
->
read_record
);
curr_join
->
const_tables
=
curr_join
->
tables
;
// Mark free for
join_free
()
curr_join
->
const_tables
=
curr_join
->
tables
;
// Mark free for
cleanup
()
curr_join
->
join_tab
[
0
].
table
=
0
;
// Table is freed
// No sum funcs anymore
...
...
@@ -1667,9 +1665,9 @@ JOIN::exec()
*/
int
JOIN
::
cleanup
()
JOIN
::
destroy
()
{
DBUG_ENTER
(
"JOIN::
cleanup
"
);
DBUG_ENTER
(
"JOIN::
destroy
"
);
select_lex
->
join
=
0
;
if
(
tmp_join
)
...
...
@@ -1684,12 +1682,11 @@ JOIN::cleanup()
}
tmp_join
->
tmp_join
=
0
;
tmp_table_param
.
copy_field
=
0
;
DBUG_RETURN
(
tmp_join
->
cleanup
());
DBUG_RETURN
(
tmp_join
->
destroy
());
}
cond_equal
=
0
;
lock
=
0
;
// It's faster to unlock later
join_free
(
1
);
cleanup
(
1
);
if
(
exec_tmp_table1
)
free_tmp_table
(
thd
,
exec_tmp_table1
);
if
(
exec_tmp_table2
)
...
...
@@ -1697,12 +1694,6 @@ JOIN::cleanup()
delete
select
;
delete_dynamic
(
&
keyuse
);
delete
procedure
;
for
(
SELECT_LEX_UNIT
*
lex_unit
=
select_lex
->
first_inner_unit
();
lex_unit
!=
0
;
lex_unit
=
lex_unit
->
next_unit
())
{
error
|=
lex_unit
->
cleanup
();
}
DBUG_RETURN
(
error
);
}
...
...
@@ -1885,17 +1876,14 @@ Cursor::close()
THD
*
thd
=
join
->
thd
;
DBUG_ENTER
(
"Cursor::close"
);
join
->
join_free
(
0
);
/*
In case of UNIONs JOIN is freed inside of unit->cleanup(),
otherwise in select_lex->cleanup().
*/
if
(
unit
)
{
/* In case of UNIONs JOIN is freed inside unit->cleanup() */
unit
->
cleanup
();
}
(
void
)
unit
->
cleanup
();
else
{
join
->
cleanup
();
delete
join
;
}
(
void
)
join
->
select_lex
->
cleanup
();
{
/* XXX: Another hack: closing tables used in the cursor */
DBUG_ASSERT
(
lock
||
open_tables
||
derived_tables
);
...
...
@@ -2071,8 +2059,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array,
if
(
free_join
)
{
thd
->
proc_info
=
"end"
;
err
=
join
->
cleanup
();
delete
join
;
err
=
select_lex
->
cleanup
();
DBUG_RETURN
(
err
||
thd
->
net
.
report_error
);
}
DBUG_RETURN
(
join
->
error
);
...
...
@@ -5905,29 +5892,75 @@ void JOIN_TAB::cleanup()
}
void
JOIN
::
join_free
(
bool
full
)
{
SELECT_LEX_UNIT
*
unit
;
SELECT_LEX
*
sl
;
DBUG_ENTER
(
"JOIN::join_free"
);
/*
Optimization: if not EXPLAIN and we are done with the JOIN,
free all tables.
*/
full
=
full
||
(
!
select_lex
->
uncacheable
&&
!
thd
->
lex
->
subqueries
&&
!
thd
->
lex
->
describe
);
cleanup
(
full
);
for
(
unit
=
select_lex
->
first_inner_unit
();
unit
;
unit
=
unit
->
next_unit
())
for
(
sl
=
unit
->
first_select_in_union
();
sl
;
sl
=
sl
->
next_select
())
{
JOIN
*
join
=
sl
->
join
;
if
(
join
)
{
/* Check that we don't occasionally clean up an uncacheable JOIN */
#if 0
DBUG_ASSERT(! (!select_lex->uncacheable && sl->uncacheable));
#endif
join
->
join_free
(
full
);
}
}
/*
We are not using tables anymore
Unlock all tables. We may be in an INSERT .... SELECT statement.
*/
if
(
full
&&
lock
&&
thd
->
lock
&&
!
(
select_options
&
SELECT_NO_UNLOCK
)
&&
!
select_lex
->
subquery_in_having
&&
(
select_lex
==
(
thd
->
lex
->
unit
.
fake_select_lex
?
thd
->
lex
->
unit
.
fake_select_lex
:
&
thd
->
lex
->
select_lex
)))
{
/*
TODO: unlock tables even if the join isn't top level select in the
tree.
*/
mysql_unlock_read_tables
(
thd
,
lock
);
// Don't free join->lock
lock
=
0
;
}
DBUG_VOID_RETURN
;
}
/*
Free resources of given join
SYNOPSIS
JOIN::
join_free
()
JOIN::
cleanup
()
fill - true if we should free all resources, call with full==1 should be
last, before it this function can be called with full==0
NOTE: with subquery this function definitely will be called several times,
but even for simple query it can be called several times.
*/
void
JOIN
::
join_free
(
bool
full
)
{
JOIN_TAB
*
tab
,
*
end
;
DBUG_ENTER
(
"JOIN::join_free"
);
full
=
full
||
(
!
select_lex
->
uncacheable
&&
!
thd
->
lex
->
subqueries
&&
!
thd
->
lex
->
describe
);
// do not cleanup too early on EXPLAIN
void
JOIN
::
cleanup
(
bool
full
)
{
DBUG_ENTER
(
"JOIN::cleanup"
);
if
(
table
)
{
JOIN_TAB
*
tab
,
*
end
;
/*
Only a sorted table may be cached. This sorted table is always the
first non const table in join->table
...
...
@@ -5938,16 +5971,6 @@ JOIN::join_free(bool full)
filesort_free_buffers
(
table
[
const_tables
]);
}
for
(
SELECT_LEX_UNIT
*
unit
=
select_lex
->
first_inner_unit
();
unit
;
unit
=
unit
->
next_unit
())
{
JOIN
*
join
;
for
(
SELECT_LEX
*
sl
=
unit
->
first_select_in_union
();
sl
;
sl
=
sl
->
next_select
())
if
((
join
=
sl
->
join
))
join
->
join_free
(
full
);
}
if
(
full
)
{
for
(
tab
=
join_tab
,
end
=
tab
+
tables
;
tab
!=
end
;
tab
++
)
...
...
@@ -5964,23 +5987,10 @@ JOIN::join_free(bool full)
}
}
}
/*
We are not using tables anymore
Unlock all tables. We may be in an INSERT .... SELECT statement.
*/
if
(
full
&&
lock
&&
thd
->
lock
&&
!
(
select_options
&
SELECT_NO_UNLOCK
)
&&
!
select_lex
->
subquery_in_having
)
{
// TODO: unlock tables even if the join isn't top level select in the tree
if
(
select_lex
==
(
thd
->
lex
->
unit
.
fake_select_lex
?
thd
->
lex
->
unit
.
fake_select_lex
:
&
thd
->
lex
->
select_lex
))
{
mysql_unlock_read_tables
(
thd
,
lock
);
// Don't free join->lock
lock
=
0
;
}
}
if
(
full
)
{
group_fields
.
delete_elements
();
...
...
@@ -6217,8 +6227,7 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond,
static
int
return_zero_rows
(
JOIN
*
join
,
select_result
*
result
,
TABLE_LIST
*
tables
,
List
<
Item
>
&
fields
,
bool
send_row
,
uint
select_options
,
const
char
*
info
,
Item
*
having
,
Procedure
*
procedure
,
SELECT_LEX_UNIT
*
unit
)
const
char
*
info
,
Item
*
having
)
{
DBUG_ENTER
(
"return_zero_rows"
);
...
...
sql/sql_select.h
View file @
aa300fa7
...
...
@@ -325,7 +325,7 @@ class JOIN :public Sql_alloc
int
optimize
();
int
reinit
();
void
exec
();
int
cleanup
();
int
destroy
();
void
restore_tmp
();
bool
alloc_func_list
();
bool
make_sum_func_list
(
List
<
Item
>
&
all_fields
,
List
<
Item
>
&
send_fields
,
...
...
@@ -349,7 +349,15 @@ class JOIN :public Sql_alloc
int
rollup_send_data
(
uint
idx
);
int
rollup_write_data
(
uint
idx
,
TABLE
*
table
);
bool
test_in_subselect
(
Item
**
where
);
/*
Release memory and, if possible, the open tables held by this execution
plan (and nested plans). It's used to release some tables before
the end of execution in order to increase concurrency and reduce
memory consumption.
*/
void
join_free
(
bool
full
);
/* Cleanup this JOIN, possibly for reuse */
void
cleanup
(
bool
full
);
void
clear
();
bool
save_join_tab
();
bool
send_row_on_empty_set
()
...
...
sql/sql_union.cc
View file @
aa300fa7
...
...
@@ -553,7 +553,6 @@ bool st_select_lex_unit::exec()
bool
st_select_lex_unit
::
cleanup
()
{
int
error
=
0
;
JOIN
*
join
;
DBUG_ENTER
(
"st_select_lex_unit::cleanup"
);
if
(
cleaned
)
...
...
@@ -572,29 +571,17 @@ bool st_select_lex_unit::cleanup()
}
for
(
SELECT_LEX
*
sl
=
first_select_in_union
();
sl
;
sl
=
sl
->
next_select
())
error
|=
sl
->
cleanup
();
if
(
fake_select_lex
)
{
if
((
join
=
sl
->
join
))
{
error
|=
sl
->
join
->
cleanup
();
delete
join
;
}
else
JOIN
*
join
;
if
((
join
=
fake_select_lex
->
join
))
{
// it can be DO/SET with subqueries
for
(
SELECT_LEX_UNIT
*
lex_unit
=
sl
->
first_inner_unit
();
lex_unit
!=
0
;
lex_unit
=
lex_unit
->
next_unit
())
{
error
|=
lex_unit
->
cleanup
();
}
join
->
tables_list
=
0
;
join
->
tables
=
0
;
}
}
if
(
fake_select_lex
&&
(
join
=
fake_select_lex
->
join
))
{
join
->
tables_list
=
0
;
join
->
tables
=
0
;
error
|=
join
->
cleanup
();
delete
join
;
error
|=
fake_select_lex
->
cleanup
();
}
DBUG_RETURN
(
error
);
...
...
@@ -650,3 +637,24 @@ bool st_select_lex_unit::change_result(select_subselect *result,
res
=
fake_select_lex
->
join
->
change_result
(
result
);
return
(
res
);
}
bool
st_select_lex
::
cleanup
()
{
bool
error
=
FALSE
;
DBUG_ENTER
(
"st_select_lex::cleanup()"
);
if
(
join
)
{
error
|=
join
->
destroy
();
delete
join
;
join
=
0
;
}
for
(
SELECT_LEX_UNIT
*
lex_unit
=
first_inner_unit
();
lex_unit
;
lex_unit
=
lex_unit
->
next_unit
())
{
error
|=
lex_unit
->
cleanup
();
}
DBUG_RETURN
(
error
);
}
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