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
5de770f3
Commit
5de770f3
authored
Mar 27, 2011
by
Sergey Petrunya
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MWL#90: Address review feedback part #14
parent
290a72d5
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
139 additions
and
96 deletions
+139
-96
sql/item_subselect.cc
sql/item_subselect.cc
+3
-3
sql/opt_range.cc
sql/opt_range.cc
+2
-2
sql/opt_subselect.cc
sql/opt_subselect.cc
+29
-20
sql/sql_cursor.cc
sql/sql_cursor.cc
+4
-4
sql/sql_delete.cc
sql/sql_delete.cc
+4
-3
sql/sql_select.cc
sql/sql_select.cc
+87
-60
sql/sql_select.h
sql/sql_select.h
+9
-3
sql/sql_union.cc
sql/sql_union.cc
+1
-1
No files found.
sql/item_subselect.cc
View file @
5de770f3
...
@@ -2316,7 +2316,7 @@ bool Item_in_subselect::init_left_expr_cache()
...
@@ -2316,7 +2316,7 @@ bool Item_in_subselect::init_left_expr_cache()
An IN predicate might be evaluated in a query for which all tables have
An IN predicate might be evaluated in a query for which all tables have
been optimzied away.
been optimzied away.
*/
*/
if
(
!
outer_join
||
!
outer_join
->
table
s
||
!
outer_join
->
tables_list
)
if
(
!
outer_join
||
!
outer_join
->
table
_count
||
!
outer_join
->
tables_list
)
return
TRUE
;
return
TRUE
;
if
(
!
(
left_expr_cache
=
new
List
<
Cached_item
>
))
if
(
!
(
left_expr_cache
=
new
List
<
Cached_item
>
))
...
@@ -2701,9 +2701,9 @@ int subselect_single_select_engine::exec()
...
@@ -2701,9 +2701,9 @@ int subselect_single_select_engine::exec()
pushed down into the subquery. Those optimizations are ref[_or_null]
pushed down into the subquery. Those optimizations are ref[_or_null]
acceses. Change them to be full table scans.
acceses. Change them to be full table scans.
*/
*/
for
(
uint
i
=
join
->
const_tables
;
i
<
join
->
tables
;
i
++
)
for
(
JOIN_TAB
*
tab
=
first_linear_tab
(
join
,
WITHOUT_CONST_TABLES
);
tab
;
tab
=
next_linear_tab
(
join
,
tab
,
WITH_BUSH_ROOTS
))
{
{
JOIN_TAB
*
tab
=
join
->
join_tab
+
i
;
if
(
tab
&&
tab
->
keyuse
)
if
(
tab
&&
tab
->
keyuse
)
{
{
for
(
uint
i
=
0
;
i
<
tab
->
ref
.
key_parts
;
i
++
)
for
(
uint
i
=
0
;
i
<
tab
->
ref
.
key_parts
;
i
++
)
...
...
sql/opt_range.cc
View file @
5de770f3
...
@@ -4319,7 +4319,7 @@ double get_sweep_read_cost(const PARAM *param, ha_rows records)
...
@@ -4319,7 +4319,7 @@ double get_sweep_read_cost(const PARAM *param, ha_rows records)
return 1;
return 1;
*/
*/
JOIN
*
join
=
param
->
thd
->
lex
->
select_lex
.
join
;
JOIN
*
join
=
param
->
thd
->
lex
->
select_lex
.
join
;
if
(
!
join
||
join
->
table
s
==
1
)
if
(
!
join
||
join
->
table
_count
==
1
)
{
{
/* No join, assume reading is done in one 'sweep' */
/* No join, assume reading is done in one 'sweep' */
result
=
busy_blocks
*
(
DISK_SEEK_BASE_COST
+
result
=
busy_blocks
*
(
DISK_SEEK_BASE_COST
+
...
@@ -11270,7 +11270,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
...
@@ -11270,7 +11270,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
/* Perform few 'cheap' tests whether this access method is applicable. */
/* Perform few 'cheap' tests whether this access method is applicable. */
if
(
!
join
)
if
(
!
join
)
DBUG_RETURN
(
NULL
);
/* This is not a select statement. */
DBUG_RETURN
(
NULL
);
/* This is not a select statement. */
if
((
join
->
table
s
!=
1
)
||
/* The query must reference one table. */
if
((
join
->
table
_count
!=
1
)
||
/* The query must reference one table. */
((
!
join
->
group_list
)
&&
/* Neither GROUP BY nor a DISTINCT query. */
((
!
join
->
group_list
)
&&
/* Neither GROUP BY nor a DISTINCT query. */
(
!
join
->
select_distinct
))
||
(
!
join
->
select_distinct
))
||
(
join
->
select_lex
->
olap
==
ROLLUP_TYPE
))
/* Check (B3) for ROLLUP */
(
join
->
select_lex
->
olap
==
ROLLUP_TYPE
))
/* Check (B3) for ROLLUP */
...
...
sql/opt_subselect.cc
View file @
5de770f3
...
@@ -203,6 +203,9 @@ static bool sj_table_is_included(JOIN *join, JOIN_TAB *join_tab);
...
@@ -203,6 +203,9 @@ static bool sj_table_is_included(JOIN *join, JOIN_TAB *join_tab);
static
Item
*
remove_additional_cond
(
Item
*
conds
);
static
Item
*
remove_additional_cond
(
Item
*
conds
);
static
void
remove_subq_pushed_predicates
(
JOIN
*
join
,
Item
**
where
);
static
void
remove_subq_pushed_predicates
(
JOIN
*
join
,
Item
**
where
);
enum_nested_loop_state
end_sj_materialize
(
JOIN
*
join
,
JOIN_TAB
*
join_tab
,
bool
end_of_records
);
/*
/*
Check if we need JOIN::prepare()-phase subquery rewrites and if yes, do them
Check if we need JOIN::prepare()-phase subquery rewrites and if yes, do them
...
@@ -644,7 +647,7 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
...
@@ -644,7 +647,7 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
{
{
st_select_lex
*
child_select
=
(
*
in_subq
)
->
get_select_lex
();
st_select_lex
*
child_select
=
(
*
in_subq
)
->
get_select_lex
();
JOIN
*
child_join
=
child_select
->
join
;
JOIN
*
child_join
=
child_select
->
join
;
child_join
->
outer_tables
=
child_join
->
table
s
;
child_join
->
outer_tables
=
child_join
->
table
_count
;
/*
/*
child_select->where contains only the WHERE predicate of the
child_select->where contains only the WHERE predicate of the
...
@@ -693,15 +696,15 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
...
@@ -693,15 +696,15 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
bool
remove_item
=
TRUE
;
bool
remove_item
=
TRUE
;
if
((
*
in_subq
)
->
is_flattenable_semijoin
)
if
((
*
in_subq
)
->
is_flattenable_semijoin
)
{
{
if
(
join
->
table
s
+
if
(
join
->
table
_count
+
(
*
in_subq
)
->
unit
->
first_select
()
->
join
->
table
s
>=
MAX_TABLES
)
(
*
in_subq
)
->
unit
->
first_select
()
->
join
->
table
_count
>=
MAX_TABLES
)
break
;
break
;
if
(
convert_subq_to_sj
(
join
,
*
in_subq
))
if
(
convert_subq_to_sj
(
join
,
*
in_subq
))
DBUG_RETURN
(
TRUE
);
DBUG_RETURN
(
TRUE
);
}
}
else
else
{
{
if
(
join
->
table
s
+
1
>=
MAX_TABLES
)
if
(
join
->
table
_count
+
1
>=
MAX_TABLES
)
break
;
break
;
if
(
convert_subq_to_jtbm
(
join
,
*
in_subq
,
&
remove_item
))
if
(
convert_subq_to_jtbm
(
join
,
*
in_subq
,
&
remove_item
))
DBUG_RETURN
(
TRUE
);
DBUG_RETURN
(
TRUE
);
...
@@ -830,7 +833,8 @@ void get_delayed_table_estimates(TABLE *table,
...
@@ -830,7 +833,8 @@ void get_delayed_table_estimates(TABLE *table,
double
read_time
;
double
read_time
;
/* Calculate #rows and cost of join execution */
/* Calculate #rows and cost of join execution */
get_partial_join_cost
(
join
,
join
->
tables
-
join
->
const_tables
,
&
read_time
,
&
rows
);
get_partial_join_cost
(
join
,
join
->
table_count
-
join
->
const_tables
,
&
read_time
,
&
rows
);
*
out_rows
=
(
ha_rows
)
rows
;
*
out_rows
=
(
ha_rows
)
rows
;
*
startup_cost
=
read_time
;
*
startup_cost
=
read_time
;
...
@@ -1097,8 +1101,8 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
...
@@ -1097,8 +1101,8 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
subq_pred
->
exec_method
=
Item_in_subselect
::
SEMI_JOIN
;
// for subsequent executions
subq_pred
->
exec_method
=
Item_in_subselect
::
SEMI_JOIN
;
// for subsequent executions
/*TODO: also reset the 'with_subselect' there. */
/*TODO: also reset the 'with_subselect' there. */
/* n. Adjust the parent_join->table
s
counter */
/* n. Adjust the parent_join->table
_count
counter */
uint
table_no
=
parent_join
->
table
s
;
uint
table_no
=
parent_join
->
table
_count
;
/* n. Walk through child's tables and adjust table->map */
/* n. Walk through child's tables and adjust table->map */
for
(
tl
=
subq_lex
->
leaf_tables
;
tl
;
tl
=
tl
->
next_leaf
,
table_no
++
)
for
(
tl
=
subq_lex
->
leaf_tables
;
tl
;
tl
=
tl
->
next_leaf
,
table_no
++
)
{
{
...
@@ -1111,7 +1115,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
...
@@ -1111,7 +1115,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
emb
=
emb
->
embedding
)
emb
=
emb
->
embedding
)
emb
->
select_lex
=
parent_join
->
select_lex
;
emb
->
select_lex
=
parent_join
->
select_lex
;
}
}
parent_join
->
table
s
+=
subq_lex
->
join
->
tables
;
parent_join
->
table
_count
+=
subq_lex
->
join
->
table_count
;
/*
/*
Put the subquery's WHERE into semi-join's sj_on_expr
Put the subquery's WHERE into semi-join's sj_on_expr
...
@@ -1300,11 +1304,11 @@ static bool convert_subq_to_jtbm(JOIN *parent_join,
...
@@ -1300,11 +1304,11 @@ static bool convert_subq_to_jtbm(JOIN *parent_join,
((
subselect_hash_sj_engine
*
)
subq_pred
->
engine
);
((
subselect_hash_sj_engine
*
)
subq_pred
->
engine
);
jtbm
->
table
=
hash_sj_engine
->
tmp_table
;
jtbm
->
table
=
hash_sj_engine
->
tmp_table
;
jtbm
->
table
->
tablenr
=
parent_join
->
table
s
;
jtbm
->
table
->
tablenr
=
parent_join
->
table
_count
;
jtbm
->
table
->
map
=
table_map
(
1
)
<<
(
parent_join
->
table
s
);
jtbm
->
table
->
map
=
table_map
(
1
)
<<
(
parent_join
->
table
_count
);
parent_join
->
table
s
++
;
parent_join
->
table
_count
++
;
DBUG_ASSERT
(
parent_join
->
table
s
<
MAX_TABLES
);
DBUG_ASSERT
(
parent_join
->
table
_count
<
MAX_TABLES
);
Item
*
conds
=
hash_sj_engine
->
semi_join_conds
;
Item
*
conds
=
hash_sj_engine
->
semi_join_conds
;
conds
->
fix_after_pullout
(
parent_lex
,
&
conds
);
conds
->
fix_after_pullout
(
parent_lex
,
&
conds
);
...
@@ -2479,7 +2483,7 @@ at_sjmat_pos(const JOIN *join, table_map remaining_tables, const JOIN_TAB *tab,
...
@@ -2479,7 +2483,7 @@ at_sjmat_pos(const JOIN *join, table_map remaining_tables, const JOIN_TAB *tab,
void
fix_semijoin_strategies_for_picked_join_order
(
JOIN
*
join
)
void
fix_semijoin_strategies_for_picked_join_order
(
JOIN
*
join
)
{
{
uint
table_count
=
join
->
table
s
;
uint
table_count
=
join
->
table
_count
;
uint
tablenr
;
uint
tablenr
;
table_map
remaining_tables
=
0
;
table_map
remaining_tables
=
0
;
table_map
handled_tabs
=
0
;
table_map
handled_tabs
=
0
;
...
@@ -2643,8 +2647,6 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
...
@@ -2643,8 +2647,6 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
}
}
}
}
enum_nested_loop_state
end_sj_materialize
(
JOIN
*
join
,
JOIN_TAB
*
join_tab
,
bool
end_of_records
);
/*
/*
Setup semi-join materialization strategy for one semi-join nest
Setup semi-join materialization strategy for one semi-join nest
...
@@ -3505,6 +3507,7 @@ int do_sj_dups_weedout(THD *thd, SJ_TMP_TABLE *sjtbl)
...
@@ -3505,6 +3507,7 @@ int do_sj_dups_weedout(THD *thd, SJ_TMP_TABLE *sjtbl)
FALSE OK
FALSE OK
TRUE Out of memory error
TRUE Out of memory error
*/
*/
JOIN_TAB
*
first_linear_tab
(
JOIN
*
join
,
enum
enum_with_const_tables
const_tbls
);
int
setup_semijoin_dups_elimination
(
JOIN
*
join
,
ulonglong
options
,
int
setup_semijoin_dups_elimination
(
JOIN
*
join
,
ulonglong
options
,
uint
no_jbuf_after
)
uint
no_jbuf_after
)
...
@@ -3512,17 +3515,19 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
...
@@ -3512,17 +3515,19 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
uint
i
;
uint
i
;
THD
*
thd
=
join
->
thd
;
THD
*
thd
=
join
->
thd
;
DBUG_ENTER
(
"setup_semijoin_dups_elimination"
);
DBUG_ENTER
(
"setup_semijoin_dups_elimination"
);
for
(
i
=
join
->
const_tables
;
i
<
join
->
tables
;
)
POSITION
*
pos
=
join
->
best_positions
+
join
->
const_tables
;
for
(
i
=
join
->
const_tables
;
i
<
join
->
top_jtrange_tables
;
)
{
{
JOIN_TAB
*
tab
=
join
->
join_tab
+
i
;
JOIN_TAB
*
tab
=
join
->
join_tab
+
i
;
POSITION
*
pos
=
join
->
best_positions
+
i
;
//
POSITION *pos= join->best_positions + i;
uint
keylen
,
keyno
;
uint
keylen
,
keyno
;
switch
(
pos
->
sj_strategy
)
{
switch
(
pos
->
sj_strategy
)
{
case
SJ_OPT_MATERIALIZE
:
case
SJ_OPT_MATERIALIZE
:
case
SJ_OPT_MATERIALIZE_SCAN
:
case
SJ_OPT_MATERIALIZE_SCAN
:
/* Do nothing */
/* Do nothing */
i
+=
pos
->
n_sj_tables
;
i
+=
1
;
// It used to be pos->n_sj_tables, but now they are embedded in a nest
pos
+=
pos
->
n_sj_tables
;
break
;
break
;
case
SJ_OPT_LOOSE_SCAN
:
case
SJ_OPT_LOOSE_SCAN
:
{
{
...
@@ -3539,6 +3544,7 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
...
@@ -3539,6 +3544,7 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
if
(
pos
->
n_sj_tables
>
1
)
if
(
pos
->
n_sj_tables
>
1
)
tab
[
pos
->
n_sj_tables
-
1
].
do_firstmatch
=
tab
;
tab
[
pos
->
n_sj_tables
-
1
].
do_firstmatch
=
tab
;
i
+=
pos
->
n_sj_tables
;
i
+=
pos
->
n_sj_tables
;
pos
+=
pos
->
n_sj_tables
;
break
;
break
;
}
}
case
SJ_OPT_DUPS_WEEDOUT
:
case
SJ_OPT_DUPS_WEEDOUT
:
...
@@ -3636,6 +3642,7 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
...
@@ -3636,6 +3642,7 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
join
->
join_tab
[
i
+
pos
->
n_sj_tables
-
1
].
check_weed_out_table
=
sjtbl
;
join
->
join_tab
[
i
+
pos
->
n_sj_tables
-
1
].
check_weed_out_table
=
sjtbl
;
i
+=
pos
->
n_sj_tables
;
i
+=
pos
->
n_sj_tables
;
pos
+=
pos
->
n_sj_tables
;
break
;
break
;
}
}
case
SJ_OPT_FIRST_MATCH
:
case
SJ_OPT_FIRST_MATCH
:
...
@@ -3658,10 +3665,12 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
...
@@ -3658,10 +3665,12 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
}
}
j
[
-
1
].
do_firstmatch
=
jump_to
;
j
[
-
1
].
do_firstmatch
=
jump_to
;
i
+=
pos
->
n_sj_tables
;
i
+=
pos
->
n_sj_tables
;
pos
+=
pos
->
n_sj_tables
;
break
;
break
;
}
}
case
SJ_OPT_NONE
:
case
SJ_OPT_NONE
:
i
++
;
i
++
;
pos
++
;
break
;
break
;
}
}
}
}
...
@@ -3848,7 +3857,7 @@ int rewrite_to_index_subquery_engine(JOIN *join)
...
@@ -3848,7 +3857,7 @@ int rewrite_to_index_subquery_engine(JOIN *join)
if
(
!
join
->
group_list
&&
!
join
->
order
&&
if
(
!
join
->
group_list
&&
!
join
->
order
&&
join
->
unit
->
item
&&
join
->
unit
->
item
&&
join
->
unit
->
item
->
substype
()
==
Item_subselect
::
IN_SUBS
&&
join
->
unit
->
item
->
substype
()
==
Item_subselect
::
IN_SUBS
&&
join
->
table
s
==
1
&&
join
->
conds
&&
join
->
table
_count
==
1
&&
join
->
conds
&&
!
join
->
unit
->
is_union
())
!
join
->
unit
->
is_union
())
{
{
if
(
!
join
->
having
)
if
(
!
join
->
having
)
...
...
sql/sql_cursor.cc
View file @
5de770f3
...
@@ -381,14 +381,14 @@ Sensitive_cursor::open(JOIN *join_arg)
...
@@ -381,14 +381,14 @@ Sensitive_cursor::open(JOIN *join_arg)
/* Prepare JOIN for reading rows. */
/* Prepare JOIN for reading rows. */
join
->
tmp_table
=
0
;
join
->
tmp_table
=
0
;
join
->
join_tab
[
join
->
t
ables
-
1
].
next_select
=
setup_end_select_func
(
join
);
join
->
join_tab
[
join
->
t
op_jtrange_tables
-
1
].
next_select
=
setup_end_select_func
(
join
);
join
->
send_records
=
0
;
join
->
send_records
=
0
;
join
->
fetch_limit
=
join
->
unit
->
offset_limit_cnt
;
join
->
fetch_limit
=
join
->
unit
->
offset_limit_cnt
;
/* Disable JOIN CACHE as it is not working with cursors yet */
/* Disable JOIN CACHE as it is not working with cursors yet */
for
(
JOIN_TAB
*
tab
=
join_tab
;
for
(
JOIN_TAB
*
tab
=
first_linear_tab
(
join
,
WITHOUT_CONST_TABLES
);
tab
!=
join
->
join_tab
+
join
->
tables
-
1
;
tab
!=
join
->
join_tab
+
join
->
t
op_jtrange_t
ables
-
1
;
tab
++
)
tab
=
next_linear_tab
(
join
,
tab
,
WITH_BUSH_ROOTS
)
)
{
{
if
(
tab
->
next_select
==
sub_select_cache
)
if
(
tab
->
next_select
==
sub_select_cache
)
tab
->
next_select
=
sub_select
;
tab
->
next_select
=
sub_select
;
...
...
sql/sql_delete.cc
View file @
5de770f3
...
@@ -677,9 +677,10 @@ multi_delete::initialize_tables(JOIN *join)
...
@@ -677,9 +677,10 @@ multi_delete::initialize_tables(JOIN *join)
walk
=
delete_tables
;
walk
=
delete_tables
;
for
(
JOIN_TAB
*
tab
=
join
->
join_tab
,
*
end
=
join
->
join_tab
+
join
->
tables
;
tab
<
end
;
for
(
JOIN_TAB
*
tab
=
first_linear_tab
(
join
,
WITH_CONST_TABLES
);
tab
++
)
tab
;
tab
=
next_linear_tab
(
join
,
tab
,
WITH_BUSH_ROOTS
))
{
{
if
(
tab
->
table
->
map
&
tables_to_delete_from
)
if
(
tab
->
table
->
map
&
tables_to_delete_from
)
{
{
...
...
sql/sql_select.cc
View file @
5de770f3
...
@@ -520,7 +520,7 @@ JOIN::prepare(Item ***rref_pointer_array,
...
@@ -520,7 +520,7 @@ JOIN::prepare(Item ***rref_pointer_array,
for
(
table_ptr
=
select_lex
->
leaf_tables
;
for
(
table_ptr
=
select_lex
->
leaf_tables
;
table_ptr
;
table_ptr
;
table_ptr
=
table_ptr
->
next_leaf
)
table_ptr
=
table_ptr
->
next_leaf
)
table
s
++
;
table
_count
++
;
if
(
setup_wild
(
thd
,
tables_list
,
fields_list
,
&
all_fields
,
wild_num
)
||
if
(
setup_wild
(
thd
,
tables_list
,
fields_list
,
&
all_fields
,
wild_num
)
||
select_lex
->
setup_ref_array
(
thd
,
og_num
)
||
select_lex
->
setup_ref_array
(
thd
,
og_num
)
||
...
@@ -840,7 +840,7 @@ JOIN::optimize()
...
@@ -840,7 +840,7 @@ JOIN::optimize()
"Impossible HAVING"
:
"Impossible WHERE"
));
"Impossible HAVING"
:
"Impossible WHERE"
));
zero_result_cause
=
having_value
==
Item
::
COND_FALSE
?
zero_result_cause
=
having_value
==
Item
::
COND_FALSE
?
"Impossible HAVING"
:
"Impossible WHERE"
;
"Impossible HAVING"
:
"Impossible WHERE"
;
table
s
=
0
;
table
_count
=
0
;
error
=
0
;
error
=
0
;
goto
setup_subq_exit
;
goto
setup_subq_exit
;
}
}
...
@@ -890,7 +890,7 @@ JOIN::optimize()
...
@@ -890,7 +890,7 @@ JOIN::optimize()
{
{
DBUG_PRINT
(
"info"
,(
"No matching min/max row"
));
DBUG_PRINT
(
"info"
,(
"No matching min/max row"
));
zero_result_cause
=
"No matching min/max row"
;
zero_result_cause
=
"No matching min/max row"
;
table
s
=
0
;
table
_count
=
0
;
error
=
0
;
error
=
0
;
goto
setup_subq_exit
;
goto
setup_subq_exit
;
}
}
...
@@ -904,14 +904,14 @@ JOIN::optimize()
...
@@ -904,14 +904,14 @@ JOIN::optimize()
{
{
DBUG_PRINT
(
"info"
,(
"No matching min/max row"
));
DBUG_PRINT
(
"info"
,(
"No matching min/max row"
));
zero_result_cause
=
"No matching min/max row"
;
zero_result_cause
=
"No matching min/max row"
;
table
s
=
0
;
table
_count
=
0
;
error
=
0
;
error
=
0
;
goto
setup_subq_exit
;
goto
setup_subq_exit
;
}
}
DBUG_PRINT
(
"info"
,(
"Select tables optimized away"
));
DBUG_PRINT
(
"info"
,(
"Select tables optimized away"
));
zero_result_cause
=
"Select tables optimized away"
;
zero_result_cause
=
"Select tables optimized away"
;
tables_list
=
0
;
// All tables resolved
tables_list
=
0
;
// All tables resolved
const_tables
=
table
s
;
const_tables
=
table
_count
;
/*
/*
Extract all table-independent conditions and replace the WHERE
Extract all table-independent conditions and replace the WHERE
clause with them. All other conditions were computed by opt_sum_query
clause with them. All other conditions were computed by opt_sum_query
...
@@ -967,7 +967,7 @@ JOIN::optimize()
...
@@ -967,7 +967,7 @@ JOIN::optimize()
else
else
{
{
/* Remove distinct if only const tables */
/* Remove distinct if only const tables */
select_distinct
=
select_distinct
&&
(
const_tables
!=
table
s
);
select_distinct
=
select_distinct
&&
(
const_tables
!=
table
_count
);
}
}
thd_proc_info
(
thd
,
"preparing"
);
thd_proc_info
(
thd
,
"preparing"
);
...
@@ -1125,7 +1125,7 @@ JOIN::optimize()
...
@@ -1125,7 +1125,7 @@ JOIN::optimize()
The FROM clause must contain a single non-constant table.
The FROM clause must contain a single non-constant table.
*/
*/
if
(
table
s
-
const_tables
==
1
&&
(
group_list
||
select_distinct
)
&&
if
(
table
_count
-
const_tables
==
1
&&
(
group_list
||
select_distinct
)
&&
!
tmp_table_param
.
sum_func_count
&&
!
tmp_table_param
.
sum_func_count
&&
(
!
join_tab
[
const_tables
].
select
||
(
!
join_tab
[
const_tables
].
select
||
!
join_tab
[
const_tables
].
select
->
quick
||
!
join_tab
[
const_tables
].
select
->
quick
||
...
@@ -1176,7 +1176,7 @@ JOIN::optimize()
...
@@ -1176,7 +1176,7 @@ JOIN::optimize()
if
(
!
hidden_group_fields
&&
rollup
.
state
==
ROLLUP
::
STATE_NONE
)
if
(
!
hidden_group_fields
&&
rollup
.
state
==
ROLLUP
::
STATE_NONE
)
select_distinct
=
0
;
select_distinct
=
0
;
}
}
else
if
(
select_distinct
&&
table
s
-
const_tables
==
1
&&
else
if
(
select_distinct
&&
table
_count
-
const_tables
==
1
&&
rollup
.
state
==
ROLLUP
::
STATE_NONE
)
rollup
.
state
==
ROLLUP
::
STATE_NONE
)
{
{
/*
/*
...
@@ -1305,7 +1305,7 @@ JOIN::optimize()
...
@@ -1305,7 +1305,7 @@ JOIN::optimize()
When the WITH ROLLUP modifier is present, we cannot skip temporary table
When the WITH ROLLUP modifier is present, we cannot skip temporary table
creation for the DISTINCT clause just because there are only const tables.
creation for the DISTINCT clause just because there are only const tables.
*/
*/
need_tmp
=
((
const_tables
!=
table
s
&&
need_tmp
=
((
const_tables
!=
table
_count
&&
((
select_distinct
||
!
simple_order
||
!
simple_group
)
||
((
select_distinct
||
!
simple_order
||
!
simple_group
)
||
(
group_list
&&
order
)
||
(
group_list
&&
order
)
||
test
(
select_options
&
OPTION_BUFFER_RESULT
)))
||
test
(
select_options
&
OPTION_BUFFER_RESULT
)))
||
...
@@ -1319,7 +1319,7 @@ JOIN::optimize()
...
@@ -1319,7 +1319,7 @@ JOIN::optimize()
Yet the current implementation of FORCE INDEX hints does not
Yet the current implementation of FORCE INDEX hints does not
allow us to do it in a clean manner.
allow us to do it in a clean manner.
*/
*/
no_jbuf_after
=
1
?
table
s
:
make_join_orderinfo
(
this
);
no_jbuf_after
=
1
?
table
_count
:
make_join_orderinfo
(
this
);
select_opts_for_readinfo
=
select_opts_for_readinfo
=
(
select_options
&
(
SELECT_DESCRIBE
|
SELECT_NO_JOIN_CACHE
))
|
(
select_options
&
(
SELECT_DESCRIBE
|
SELECT_NO_JOIN_CACHE
))
|
...
@@ -1351,7 +1351,7 @@ JOIN::optimize()
...
@@ -1351,7 +1351,7 @@ JOIN::optimize()
*/
*/
if
(
need_tmp
||
select_distinct
||
group_list
||
order
)
if
(
need_tmp
||
select_distinct
||
group_list
||
order
)
{
{
for
(
uint
i
=
0
;
i
<
table
s
;
i
++
)
for
(
uint
i
=
0
;
i
<
table
_count
;
i
++
)
{
{
if
(
!
(
table
[
i
]
->
map
&
const_table_map
))
if
(
!
(
table
[
i
]
->
map
&
const_table_map
))
table
[
i
]
->
prepare_for_position
();
table
[
i
]
->
prepare_for_position
();
...
@@ -1360,7 +1360,7 @@ JOIN::optimize()
...
@@ -1360,7 +1360,7 @@ JOIN::optimize()
DBUG_EXECUTE
(
"info"
,
TEST_join
(
this
););
DBUG_EXECUTE
(
"info"
,
TEST_join
(
this
););
if
(
const_tables
!=
table
s
)
if
(
const_tables
!=
table
_count
)
{
{
/*
/*
Because filesort always does a full table scan or a quick range scan
Because filesort always does a full table scan or a quick range scan
...
@@ -1535,7 +1535,7 @@ JOIN::optimize()
...
@@ -1535,7 +1535,7 @@ JOIN::optimize()
if
(
exec_tmp_table1
->
distinct
)
if
(
exec_tmp_table1
->
distinct
)
{
{
table_map
used_tables
=
thd
->
used_tables
;
table_map
used_tables
=
thd
->
used_tables
;
JOIN_TAB
*
last_join_tab
=
join_tab
+
tables
-
1
;
JOIN_TAB
*
last_join_tab
=
join_tab
+
top_jtrange_tables
-
1
;
do
do
{
{
if
(
used_tables
&
last_join_tab
->
table
->
map
)
if
(
used_tables
&
last_join_tab
->
table
->
map
)
...
@@ -1761,12 +1761,17 @@ JOIN::reinit()
...
@@ -1761,12 +1761,17 @@ JOIN::reinit()
set_items_ref_array
(
items0
);
set_items_ref_array
(
items0
);
if
(
join_tab_save
)
if
(
join_tab_save
)
memcpy
(
join_tab
,
join_tab_save
,
sizeof
(
JOIN_TAB
)
*
table
s
);
memcpy
(
join_tab
,
join_tab_save
,
sizeof
(
JOIN_TAB
)
*
table
_count
);
/* need to reset ref access state (see join_read_key) */
/* need to reset ref access state (see join_read_key) */
if
(
join_tab
)
if
(
join_tab
)
for
(
uint
i
=
0
;
i
<
tables
;
i
++
)
{
join_tab
[
i
].
ref
.
key_err
=
TRUE
;
for
(
JOIN_TAB
*
tab
=
first_linear_tab
(
this
,
WITH_CONST_TABLES
);
tab
;
tab
=
next_linear_tab
(
this
,
tab
,
WITH_BUSH_ROOTS
))
{
tab
->
ref
.
key_err
=
TRUE
;
}
}
if
(
tmp_join
)
if
(
tmp_join
)
restore_tmp
();
restore_tmp
();
...
@@ -1823,7 +1828,7 @@ JOIN::save_join_tab()
...
@@ -1823,7 +1828,7 @@ JOIN::save_join_tab()
if
(
!
join_tab_save
&&
select_lex
->
master_unit
()
->
uncacheable
)
if
(
!
join_tab_save
&&
select_lex
->
master_unit
()
->
uncacheable
)
{
{
if
(
!
(
join_tab_save
=
(
JOIN_TAB
*
)
thd
->
memdup
((
uchar
*
)
join_tab
,
if
(
!
(
join_tab_save
=
(
JOIN_TAB
*
)
thd
->
memdup
((
uchar
*
)
join_tab
,
sizeof
(
JOIN_TAB
)
*
table
s
)))
sizeof
(
JOIN_TAB
)
*
table
_count
)))
return
1
;
return
1
;
}
}
return
0
;
return
0
;
...
@@ -1863,7 +1868,7 @@ JOIN::exec()
...
@@ -1863,7 +1868,7 @@ JOIN::exec()
}
}
(
void
)
result
->
prepare2
();
// Currently, this cannot fail.
(
void
)
result
->
prepare2
();
// Currently, this cannot fail.
if
(
!
tables_list
&&
(
table
s
||
!
select_lex
->
with_sum_func
))
if
(
!
tables_list
&&
(
table
_count
||
!
select_lex
->
with_sum_func
))
{
// Only test of functions
{
// Only test of functions
if
(
select_options
&
SELECT_DESCRIBE
)
if
(
select_options
&
SELECT_DESCRIBE
)
select_describe
(
this
,
FALSE
,
FALSE
,
FALSE
,
select_describe
(
this
,
FALSE
,
FALSE
,
FALSE
,
...
@@ -1916,7 +1921,7 @@ JOIN::exec()
...
@@ -1916,7 +1921,7 @@ JOIN::exec()
FOUND_ROWS() may be called. Never reset the examined row count here.
FOUND_ROWS() may be called. Never reset the examined row count here.
It must be accumulated from all join iterations of all join parts.
It must be accumulated from all join iterations of all join parts.
*/
*/
if
(
table
s
)
if
(
table
_count
)
thd
->
limit_found_rows
=
0
;
thd
->
limit_found_rows
=
0
;
if
(
zero_result_cause
)
if
(
zero_result_cause
)
...
@@ -1953,7 +1958,7 @@ JOIN::exec()
...
@@ -1953,7 +1958,7 @@ JOIN::exec()
}
}
if
(
order
&&
if
(
order
&&
(
order
!=
group_list
||
!
(
select_options
&
SELECT_BIG_RESULT
))
&&
(
order
!=
group_list
||
!
(
select_options
&
SELECT_BIG_RESULT
))
&&
(
const_tables
==
table
s
||
(
const_tables
==
table
_count
||
((
simple_order
||
skip_sort_order
)
&&
((
simple_order
||
skip_sort_order
)
&&
test_if_skip_sort_order
(
&
join_tab
[
const_tables
],
order
,
test_if_skip_sort_order
(
&
join_tab
[
const_tables
],
order
,
select_limit
,
0
,
select_limit
,
0
,
...
@@ -1964,7 +1969,7 @@ JOIN::exec()
...
@@ -1964,7 +1969,7 @@ JOIN::exec()
select_describe
(
this
,
need_tmp
,
select_describe
(
this
,
need_tmp
,
order
!=
0
&&
!
skip_sort_order
,
order
!=
0
&&
!
skip_sort_order
,
select_distinct
,
select_distinct
,
!
table
s
?
"No tables used"
:
NullS
);
!
table
_count
?
"No tables used"
:
NullS
);
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
...
@@ -1998,7 +2003,7 @@ JOIN::exec()
...
@@ -1998,7 +2003,7 @@ JOIN::exec()
thd_proc_info
(
thd
,
copy_to_tmp_table
);
thd_proc_info
(
thd
,
copy_to_tmp_table
);
DBUG_PRINT
(
"info"
,
(
"%s"
,
thd
->
proc_info
));
DBUG_PRINT
(
"info"
,
(
"%s"
,
thd
->
proc_info
));
if
(
!
curr_join
->
sort_and_group
&&
if
(
!
curr_join
->
sort_and_group
&&
curr_join
->
const_tables
!=
curr_join
->
table
s
)
curr_join
->
const_tables
!=
curr_join
->
table
_count
)
{
{
JOIN_TAB
*
first_tab
=
curr_join
->
join_tab
+
curr_join
->
const_tables
;
JOIN_TAB
*
first_tab
=
curr_join
->
join_tab
+
curr_join
->
const_tables
;
first_tab
->
sorted
=
test
(
first_tab
->
loosescan_match_tab
);
first_tab
->
sorted
=
test
(
first_tab
->
loosescan_match_tab
);
...
@@ -2169,7 +2174,7 @@ JOIN::exec()
...
@@ -2169,7 +2174,7 @@ JOIN::exec()
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
curr_join
->
group_list
=
0
;
curr_join
->
group_list
=
0
;
if
(
!
curr_join
->
sort_and_group
&&
if
(
!
curr_join
->
sort_and_group
&&
curr_join
->
const_tables
!=
curr_join
->
table
s
)
curr_join
->
const_tables
!=
curr_join
->
table
_count
)
{
{
JOIN_TAB
*
first_tab
=
curr_join
->
join_tab
+
curr_join
->
const_tables
;
JOIN_TAB
*
first_tab
=
curr_join
->
join_tab
+
curr_join
->
const_tables
;
first_tab
->
sorted
=
test
(
first_tab
->
loosescan_match_tab
);
first_tab
->
sorted
=
test
(
first_tab
->
loosescan_match_tab
);
...
@@ -2182,7 +2187,7 @@ JOIN::exec()
...
@@ -2182,7 +2187,7 @@ JOIN::exec()
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
end_read_record
(
&
curr_join
->
join_tab
->
read_record
);
end_read_record
(
&
curr_join
->
join_tab
->
read_record
);
curr_join
->
const_tables
=
curr_join
->
table
s
;
// Mark free for cleanup()
curr_join
->
const_tables
=
curr_join
->
table
_count
;
// Mark free for cleanup()
curr_join
->
join_tab
[
0
].
table
=
0
;
// Table is freed
curr_join
->
join_tab
[
0
].
table
=
0
;
// Table is freed
// No sum funcs anymore
// No sum funcs anymore
...
@@ -2385,7 +2390,7 @@ JOIN::exec()
...
@@ -2385,7 +2390,7 @@ JOIN::exec()
curr_join
->
group_list
?
TRUE
:
FALSE
))
curr_join
->
group_list
?
TRUE
:
FALSE
))
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
sortorder
=
curr_join
->
sortorder
;
sortorder
=
curr_join
->
sortorder
;
if
(
curr_join
->
const_tables
!=
curr_join
->
table
s
&&
if
(
curr_join
->
const_tables
!=
curr_join
->
table
_count
&&
!
curr_join
->
join_tab
[
curr_join
->
const_tables
].
table
->
sort
.
io_cache
)
!
curr_join
->
join_tab
[
curr_join
->
const_tables
].
table
->
sort
.
io_cache
)
{
{
/*
/*
...
@@ -2407,7 +2412,7 @@ JOIN::exec()
...
@@ -2407,7 +2412,7 @@ JOIN::exec()
curr_join
->
fields
=
curr_fields_list
;
curr_join
->
fields
=
curr_fields_list
;
curr_join
->
procedure
=
procedure
;
curr_join
->
procedure
=
procedure
;
if
(
is_top_level_join
()
&&
thd
->
cursor
&&
table
s
!=
const_tables
)
if
(
is_top_level_join
()
&&
thd
->
cursor
&&
table
_count
!=
const_tables
)
{
{
/*
/*
We are here if this is JOIN::exec for the last select of the main unit
We are here if this is JOIN::exec for the last select of the main unit
...
@@ -2474,9 +2479,11 @@ JOIN::destroy()
...
@@ -2474,9 +2479,11 @@ JOIN::destroy()
{
{
if
(
join_tab
!=
tmp_join
->
join_tab
)
if
(
join_tab
!=
tmp_join
->
join_tab
)
{
{
JOIN_TAB
*
tab
,
*
end
;
for
(
JOIN_TAB
*
tab
=
first_linear_tab
(
this
,
WITH_CONST_TABLES
);
tab
;
for
(
tab
=
join_tab
,
end
=
tab
+
tables
;
tab
!=
end
;
tab
++
)
tab
=
next_linear_tab
(
this
,
tab
,
WITH_BUSH_ROOTS
))
{
tab
->
cleanup
();
tab
->
cleanup
();
}
}
}
tmp_join
->
tmp_join
=
0
;
tmp_join
->
tmp_join
=
0
;
/*
/*
...
@@ -2801,7 +2808,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
...
@@ -2801,7 +2808,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
DBUG_ENTER
(
"make_join_statistics"
);
DBUG_ENTER
(
"make_join_statistics"
);
LINT_INIT
(
table
);
/* inited in all loops */
LINT_INIT
(
table
);
/* inited in all loops */
table_count
=
join
->
table
s
;
table_count
=
join
->
table
_count
;
stat
=
(
JOIN_TAB
*
)
join
->
thd
->
calloc
(
sizeof
(
JOIN_TAB
)
*
(
table_count
));
stat
=
(
JOIN_TAB
*
)
join
->
thd
->
calloc
(
sizeof
(
JOIN_TAB
)
*
(
table_count
));
stat_ref
=
(
JOIN_TAB
**
)
join
->
thd
->
alloc
(
sizeof
(
JOIN_TAB
*
)
*
MAX_TABLES
);
stat_ref
=
(
JOIN_TAB
**
)
join
->
thd
->
alloc
(
sizeof
(
JOIN_TAB
*
)
*
MAX_TABLES
);
...
@@ -2943,7 +2950,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
...
@@ -2943,7 +2950,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
{
{
if
(
s
->
dependent
&
s
->
table
->
map
)
if
(
s
->
dependent
&
s
->
table
->
map
)
{
{
join
->
table
s
=
0
;
// Don't use join->table
join
->
table
_count
=
0
;
// Don't use join->table
my_message
(
ER_WRONG_OUTER_JOIN
,
ER
(
ER_WRONG_OUTER_JOIN
),
MYF
(
0
));
my_message
(
ER_WRONG_OUTER_JOIN
,
ER
(
ER_WRONG_OUTER_JOIN
),
MYF
(
0
));
goto
error
;
goto
error
;
}
}
...
@@ -2952,7 +2959,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
...
@@ -2952,7 +2959,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
}
}
if
(
conds
||
outer_join
)
if
(
conds
||
outer_join
)
if
(
update_ref_and_keys
(
join
->
thd
,
keyuse_array
,
stat
,
join
->
table
s
,
if
(
update_ref_and_keys
(
join
->
thd
,
keyuse_array
,
stat
,
join
->
table
_count
,
conds
,
join
->
cond_equal
,
conds
,
join
->
cond_equal
,
~
outer_join
,
join
->
select_lex
,
&
sargables
))
~
outer_join
,
join
->
select_lex
,
&
sargables
))
goto
error
;
goto
error
;
...
@@ -3269,14 +3276,14 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
...
@@ -3269,14 +3276,14 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
join
->
const_tables
=
const_count
;
join
->
const_tables
=
const_count
;
join
->
found_const_table_map
=
found_const_table_map
;
join
->
found_const_table_map
=
found_const_table_map
;
if
(
join
->
const_tables
!=
join
->
table
s
)
if
(
join
->
const_tables
!=
join
->
table
_count
)
optimize_keyuse
(
join
,
keyuse_array
);
optimize_keyuse
(
join
,
keyuse_array
);
if
(
optimize_semijoin_nests
(
join
,
all_table_map
))
if
(
optimize_semijoin_nests
(
join
,
all_table_map
))
DBUG_RETURN
(
TRUE
);
/* purecov: inspected */
DBUG_RETURN
(
TRUE
);
/* purecov: inspected */
/* Find an optimal join order of the non-constant tables. */
/* Find an optimal join order of the non-constant tables. */
if
(
join
->
const_tables
!=
join
->
table
s
)
if
(
join
->
const_tables
!=
join
->
table
_count
)
{
{
if
(
choose_plan
(
join
,
all_table_map
&
~
join
->
const_table_map
))
if
(
choose_plan
(
join
,
all_table_map
&
~
join
->
const_table_map
))
goto
error
;
goto
error
;
...
@@ -5299,7 +5306,7 @@ choose_plan(JOIN *join, table_map join_tables)
...
@@ -5299,7 +5306,7 @@ choose_plan(JOIN *join, table_map join_tables)
jtab_sort_func
=
straight_join
?
join_tab_cmp_straight
:
join_tab_cmp
;
jtab_sort_func
=
straight_join
?
join_tab_cmp_straight
:
join_tab_cmp
;
}
}
my_qsort2
(
join
->
best_ref
+
join
->
const_tables
,
my_qsort2
(
join
->
best_ref
+
join
->
const_tables
,
join
->
table
s
-
join
->
const_tables
,
sizeof
(
JOIN_TAB
*
),
join
->
table
_count
-
join
->
const_tables
,
sizeof
(
JOIN_TAB
*
),
jtab_sort_func
,
(
void
*
)
join
->
emb_sjm_nest
);
jtab_sort_func
,
(
void
*
)
join
->
emb_sjm_nest
);
join
->
cur_sj_inner_tables
=
0
;
join
->
cur_sj_inner_tables
=
0
;
...
@@ -5475,7 +5482,7 @@ join_tab_cmp_embedded_first(const void *emb, const void* ptr1, const void* ptr2
...
@@ -5475,7 +5482,7 @@ join_tab_cmp_embedded_first(const void *emb, const void* ptr1, const void* ptr2
static
uint
static
uint
determine_search_depth
(
JOIN
*
join
)
determine_search_depth
(
JOIN
*
join
)
{
{
uint
table_count
=
join
->
table
s
-
join
->
const_tables
;
uint
table_count
=
join
->
table
_count
-
join
->
const_tables
;
uint
search_depth
;
uint
search_depth
;
/* TODO: this value should be determined dynamically, based on statistics: */
/* TODO: this value should be determined dynamically, based on statistics: */
uint
max_tables_for_exhaustive_opt
=
7
;
uint
max_tables_for_exhaustive_opt
=
7
;
...
@@ -6415,6 +6422,28 @@ JOIN_TAB *next_breadth_first_tab(JOIN *join, JOIN_TAB *tab)
...
@@ -6415,6 +6422,28 @@ JOIN_TAB *next_breadth_first_tab(JOIN *join, JOIN_TAB *tab)
}
}
JOIN_TAB
*
first_top_level_tab
(
JOIN
*
join
,
enum
enum_with_const_tables
with_const
)
{
JOIN_TAB
*
tab
=
join
->
join_tab
;
if
(
with_const
==
WITH_CONST_TABLES
)
{
if
(
join
->
const_tables
==
join
->
table_count
)
return
NULL
;
tab
+=
join
->
const_tables
;
}
return
tab
;
}
JOIN_TAB
*
next_top_level_tab
(
JOIN
*
join
,
JOIN_TAB
*
tab
)
{
tab
=
next_breadth_first_tab
(
join
,
tab
);
if
(
tab
->
bush_root_tab
)
tab
=
NULL
;
return
tab
;
}
JOIN_TAB
*
first_linear_tab
(
JOIN
*
join
,
enum
enum_with_const_tables
const_tbls
)
JOIN_TAB
*
first_linear_tab
(
JOIN
*
join
,
enum
enum_with_const_tables
const_tbls
)
{
{
JOIN_TAB
*
first
=
join
->
join_tab
;
JOIN_TAB
*
first
=
join
->
join_tab
;
...
@@ -6580,7 +6609,7 @@ get_best_combination(JOIN *join)
...
@@ -6580,7 +6609,7 @@ get_best_combination(JOIN *join)
THD
*
thd
=
join
->
thd
;
THD
*
thd
=
join
->
thd
;
DBUG_ENTER
(
"get_best_combination"
);
DBUG_ENTER
(
"get_best_combination"
);
table_count
=
join
->
table
s
;
table_count
=
join
->
table
_count
;
if
(
!
(
join
->
join_tab
=
join_tab
=
if
(
!
(
join
->
join_tab
=
join_tab
=
(
JOIN_TAB
*
)
thd
->
alloc
(
sizeof
(
JOIN_TAB
)
*
table_count
)))
(
JOIN_TAB
*
)
thd
->
alloc
(
sizeof
(
JOIN_TAB
)
*
table_count
)))
DBUG_RETURN
(
TRUE
);
DBUG_RETURN
(
TRUE
);
...
@@ -6629,7 +6658,6 @@ get_best_combination(JOIN *join)
...
@@ -6629,7 +6658,6 @@ get_best_combination(JOIN *join)
j
->
on_expr_ref
=
(
Item
**
)
&
null_ptr
;
j
->
on_expr_ref
=
(
Item
**
)
&
null_ptr
;
j
->
keys
=
key_map
(
1
);
/* The unique index is always in 'possible keys' in EXPLAIN */
j
->
keys
=
key_map
(
1
);
/* The unique index is always in 'possible keys' in EXPLAIN */
/*
/*
2. Proceed with processing SJM nest's join tabs, putting them into the
2. Proceed with processing SJM nest's join tabs, putting them into the
sub-order
sub-order
...
@@ -7041,7 +7069,7 @@ JOIN::make_simple_join(JOIN *parent, TABLE *temp_table)
...
@@ -7041,7 +7069,7 @@ JOIN::make_simple_join(JOIN *parent, TABLE *temp_table)
join_tab
=
parent
->
join_tab_reexec
;
join_tab
=
parent
->
join_tab_reexec
;
table
=
&
parent
->
table_reexec
[
0
];
parent
->
table_reexec
[
0
]
=
temp_table
;
table
=
&
parent
->
table_reexec
[
0
];
parent
->
table_reexec
[
0
]
=
temp_table
;
table
s
=
top_jtrange_tables
=
1
;
table
_count
=
top_jtrange_tables
=
1
;
const_tables
=
0
;
const_tables
=
0
;
const_table_map
=
0
;
const_table_map
=
0
;
...
@@ -7383,9 +7411,9 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
...
@@ -7383,9 +7411,9 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
*/
*/
if
(
cond
)
/* Because of QUICK_GROUP_MIN_MAX_SELECT */
if
(
cond
)
/* Because of QUICK_GROUP_MIN_MAX_SELECT */
{
/* there may be a select without a cond. */
{
/* there may be a select without a cond. */
if
(
join
->
table
s
>
1
)
if
(
join
->
table
_count
>
1
)
cond
->
update_used_tables
();
// Tablenr may have changed
cond
->
update_used_tables
();
// Tablenr may have changed
if
(
join
->
const_tables
==
join
->
table
s
&&
if
(
join
->
const_tables
==
join
->
table
_count
&&
thd
->
lex
->
current_select
->
master_unit
()
==
thd
->
lex
->
current_select
->
master_unit
()
==
&
thd
->
lex
->
unit
)
// not upper level SELECT
&
thd
->
lex
->
unit
)
// not upper level SELECT
join
->
const_table_map
|=
RAND_TABLE_BIT
;
join
->
const_table_map
|=
RAND_TABLE_BIT
;
...
@@ -7486,7 +7514,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
...
@@ -7486,7 +7514,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
Following force including random expression in last table condition.
Following force including random expression in last table condition.
It solve problem with select like SELECT * FROM t1 WHERE rand() > 0.5
It solve problem with select like SELECT * FROM t1 WHERE rand() > 0.5
*/
*/
if
(
i
==
join
->
tables
-
1
)
if
(
tab
==
join
->
join_tab
+
join
->
top_jtrange_tables
-
1
)
current_map
|=
OUTER_REF_TABLE_BIT
|
RAND_TABLE_BIT
;
current_map
|=
OUTER_REF_TABLE_BIT
|
RAND_TABLE_BIT
;
used_tables
|=
current_map
;
used_tables
|=
current_map
;
...
@@ -7506,7 +7534,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
...
@@ -7506,7 +7534,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
We will use join cache here : prevent sorting of the first
We will use join cache here : prevent sorting of the first
table only and sort at the end.
table only and sort at the end.
*/
*/
if
(
i
!=
join
->
const_tables
&&
join
->
table
s
>
join
->
const_tables
+
1
)
if
(
i
!=
join
->
const_tables
&&
join
->
table
_count
>
join
->
const_tables
+
1
)
join
->
full_join
=
1
;
join
->
full_join
=
1
;
}
}
...
@@ -7884,9 +7912,9 @@ static uint make_join_orderinfo(JOIN *join)
...
@@ -7884,9 +7912,9 @@ static uint make_join_orderinfo(JOIN *join)
JOIN_TAB
*
tab
;
JOIN_TAB
*
tab
;
if
(
join
->
need_tmp
)
if
(
join
->
need_tmp
)
return
join
->
table
s
;
return
join
->
table
_count
;
tab
=
join
->
get_sort_by_join_tab
();
tab
=
join
->
get_sort_by_join_tab
();
return
tab
?
tab
-
join
->
join_tab
:
join
->
table
s
;
return
tab
?
tab
-
join
->
join_tab
:
join
->
table
_count
;
}
}
/*
/*
...
@@ -8840,9 +8868,8 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after)
...
@@ -8840,9 +8868,8 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after)
bool
error_if_full_join
(
JOIN
*
join
)
bool
error_if_full_join
(
JOIN
*
join
)
{
{
for
(
JOIN_TAB
*
tab
=
join
->
join_tab
,
*
end
=
join
->
join_tab
+
join
->
tables
;
for
(
JOIN_TAB
*
tab
=
first_top_level_tab
(
join
,
WITH_CONST_TABLES
);
tab
;
tab
<
end
;
tab
=
next_top_level_tab
(
join
,
tab
))
tab
++
)
{
{
if
(
tab
->
type
==
JT_ALL
&&
(
!
tab
->
select
||
!
tab
->
select
->
quick
))
if
(
tab
->
type
==
JT_ALL
&&
(
!
tab
->
select
||
!
tab
->
select
->
quick
))
{
{
...
@@ -9085,7 +9112,7 @@ void JOIN::cleanup(bool full)
...
@@ -9085,7 +9112,7 @@ void JOIN::cleanup(bool full)
Only a sorted table may be cached. This sorted table is always the
Only a sorted table may be cached. This sorted table is always the
first non const table in join->table
first non const table in join->table
*/
*/
if
(
table
s
>
const_tables
)
// Test for not-const tables
if
(
table
_count
>
const_tables
)
// Test for not-const tables
{
{
free_io_cache
(
table
[
const_tables
]);
free_io_cache
(
table
[
const_tables
]);
filesort_free_buffers
(
table
[
const_tables
],
full
);
filesort_free_buffers
(
table
[
const_tables
],
full
);
...
@@ -9318,7 +9345,7 @@ static ORDER *
...
@@ -9318,7 +9345,7 @@ static ORDER *
remove_const
(
JOIN
*
join
,
ORDER
*
first_order
,
COND
*
cond
,
remove_const
(
JOIN
*
join
,
ORDER
*
first_order
,
COND
*
cond
,
bool
change_list
,
bool
*
simple_order
)
bool
change_list
,
bool
*
simple_order
)
{
{
if
(
join
->
table
s
==
join
->
const_tables
)
if
(
join
->
table
_count
==
join
->
const_tables
)
return
change_list
?
0
:
first_order
;
// No need to sort
return
change_list
?
0
:
first_order
;
// No need to sort
ORDER
*
order
,
**
prev_ptr
;
ORDER
*
order
,
**
prev_ptr
;
...
@@ -9356,7 +9383,7 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond,
...
@@ -9356,7 +9383,7 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond,
table for all queries containing more than one table, ROLLUP, and an
table for all queries containing more than one table, ROLLUP, and an
outer join.
outer join.
*/
*/
(
join
->
table
s
>
1
&&
join
->
rollup
.
state
==
ROLLUP
::
STATE_INITED
&&
(
join
->
table
_count
>
1
&&
join
->
rollup
.
state
==
ROLLUP
::
STATE_INITED
&&
join
->
outer_join
))
join
->
outer_join
))
*
simple_order
=
0
;
// Must do a temp table to sort
*
simple_order
=
0
;
// Must do a temp table to sort
else
if
(
!
(
order_tables
&
not_const_tables
))
else
if
(
!
(
order_tables
&
not_const_tables
))
...
@@ -9455,7 +9482,7 @@ static void clear_tables(JOIN *join)
...
@@ -9455,7 +9482,7 @@ static void clear_tables(JOIN *join)
must clear only the non-const tables, as const tables
must clear only the non-const tables, as const tables
are not re-calculated.
are not re-calculated.
*/
*/
for
(
uint
i
=
0
;
i
<
join
->
table
s
;
i
++
)
for
(
uint
i
=
0
;
i
<
join
->
table
_count
;
i
++
)
{
{
if
(
!
(
join
->
table
[
i
]
->
map
&
join
->
const_table_map
))
if
(
!
(
join
->
table
[
i
]
->
map
&
join
->
const_table_map
))
mark_as_null_row
(
join
->
table
[
i
]);
// All fields are NULL
mark_as_null_row
(
join
->
table
[
i
]);
// All fields are NULL
...
@@ -13787,13 +13814,13 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
...
@@ -13787,13 +13814,13 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
}
}
/* Set up select_end */
/* Set up select_end */
Next_select_func
end_select
=
setup_end_select_func
(
join
);
Next_select_func
end_select
=
setup_end_select_func
(
join
);
if
(
join
->
table
s
)
if
(
join
->
table
_count
)
{
{
join
->
join_tab
[
join
->
top_jtrange_tables
-
1
].
next_select
=
end_select
;
join
->
join_tab
[
join
->
top_jtrange_tables
-
1
].
next_select
=
end_select
;
join_tab
=
join
->
join_tab
+
join
->
const_tables
;
join_tab
=
join
->
join_tab
+
join
->
const_tables
;
}
}
join
->
send_records
=
0
;
join
->
send_records
=
0
;
if
(
join
->
table
s
==
join
->
const_tables
)
if
(
join
->
table
_count
==
join
->
const_tables
)
{
{
/*
/*
HAVING will be checked after processing aggregate functions,
HAVING will be checked after processing aggregate functions,
...
@@ -13826,7 +13853,7 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
...
@@ -13826,7 +13853,7 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
}
}
else
else
{
{
DBUG_ASSERT
(
join
->
table
s
);
DBUG_ASSERT
(
join
->
table
_count
);
error
=
sub_select
(
join
,
join_tab
,
0
);
error
=
sub_select
(
join
,
join_tab
,
0
);
if
(
error
==
NESTED_LOOP_OK
||
error
==
NESTED_LOOP_NO_MORE_ROWS
)
if
(
error
==
NESTED_LOOP_OK
||
error
==
NESTED_LOOP_NO_MORE_ROWS
)
error
=
sub_select
(
join
,
join_tab
,
1
);
error
=
sub_select
(
join
,
join_tab
,
1
);
...
@@ -14120,7 +14147,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
...
@@ -14120,7 +14147,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
if
(
join
->
resume_nested_loop
)
if
(
join
->
resume_nested_loop
)
{
{
/* If not the last table, plunge down the nested loop */
/* If not the last table, plunge down the nested loop */
if
(
join_tab
<
join
->
join_tab
+
join
->
tables
-
1
)
if
(
join_tab
<
join
->
join_tab
+
join
->
t
op_jtrange_t
ables
-
1
)
rc
=
(
*
join_tab
->
next_select
)(
join
,
join_tab
+
1
,
0
);
rc
=
(
*
join_tab
->
next_select
)(
join
,
join_tab
+
1
,
0
);
else
else
{
{
...
@@ -15152,7 +15179,7 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
...
@@ -15152,7 +15179,7 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if
(
join
->
select_options
&
OPTION_FOUND_ROWS
)
if
(
join
->
select_options
&
OPTION_FOUND_ROWS
)
{
{
JOIN_TAB
*
jt
=
join
->
join_tab
;
JOIN_TAB
*
jt
=
join
->
join_tab
;
if
((
join
->
table
s
==
1
)
&&
!
join
->
tmp_table
&&
!
join
->
sort_and_group
if
((
join
->
table
_count
==
1
)
&&
!
join
->
tmp_table
&&
!
join
->
sort_and_group
&&
!
join
->
send_group_parts
&&
!
join
->
having
&&
!
jt
->
select_cond
&&
&&
!
join
->
send_group_parts
&&
!
join
->
having
&&
!
jt
->
select_cond
&&
!
(
jt
->
select
&&
jt
->
select
->
quick
)
&&
!
(
jt
->
select
&&
jt
->
select
->
quick
)
&&
(
jt
->
table
->
file
->
ha_table_flags
()
&
HA_STATS_RECORDS_IS_EXACT
)
&&
(
jt
->
table
->
file
->
ha_table_flags
()
&
HA_STATS_RECORDS_IS_EXACT
)
&&
...
@@ -15460,7 +15487,7 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
...
@@ -15460,7 +15487,7 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
table
->
file
->
print_error
(
error
,
MYF
(
0
));
/* purecov: inspected */
table
->
file
->
print_error
(
error
,
MYF
(
0
));
/* purecov: inspected */
DBUG_RETURN
(
NESTED_LOOP_ERROR
);
/* purecov: inspected */
DBUG_RETURN
(
NESTED_LOOP_ERROR
);
/* purecov: inspected */
}
}
join
->
join_tab
[
join
->
tables
-
1
].
next_select
=
end_unique_update
;
join
->
join_tab
[
join
->
t
op_jtrange_t
ables
-
1
].
next_select
=
end_unique_update
;
}
}
join
->
send_records
++
;
join
->
send_records
++
;
DBUG_RETURN
(
NESTED_LOOP_OK
);
DBUG_RETURN
(
NESTED_LOOP_OK
);
...
@@ -16543,7 +16570,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
...
@@ -16543,7 +16570,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
ref_key_quick_rows
=
table
->
quick_rows
[
ref_key
];
ref_key_quick_rows
=
table
->
quick_rows
[
ref_key
];
read_time
=
join
->
best_positions
[
tablenr
].
read_time
;
read_time
=
join
->
best_positions
[
tablenr
].
read_time
;
for
(
uint
i
=
tablenr
+
1
;
i
<
join
->
table
s
;
i
++
)
for
(
uint
i
=
tablenr
+
1
;
i
<
join
->
table
_count
;
i
++
)
fanout
*=
join
->
best_positions
[
i
].
records_read
;
// fanout is always >= 1
fanout
*=
join
->
best_positions
[
i
].
records_read
;
// fanout is always >= 1
for
(
nr
=
0
;
nr
<
table
->
s
->
keys
;
nr
++
)
for
(
nr
=
0
;
nr
<
table
->
s
->
keys
;
nr
++
)
...
@@ -16719,7 +16746,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
...
@@ -16719,7 +16746,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
*/
*/
if
((
select_limit
>=
table_records
)
&&
if
((
select_limit
>=
table_records
)
&&
(
tab
->
type
==
JT_ALL
&&
(
tab
->
type
==
JT_ALL
&&
tab
->
join
->
table
s
>
tab
->
join
->
const_tables
+
1
)
&&
tab
->
join
->
table
_count
>
tab
->
join
->
const_tables
+
1
)
&&
((
unsigned
)
best_key
!=
table
->
s
->
primary_key
||
((
unsigned
)
best_key
!=
table
->
s
->
primary_key
||
!
table
->
file
->
primary_key_is_clustered
()))
!
table
->
file
->
primary_key_is_clustered
()))
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
...
@@ -16919,7 +16946,7 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
...
@@ -16919,7 +16946,7 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
JOIN_TAB
*
tab
;
JOIN_TAB
*
tab
;
DBUG_ENTER
(
"create_sort_index"
);
DBUG_ENTER
(
"create_sort_index"
);
if
(
join
->
table
s
==
join
->
const_tables
)
if
(
join
->
table
_count
==
join
->
const_tables
)
DBUG_RETURN
(
0
);
// One row, no need to sort
DBUG_RETURN
(
0
);
// One row, no need to sort
tab
=
join
->
join_tab
+
join
->
const_tables
;
tab
=
join
->
join_tab
+
join
->
const_tables
;
table
=
tab
->
table
;
table
=
tab
->
table
;
...
...
sql/sql_select.h
View file @
5de770f3
...
@@ -647,7 +647,13 @@ public:
...
@@ -647,7 +647,13 @@ public:
passing 1st non-const table to filesort(). NULL means no such table exists.
passing 1st non-const table to filesort(). NULL means no such table exists.
*/
*/
TABLE
*
sort_by_table
;
TABLE
*
sort_by_table
;
uint
tables
;
/**< Number of tables in the join */
/*
Number of tables in the join.
(In MySQL, it is named 'tables' and is also the number of elements in
join->join_tab array. In MariaDB, the latter is not true, so we've renamed
the variable)
*/
uint
table_count
;
uint
outer_tables
;
/**< Number of tables that are not inside semijoin */
uint
outer_tables
;
/**< Number of tables that are not inside semijoin */
uint
const_tables
;
uint
const_tables
;
/*
/*
...
@@ -899,7 +905,7 @@ public:
...
@@ -899,7 +905,7 @@ public:
{
{
join_tab
=
join_tab_save
=
0
;
join_tab
=
join_tab_save
=
0
;
table
=
0
;
table
=
0
;
table
s
=
0
;
table
_count
=
0
;
top_jtrange_tables
=
0
;
top_jtrange_tables
=
0
;
const_tables
=
0
;
const_tables
=
0
;
eliminated_tables
=
0
;
eliminated_tables
=
0
;
...
@@ -1015,7 +1021,7 @@ public:
...
@@ -1015,7 +1021,7 @@ public:
}
}
inline
table_map
all_tables_map
()
inline
table_map
all_tables_map
()
{
{
return
(
table_map
(
1
)
<<
table
s
)
-
1
;
return
(
table_map
(
1
)
<<
table
_count
)
-
1
;
}
}
/*
/*
Return the table for which an index scan can be used to satisfy
Return the table for which an index scan can be used to satisfy
...
...
sql/sql_union.cc
View file @
5de770f3
...
@@ -690,7 +690,7 @@ bool st_select_lex_unit::cleanup()
...
@@ -690,7 +690,7 @@ bool st_select_lex_unit::cleanup()
if
((
join
=
fake_select_lex
->
join
))
if
((
join
=
fake_select_lex
->
join
))
{
{
join
->
tables_list
=
0
;
join
->
tables_list
=
0
;
join
->
table
s
=
0
;
join
->
table
_count
=
0
;
join
->
top_jtrange_tables
=
0
;
join
->
top_jtrange_tables
=
0
;
}
}
error
|=
fake_select_lex
->
cleanup
();
error
|=
fake_select_lex
->
cleanup
();
...
...
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