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()
An IN predicate might be evaluated in a query for which all tables have
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
;
if
(
!
(
left_expr_cache
=
new
List
<
Cached_item
>
))
...
...
@@ -2701,9 +2701,9 @@ int subselect_single_select_engine::exec()
pushed down into the subquery. Those optimizations are ref[_or_null]
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
)
{
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)
return 1;
*/
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' */
result
=
busy_blocks
*
(
DISK_SEEK_BASE_COST
+
...
...
@@ -11270,7 +11270,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
/* Perform few 'cheap' tests whether this access method is applicable. */
if
(
!
join
)
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
->
select_distinct
))
||
(
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);
static
Item
*
remove_additional_cond
(
Item
*
conds
);
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
...
...
@@ -644,7 +647,7 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
{
st_select_lex
*
child_select
=
(
*
in_subq
)
->
get_select_lex
();
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
...
...
@@ -693,15 +696,15 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
bool
remove_item
=
TRUE
;
if
((
*
in_subq
)
->
is_flattenable_semijoin
)
{
if
(
join
->
table
s
+
(
*
in_subq
)
->
unit
->
first_select
()
->
join
->
table
s
>=
MAX_TABLES
)
if
(
join
->
table
_count
+
(
*
in_subq
)
->
unit
->
first_select
()
->
join
->
table
_count
>=
MAX_TABLES
)
break
;
if
(
convert_subq_to_sj
(
join
,
*
in_subq
))
DBUG_RETURN
(
TRUE
);
}
else
{
if
(
join
->
table
s
+
1
>=
MAX_TABLES
)
if
(
join
->
table
_count
+
1
>=
MAX_TABLES
)
break
;
if
(
convert_subq_to_jtbm
(
join
,
*
in_subq
,
&
remove_item
))
DBUG_RETURN
(
TRUE
);
...
...
@@ -830,7 +833,8 @@ void get_delayed_table_estimates(TABLE *table,
double
read_time
;
/* 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
;
*
startup_cost
=
read_time
;
...
...
@@ -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
/*TODO: also reset the 'with_subselect' there. */
/* n. Adjust the parent_join->table
s
counter */
uint
table_no
=
parent_join
->
table
s
;
/* n. Adjust the parent_join->table
_count
counter */
uint
table_no
=
parent_join
->
table
_count
;
/* n. Walk through child's tables and adjust table->map */
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)
emb
=
emb
->
embedding
)
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
...
...
@@ -1300,11 +1304,11 @@ static bool convert_subq_to_jtbm(JOIN *parent_join,
((
subselect_hash_sj_engine
*
)
subq_pred
->
engine
);
jtbm
->
table
=
hash_sj_engine
->
tmp_table
;
jtbm
->
table
->
tablenr
=
parent_join
->
table
s
;
jtbm
->
table
->
map
=
table_map
(
1
)
<<
(
parent_join
->
table
s
);
jtbm
->
table
->
tablenr
=
parent_join
->
table
_count
;
jtbm
->
table
->
map
=
table_map
(
1
)
<<
(
parent_join
->
table
_count
);
parent_join
->
table
s
++
;
DBUG_ASSERT
(
parent_join
->
table
s
<
MAX_TABLES
);
parent_join
->
table
_count
++
;
DBUG_ASSERT
(
parent_join
->
table
_count
<
MAX_TABLES
);
Item
*
conds
=
hash_sj_engine
->
semi_join_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,
void
fix_semijoin_strategies_for_picked_join_order
(
JOIN
*
join
)
{
uint
table_count
=
join
->
table
s
;
uint
table_count
=
join
->
table
_count
;
uint
tablenr
;
table_map
remaining_tables
=
0
;
table_map
handled_tabs
=
0
;
...
...
@@ -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
...
...
@@ -3505,6 +3507,7 @@ int do_sj_dups_weedout(THD *thd, SJ_TMP_TABLE *sjtbl)
FALSE OK
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
,
uint
no_jbuf_after
)
...
...
@@ -3512,17 +3515,19 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
uint
i
;
THD
*
thd
=
join
->
thd
;
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
;
POSITION
*
pos
=
join
->
best_positions
+
i
;
//
POSITION *pos= join->best_positions + i;
uint
keylen
,
keyno
;
switch
(
pos
->
sj_strategy
)
{
case
SJ_OPT_MATERIALIZE
:
case
SJ_OPT_MATERIALIZE_SCAN
:
/* 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
;
case
SJ_OPT_LOOSE_SCAN
:
{
...
...
@@ -3539,6 +3544,7 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
if
(
pos
->
n_sj_tables
>
1
)
tab
[
pos
->
n_sj_tables
-
1
].
do_firstmatch
=
tab
;
i
+=
pos
->
n_sj_tables
;
pos
+=
pos
->
n_sj_tables
;
break
;
}
case
SJ_OPT_DUPS_WEEDOUT
:
...
...
@@ -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
;
i
+=
pos
->
n_sj_tables
;
pos
+=
pos
->
n_sj_tables
;
break
;
}
case
SJ_OPT_FIRST_MATCH
:
...
...
@@ -3658,10 +3665,12 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
}
j
[
-
1
].
do_firstmatch
=
jump_to
;
i
+=
pos
->
n_sj_tables
;
pos
+=
pos
->
n_sj_tables
;
break
;
}
case
SJ_OPT_NONE
:
i
++
;
pos
++
;
break
;
}
}
...
...
@@ -3848,7 +3857,7 @@ int rewrite_to_index_subquery_engine(JOIN *join)
if
(
!
join
->
group_list
&&
!
join
->
order
&&
join
->
unit
->
item
&&
join
->
unit
->
item
->
substype
()
==
Item_subselect
::
IN_SUBS
&&
join
->
table
s
==
1
&&
join
->
conds
&&
join
->
table
_count
==
1
&&
join
->
conds
&&
!
join
->
unit
->
is_union
())
{
if
(
!
join
->
having
)
...
...
sql/sql_cursor.cc
View file @
5de770f3
...
...
@@ -381,14 +381,14 @@ Sensitive_cursor::open(JOIN *join_arg)
/* Prepare JOIN for reading rows. */
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
->
fetch_limit
=
join
->
unit
->
offset_limit_cnt
;
/* Disable JOIN CACHE as it is not working with cursors yet */
for
(
JOIN_TAB
*
tab
=
join_tab
;
tab
!=
join
->
join_tab
+
join
->
tables
-
1
;
tab
++
)
for
(
JOIN_TAB
*
tab
=
first_linear_tab
(
join
,
WITHOUT_CONST_TABLES
);
tab
!=
join
->
join_tab
+
join
->
t
op_jtrange_t
ables
-
1
;
tab
=
next_linear_tab
(
join
,
tab
,
WITH_BUSH_ROOTS
)
)
{
if
(
tab
->
next_select
==
sub_select_cache
)
tab
->
next_select
=
sub_select
;
...
...
sql/sql_delete.cc
View file @
5de770f3
...
...
@@ -677,9 +677,10 @@ multi_delete::initialize_tables(JOIN *join)
walk
=
delete_tables
;
for
(
JOIN_TAB
*
tab
=
join
->
join_tab
,
*
end
=
join
->
join_tab
+
join
->
tables
;
tab
<
end
;
tab
++
)
for
(
JOIN_TAB
*
tab
=
first_linear_tab
(
join
,
WITH_CONST_TABLES
);
tab
;
tab
=
next_linear_tab
(
join
,
tab
,
WITH_BUSH_ROOTS
))
{
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,
for
(
table_ptr
=
select_lex
->
leaf_tables
;
table_ptr
;
table_ptr
=
table_ptr
->
next_leaf
)
table
s
++
;
table
_count
++
;
if
(
setup_wild
(
thd
,
tables_list
,
fields_list
,
&
all_fields
,
wild_num
)
||
select_lex
->
setup_ref_array
(
thd
,
og_num
)
||
...
...
@@ -840,7 +840,7 @@ JOIN::optimize()
"Impossible HAVING"
:
"Impossible WHERE"
));
zero_result_cause
=
having_value
==
Item
::
COND_FALSE
?
"Impossible HAVING"
:
"Impossible WHERE"
;
table
s
=
0
;
table
_count
=
0
;
error
=
0
;
goto
setup_subq_exit
;
}
...
...
@@ -890,7 +890,7 @@ JOIN::optimize()
{
DBUG_PRINT
(
"info"
,(
"No matching min/max row"
));
zero_result_cause
=
"No matching min/max row"
;
table
s
=
0
;
table
_count
=
0
;
error
=
0
;
goto
setup_subq_exit
;
}
...
...
@@ -904,14 +904,14 @@ JOIN::optimize()
{
DBUG_PRINT
(
"info"
,(
"No matching min/max row"
));
zero_result_cause
=
"No matching min/max row"
;
table
s
=
0
;
table
_count
=
0
;
error
=
0
;
goto
setup_subq_exit
;
}
DBUG_PRINT
(
"info"
,(
"Select tables optimized away"
));
zero_result_cause
=
"Select tables optimized away"
;
tables_list
=
0
;
// All tables resolved
const_tables
=
table
s
;
const_tables
=
table
_count
;
/*
Extract all table-independent conditions and replace the WHERE
clause with them. All other conditions were computed by opt_sum_query
...
...
@@ -967,7 +967,7 @@ JOIN::optimize()
else
{
/* 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"
);
...
...
@@ -1125,7 +1125,7 @@ JOIN::optimize()
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
&&
(
!
join_tab
[
const_tables
].
select
||
!
join_tab
[
const_tables
].
select
->
quick
||
...
...
@@ -1176,7 +1176,7 @@ JOIN::optimize()
if
(
!
hidden_group_fields
&&
rollup
.
state
==
ROLLUP
::
STATE_NONE
)
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
)
{
/*
...
...
@@ -1305,7 +1305,7 @@ JOIN::optimize()
When the WITH ROLLUP modifier is present, we cannot skip temporary table
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
)
||
(
group_list
&&
order
)
||
test
(
select_options
&
OPTION_BUFFER_RESULT
)))
||
...
...
@@ -1319,7 +1319,7 @@ JOIN::optimize()
Yet the current implementation of FORCE INDEX hints does not
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_options
&
(
SELECT_DESCRIBE
|
SELECT_NO_JOIN_CACHE
))
|
...
...
@@ -1351,7 +1351,7 @@ JOIN::optimize()
*/
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
))
table
[
i
]
->
prepare_for_position
();
...
...
@@ -1360,7 +1360,7 @@ JOIN::optimize()
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
...
...
@@ -1535,7 +1535,7 @@ JOIN::optimize()
if
(
exec_tmp_table1
->
distinct
)
{
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
{
if
(
used_tables
&
last_join_tab
->
table
->
map
)
...
...
@@ -1761,12 +1761,17 @@ JOIN::reinit()
set_items_ref_array
(
items0
);
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) */
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
)
restore_tmp
();
...
...
@@ -1823,7 +1828,7 @@ JOIN::save_join_tab()
if
(
!
join_tab_save
&&
select_lex
->
master_unit
()
->
uncacheable
)
{
if
(
!
(
join_tab_save
=
(
JOIN_TAB
*
)
thd
->
memdup
((
uchar
*
)
join_tab
,
sizeof
(
JOIN_TAB
)
*
table
s
)))
sizeof
(
JOIN_TAB
)
*
table
_count
)))
return
1
;
}
return
0
;
...
...
@@ -1863,7 +1868,7 @@ JOIN::exec()
}
(
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
if
(
select_options
&
SELECT_DESCRIBE
)
select_describe
(
this
,
FALSE
,
FALSE
,
FALSE
,
...
...
@@ -1916,7 +1921,7 @@ JOIN::exec()
FOUND_ROWS() may be called. Never reset the examined row count here.
It must be accumulated from all join iterations of all join parts.
*/
if
(
table
s
)
if
(
table
_count
)
thd
->
limit_found_rows
=
0
;
if
(
zero_result_cause
)
...
...
@@ -1953,7 +1958,7 @@ JOIN::exec()
}
if
(
order
&&
(
order
!=
group_list
||
!
(
select_options
&
SELECT_BIG_RESULT
))
&&
(
const_tables
==
table
s
||
(
const_tables
==
table
_count
||
((
simple_order
||
skip_sort_order
)
&&
test_if_skip_sort_order
(
&
join_tab
[
const_tables
],
order
,
select_limit
,
0
,
...
...
@@ -1964,7 +1969,7 @@ JOIN::exec()
select_describe
(
this
,
need_tmp
,
order
!=
0
&&
!
skip_sort_order
,
select_distinct
,
!
table
s
?
"No tables used"
:
NullS
);
!
table
_count
?
"No tables used"
:
NullS
);
DBUG_VOID_RETURN
;
}
...
...
@@ -1998,7 +2003,7 @@ JOIN::exec()
thd_proc_info
(
thd
,
copy_to_tmp_table
);
DBUG_PRINT
(
"info"
,
(
"%s"
,
thd
->
proc_info
));
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
;
first_tab
->
sorted
=
test
(
first_tab
->
loosescan_match_tab
);
...
...
@@ -2169,7 +2174,7 @@ JOIN::exec()
DBUG_VOID_RETURN
;
curr_join
->
group_list
=
0
;
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
;
first_tab
->
sorted
=
test
(
first_tab
->
loosescan_match_tab
);
...
...
@@ -2182,7 +2187,7 @@ JOIN::exec()
DBUG_VOID_RETURN
;
}
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
// No sum funcs anymore
...
...
@@ -2385,7 +2390,7 @@ JOIN::exec()
curr_join
->
group_list
?
TRUE
:
FALSE
))
DBUG_VOID_RETURN
;
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
)
{
/*
...
...
@@ -2407,7 +2412,7 @@ JOIN::exec()
curr_join
->
fields
=
curr_fields_list
;
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
...
...
@@ -2474,9 +2479,11 @@ JOIN::destroy()
{
if
(
join_tab
!=
tmp_join
->
join_tab
)
{
JOIN_TAB
*
tab
,
*
end
;
for
(
tab
=
join_tab
,
end
=
tab
+
tables
;
tab
!=
end
;
tab
++
)
for
(
JOIN_TAB
*
tab
=
first_linear_tab
(
this
,
WITH_CONST_TABLES
);
tab
;
tab
=
next_linear_tab
(
this
,
tab
,
WITH_BUSH_ROOTS
))
{
tab
->
cleanup
();
}
}
tmp_join
->
tmp_join
=
0
;
/*
...
...
@@ -2801,7 +2808,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
DBUG_ENTER
(
"make_join_statistics"
);
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_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,
{
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
));
goto
error
;
}
...
...
@@ -2952,7 +2959,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
}
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
,
~
outer_join
,
join
->
select_lex
,
&
sargables
))
goto
error
;
...
...
@@ -3269,14 +3276,14 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
join
->
const_tables
=
const_count
;
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
);
if
(
optimize_semijoin_nests
(
join
,
all_table_map
))
DBUG_RETURN
(
TRUE
);
/* purecov: inspected */
/* 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
))
goto
error
;
...
...
@@ -5299,7 +5306,7 @@ choose_plan(JOIN *join, table_map join_tables)
jtab_sort_func
=
straight_join
?
join_tab_cmp_straight
:
join_tab_cmp
;
}
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
);
join
->
cur_sj_inner_tables
=
0
;
...
...
@@ -5475,7 +5482,7 @@ join_tab_cmp_embedded_first(const void *emb, const void* ptr1, const void* ptr2
static
uint
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
;
/* TODO: this value should be determined dynamically, based on statistics: */
uint
max_tables_for_exhaustive_opt
=
7
;
...
...
@@ -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
=
join
->
join_tab
;
...
...
@@ -6580,7 +6609,7 @@ get_best_combination(JOIN *join)
THD
*
thd
=
join
->
thd
;
DBUG_ENTER
(
"get_best_combination"
);
table_count
=
join
->
table
s
;
table_count
=
join
->
table
_count
;
if
(
!
(
join
->
join_tab
=
join_tab
=
(
JOIN_TAB
*
)
thd
->
alloc
(
sizeof
(
JOIN_TAB
)
*
table_count
)))
DBUG_RETURN
(
TRUE
);
...
...
@@ -6629,7 +6658,6 @@ get_best_combination(JOIN *join)
j
->
on_expr_ref
=
(
Item
**
)
&
null_ptr
;
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
sub-order
...
...
@@ -7041,7 +7069,7 @@ JOIN::make_simple_join(JOIN *parent, TABLE *temp_table)
join_tab
=
parent
->
join_tab_reexec
;
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_table_map
=
0
;
...
...
@@ -7383,9 +7411,9 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
*/
if
(
cond
)
/* Because of QUICK_GROUP_MIN_MAX_SELECT */
{
/* 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
if
(
join
->
const_tables
==
join
->
table
s
&&
if
(
join
->
const_tables
==
join
->
table
_count
&&
thd
->
lex
->
current_select
->
master_unit
()
==
&
thd
->
lex
->
unit
)
// not upper level SELECT
join
->
const_table_map
|=
RAND_TABLE_BIT
;
...
...
@@ -7486,7 +7514,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
Following force including random expression in last table condition.
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
;
used_tables
|=
current_map
;
...
...
@@ -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
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
;
}
...
...
@@ -7884,9 +7912,9 @@ static uint make_join_orderinfo(JOIN *join)
JOIN_TAB
*
tab
;
if
(
join
->
need_tmp
)
return
join
->
table
s
;
return
join
->
table
_count
;
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)
bool
error_if_full_join
(
JOIN
*
join
)
{
for
(
JOIN_TAB
*
tab
=
join
->
join_tab
,
*
end
=
join
->
join_tab
+
join
->
tables
;
tab
<
end
;
tab
++
)
for
(
JOIN_TAB
*
tab
=
first_top_level_tab
(
join
,
WITH_CONST_TABLES
);
tab
;
tab
=
next_top_level_tab
(
join
,
tab
))
{
if
(
tab
->
type
==
JT_ALL
&&
(
!
tab
->
select
||
!
tab
->
select
->
quick
))
{
...
...
@@ -9085,7 +9112,7 @@ void JOIN::cleanup(bool full)
Only a sorted table may be cached. This sorted table is always the
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
]);
filesort_free_buffers
(
table
[
const_tables
],
full
);
...
...
@@ -9318,7 +9345,7 @@ static ORDER *
remove_const
(
JOIN
*
join
,
ORDER
*
first_order
,
COND
*
cond
,
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
ORDER
*
order
,
**
prev_ptr
;
...
...
@@ -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
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
))
*
simple_order
=
0
;
// Must do a temp table to sort
else
if
(
!
(
order_tables
&
not_const_tables
))
...
...
@@ -9455,7 +9482,7 @@ static void clear_tables(JOIN *join)
must clear only the non-const tables, as const tables
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
))
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)
}
/* Set up select_end */
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_tab
=
join
->
join_tab
+
join
->
const_tables
;
}
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,
...
...
@@ -13826,7 +13853,7 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
}
else
{
DBUG_ASSERT
(
join
->
table
s
);
DBUG_ASSERT
(
join
->
table
_count
);
error
=
sub_select
(
join
,
join_tab
,
0
);
if
(
error
==
NESTED_LOOP_OK
||
error
==
NESTED_LOOP_NO_MORE_ROWS
)
error
=
sub_select
(
join
,
join_tab
,
1
);
...
...
@@ -14120,7 +14147,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
if
(
join
->
resume_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
);
else
{
...
...
@@ -15152,7 +15179,7 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if
(
join
->
select_options
&
OPTION_FOUND_ROWS
)
{
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
&&
!
(
jt
->
select
&&
jt
->
select
->
quick
)
&&
(
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)),
table
->
file
->
print_error
(
error
,
MYF
(
0
));
/* 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
++
;
DBUG_RETURN
(
NESTED_LOOP_OK
);
...
...
@@ -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
];
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
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,
*/
if
((
select_limit
>=
table_records
)
&&
(
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
||
!
table
->
file
->
primary_key_is_clustered
()))
DBUG_RETURN
(
0
);
...
...
@@ -16919,7 +16946,7 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
JOIN_TAB
*
tab
;
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
tab
=
join
->
join_tab
+
join
->
const_tables
;
table
=
tab
->
table
;
...
...
sql/sql_select.h
View file @
5de770f3
...
...
@@ -647,7 +647,13 @@ public:
passing 1st non-const table to filesort(). NULL means no such table exists.
*/
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
const_tables
;
/*
...
...
@@ -899,7 +905,7 @@ public:
{
join_tab
=
join_tab_save
=
0
;
table
=
0
;
table
s
=
0
;
table
_count
=
0
;
top_jtrange_tables
=
0
;
const_tables
=
0
;
eliminated_tables
=
0
;
...
...
@@ -1015,7 +1021,7 @@ public:
}
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
...
...
sql/sql_union.cc
View file @
5de770f3
...
...
@@ -690,7 +690,7 @@ bool st_select_lex_unit::cleanup()
if
((
join
=
fake_select_lex
->
join
))
{
join
->
tables_list
=
0
;
join
->
table
s
=
0
;
join
->
table
_count
=
0
;
join
->
top_jtrange_tables
=
0
;
}
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