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
71c4cc4a
Commit
71c4cc4a
authored
Nov 11, 2004
by
timour@mysql.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
WL#1972 - manual merge with latest bk source
parent
866abfdd
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
277 additions
and
197 deletions
+277
-197
sql/sql_select.cc
sql/sql_select.cc
+277
-197
No files found.
sql/sql_select.cc
View file @
71c4cc4a
...
...
@@ -91,7 +91,7 @@ static int return_zero_rows(JOIN *join, select_result *res,TABLE_LIST *tables,
uint
select_options
,
const
char
*
info
,
Item
*
having
,
Procedure
*
proc
,
SELECT_LEX_UNIT
*
unit
);
static
COND
*
build_equal_items
(
COND
*
cond
,
static
COND
*
build_equal_items
(
THD
*
thd
,
COND
*
cond
,
COND_EQUAL
*
inherited
,
List
<
TABLE_LIST
>
*
join_list
,
COND_EQUAL
**
cond_equal_ref
);
...
...
@@ -101,6 +101,7 @@ static COND* substitute_for_best_equal_field(COND *cond,
static
COND
*
simplify_joins
(
JOIN
*
join
,
List
<
TABLE_LIST
>
*
join_list
,
COND
*
conds
,
bool
top
);
static
COND
*
optimize_cond
(
JOIN
*
join
,
COND
*
conds
,
List
<
TABLE_LIST
>
*
join_list
,
Item
::
cond_result
*
cond_value
);
static
bool
resolve_nested_join
(
TABLE_LIST
*
table
);
static
COND
*
remove_eq_conds
(
THD
*
thd
,
COND
*
cond
,
...
...
@@ -191,6 +192,7 @@ static void init_tmptable_sum_functions(Item_sum **func);
static
void
update_tmptable_sum_func
(
Item_sum
**
func
,
TABLE
*
tmp_table
);
static
void
copy_sum_funcs
(
Item_sum
**
func_ptr
);
static
bool
add_ref_to_table_cond
(
THD
*
thd
,
JOIN_TAB
*
join_tab
);
static
bool
setup_sum_funcs
(
THD
*
thd
,
Item_sum
**
func_ptr
);
static
bool
init_sum_functions
(
Item_sum
**
func
,
Item_sum
**
end
);
static
bool
update_sum_func
(
Item_sum
**
func
);
static
void
select_describe
(
JOIN
*
join
,
bool
need_tmp_table
,
bool
need_order
,
...
...
@@ -228,16 +230,11 @@ int handle_select(THD *thd, LEX *lex, select_result *result)
select_lex
->
options
|
thd
->
options
,
result
,
unit
,
select_lex
);
}
/* Don't set res if it's -1 as we may want this later */
DBUG_PRINT
(
"info"
,(
"res: %d report_error: %d"
,
res
,
thd
->
net
.
report_error
));
if
(
thd
->
net
.
report_error
)
res
=
1
;
if
(
unlikely
(
res
))
if
(
thd
->
net
.
report_error
||
res
<
0
)
{
if
(
res
>
0
)
result
->
send_error
(
0
,
NullS
);
result
->
send_error
(
0
,
NullS
);
result
->
abort
();
res
=
1
;
// Error sent to client
}
...
...
@@ -333,7 +330,7 @@ JOIN::prepare(Item ***rref_pointer_array,
if
(
having_fix_rc
||
thd
->
net
.
report_error
)
DBUG_RETURN
(
-
1
);
/* purecov: inspected */
if
(
having
->
with_sum_func
)
having
->
split_sum_func
(
ref_pointer_array
,
all_fields
);
having
->
split_sum_func
(
thd
,
ref_pointer_array
,
all_fields
);
}
if
(
!
thd
->
lex
->
view_prepare_mode
)
...
...
@@ -558,17 +555,7 @@ JOIN::optimize()
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
}
/*
Build all multiple equality predicates and eliminate equality
predicates that can be inferred from these multiple equalities.
For each reference of a field included into a multiple equality
that occurs in a function set a pointer to the multiple equality
predicate. Substitute a constant instead of this field if the
multiple equality contains a constant.
*/
conds
=
build_equal_items
(
conds
,
NULL
,
join_list
,
&
cond_equal
);
conds
=
optimize_cond
(
this
,
conds
,
&
cond_value
);
conds
=
optimize_cond
(
this
,
conds
,
join_list
,
&
cond_value
);
if
(
thd
->
net
.
report_error
)
{
error
=
1
;
...
...
@@ -686,6 +673,7 @@ JOIN::optimize()
{
conds
=
substitute_for_best_equal_field
(
conds
,
cond_equal
,
map2table
);
conds
->
update_used_tables
();
DBUG_EXECUTE
(
"where"
,
print_where
(
conds
,
"after substitute_best_equal"
););
}
/*
Permorm the the optimization on fields evaluation mentioned above
...
...
@@ -1003,13 +991,15 @@ JOIN::optimize()
if
(
create_sort_index
(
thd
,
this
,
group_list
,
HA_POS_ERROR
,
HA_POS_ERROR
)
||
alloc_group_fields
(
this
,
group_list
)
||
make_sum_func_list
(
all_fields
,
fields_list
,
1
))
make_sum_func_list
(
all_fields
,
fields_list
,
1
)
||
setup_sum_funcs
(
thd
,
sum_funcs
))
DBUG_RETURN
(
1
);
group_list
=
0
;
}
else
{
if
(
make_sum_func_list
(
all_fields
,
fields_list
,
0
))
if
(
make_sum_func_list
(
all_fields
,
fields_list
,
0
)
||
setup_sum_funcs
(
thd
,
sum_funcs
))
DBUG_RETURN
(
1
);
if
(
!
group_list
&&
!
exec_tmp_table1
->
distinct
&&
order
&&
simple_order
)
{
...
...
@@ -1385,6 +1375,7 @@ JOIN::exec()
}
if
(
curr_join
->
make_sum_func_list
(
*
curr_all_fields
,
*
curr_fields_list
,
1
,
TRUE
)
||
setup_sum_funcs
(
curr_join
->
thd
,
curr_join
->
sum_funcs
)
||
(
tmp_error
=
do_select
(
curr_join
,
(
List
<
Item
>
*
)
0
,
curr_tmp_table
,
0
)))
{
...
...
@@ -1472,7 +1463,9 @@ JOIN::exec()
set_items_ref_array
(
items3
);
if
(
curr_join
->
make_sum_func_list
(
*
curr_all_fields
,
*
curr_fields_list
,
1
,
TRUE
)
||
thd
->
is_fatal_error
)
1
,
TRUE
)
||
setup_sum_funcs
(
curr_join
->
thd
,
curr_join
->
sum_funcs
)
||
thd
->
is_fatal_error
)
DBUG_VOID_RETURN
;
}
if
(
curr_join
->
group_list
||
curr_join
->
order
)
...
...
@@ -1665,9 +1658,13 @@ Cursor::init_from_thd(THD *thd)
/*
We need to save and reset thd->mem_root, otherwise it'll be freed
later in mysql_parse.
We can't just change the thd->mem_root here as we want to keep the things
that is already allocated in thd->mem_root for Cursor::fetch()
*/
mem_root
=
thd
->
mem_root
;
init_sql_alloc
(
&
thd
->
mem_root
,
main_mem_root
=
*
thd
->
mem_root
;
/* Allocate new memory root for thd */
init_sql_alloc
(
thd
->
mem_root
,
thd
->
variables
.
query_alloc_block_size
,
thd
->
variables
.
query_prealloc_size
);
...
...
@@ -1681,7 +1678,7 @@ Cursor::init_from_thd(THD *thd)
open_tables
=
thd
->
open_tables
;
lock
=
thd
->
lock
;
query_id
=
thd
->
query_id
;
free_list
=
thd
->
free_list
;
free_list
=
thd
->
free_list
;
reset_thd
(
thd
);
/*
XXX: thd->locked_tables is not changed.
...
...
@@ -1696,8 +1693,6 @@ Cursor::init_from_thd(THD *thd)
void
Cursor
::
init_thd
(
THD
*
thd
)
{
thd
->
mem_root
=
mem_root
;
DBUG_ASSERT
(
thd
->
derived_tables
==
0
);
thd
->
derived_tables
=
derived_tables
;
...
...
@@ -1707,7 +1702,6 @@ Cursor::init_thd(THD *thd)
DBUG_ASSERT
(
thd
->
lock
==
0
);
thd
->
lock
=
lock
;
thd
->
query_id
=
query_id
;
thd
->
free_list
=
free_list
;
}
...
...
@@ -1725,11 +1719,10 @@ int
Cursor
::
open
(
JOIN
*
join_arg
)
{
join
=
join_arg
;
THD
*
thd
=
join
->
thd
;
/* First non-constant table */
JOIN_TAB
*
join_tab
=
join
->
join_tab
+
join
->
const_tables
;
DBUG_ENTER
(
"Cursor::open"
);
/*
Send fields description to the client; server_status is sent
...
...
@@ -1751,7 +1744,9 @@ Cursor::open(JOIN *join_arg)
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
=
join_tab
;
tab
!=
join
->
join_tab
+
join
->
tables
-
1
;
tab
++
)
{
if
(
tab
->
next_select
==
sub_select_cache
)
tab
->
next_select
=
sub_select
;
...
...
@@ -1765,7 +1760,7 @@ Cursor::open(JOIN *join_arg)
*/
DBUG_ASSERT
(
join_tab
->
table
->
null_row
==
0
);
return
join_tab
->
read_first_record
(
join_tab
);
DBUG_RETURN
(
join_tab
->
read_first_record
(
join_tab
)
);
}
...
...
@@ -1784,13 +1779,15 @@ int
Cursor
::
fetch
(
ulong
num_rows
)
{
THD
*
thd
=
join
->
thd
;
JOIN_TAB
*
join_tab
=
join
->
join_tab
+
join
->
const_tables
;
;
JOIN_TAB
*
join_tab
=
join
->
join_tab
+
join
->
const_tables
;
COND
*
on_expr
=
*
join_tab
->
on_expr_ref
;
COND
*
select_cond
=
join_tab
->
select_cond
;
READ_RECORD
*
info
=
&
join_tab
->
read_record
;
int
error
=
0
;
/* save references to memory, allocated during fetch */
thd
->
set_n_backup_item_arena
(
this
,
&
thd
->
stmt_backup
);
join
->
fetch_limit
+=
num_rows
;
/*
...
...
@@ -1855,53 +1852,37 @@ Cursor::fetch(ulong num_rows)
if
(
thd
->
net
.
report_error
)
error
=
-
1
;
switch
(
error
)
{
/* Fetch limit worked, possibly more rows are there */
case
-
4
:
if
(
error
==
-
3
)
/* LIMIT clause worked */
error
=
0
;
#ifdef USING_TRANSACTIONS
if
(
thd
->
transaction
.
all
.
innobase_tid
)
ha_release_temporary_latches
(
thd
);
#endif
thd
->
restore_backup_item_arena
(
this
,
&
thd
->
stmt_backup
);
if
(
error
==
-
4
)
{
/* Fetch limit worked, possibly more rows are there */
thd
->
server_status
|=
SERVER_STATUS_CURSOR_EXISTS
;
::
send_eof
(
thd
);
thd
->
server_status
&=
~
SERVER_STATUS_CURSOR_EXISTS
;
/* save references to memory, allocated during fetch */
mem_root
=
thd
->
mem_root
;
free_list
=
thd
->
free_list
;
break
;
/* Limit clause worked: this is the same as 'no more rows' */
case
-
3
:
/* LIMIT clause worked */
error
=
0
;
/* fallthrough */
case
0
:
/* No more rows */
if
(
thd
->
transaction
.
all
.
innobase_tid
)
ha_release_temporary_latches
(
thd
);
close
();
thd
->
server_status
|=
SERVER_STATUS_LAST_ROW_SENT
;
::
send_eof
(
thd
);
thd
->
server_status
&=
~
SERVER_STATUS_LAST_ROW_SENT
;
join
=
0
;
unit
=
0
;
free_items
(
thd
->
free_list
);
thd
->
free_list
=
free_list
=
0
;
/*
Must be last, as some memory might be allocated for free purposes,
like in free_tmp_table() (TODO: fix this issue)
*/
mem_root
=
thd
->
mem_root
;
free_root
(
&
mem_root
,
MYF
(
0
));
break
;
default:
}
else
{
close
();
join
=
0
;
unit
=
0
;
free_items
(
thd
->
free_list
);
thd
->
free_list
=
free_list
=
0
;
/*
Must be last, as some memory might be allocated for free purposes,
like in free_tmp_table() (TODO: fix this issue)
*/
mem_root
=
thd
->
mem_root
;
free_root
(
&
mem_root
,
MYF
(
0
));
break
;
if
(
error
==
0
)
{
thd
->
server_status
|=
SERVER_STATUS_LAST_ROW_SENT
;
::
send_eof
(
thd
);
thd
->
server_status
&=
~
SERVER_STATUS_LAST_ROW_SENT
;
}
else
send_error
(
thd
,
ER_OUT_OF_RESOURCES
);
/* free cursor memory */
free_items
(
free_list
);
free_list
=
0
;
free_root
(
&
main_mem_root
,
MYF
(
0
));
}
return
error
;
}
...
...
@@ -1939,6 +1920,8 @@ Cursor::close()
thd
->
derived_tables
=
tmp_derived_tables
;
thd
->
lock
=
tmp_lock
;
}
join
=
0
;
unit
=
0
;
}
...
...
@@ -1951,7 +1934,7 @@ Cursor::~Cursor()
Must be last, as some memory might be allocated for free purposes,
like in free_tmp_table() (TODO: fix this issue)
*/
free_root
(
&
mem_root
,
MYF
(
0
));
free_root
(
&
m
ain_m
em_root
,
MYF
(
0
));
}
/*********************************************************************/
...
...
@@ -5030,7 +5013,7 @@ add_found_match_trig_cond(JOIN_TAB *tab, COND *cond, JOIN_TAB *root_tab)
{
tmp
=
new
Item_func_trig_cond
(
tmp
,
&
tab
->
found
);
}
if
(
!
tmp
)
if
(
tmp
)
tmp
->
quick_fix_field
();
return
tmp
;
}
...
...
@@ -5304,8 +5287,17 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
/* Join with outer join condition */
COND
*
orig_cond
=
sel
->
cond
;
sel
->
cond
=
and_conds
(
sel
->
cond
,
*
tab
->
on_expr_ref
);
/*
We can't call sel->cond->fix_fields,
as it will break tab->on_expr if it's AND condition
(fix_fields currently removes extra AND/OR levels).
Yet attributes of the just built condition are not needed.
Thus we call sel->cond->quick_fix_field for safety.
*/
if
(
sel
->
cond
&&
!
sel
->
cond
->
fixed
)
sel
->
cond
->
fix_fields
(
join
->
thd
,
0
,
&
sel
->
cond
);
sel
->
cond
->
quick_fix_field
();
if
(
sel
->
test_quick_select
(
join
->
thd
,
tab
->
keys
,
used_tables
&
~
current_map
,
(
join
->
select_options
&
...
...
@@ -6030,7 +6022,7 @@ template class List_iterator<Item_func_match>;
find_item_equal()
cond_equal multiple equalities to search in
field field to look for
inherited_fl :out set up to TRUE if
f
multiple equality is found
inherited_fl :out set up to TRUE if multiple equality is found
on upper levels (not on current level of cond_equal)
DESCRIPTION
...
...
@@ -6448,12 +6440,14 @@ static COND *build_equal_items_for_cond(COND *cond,
return
cond
;
}
/*
Build multiple equalities for a condition and all on expressions that
inherit these multiple equalities
SYNOPSIS
build_equal_items()
thd Thread handler
cond condition to build the multiple equalities for
inherited path to all inherited multiple equality items
join_list list of join tables to which the condition refers to
...
...
@@ -6505,7 +6499,7 @@ static COND *build_equal_items_for_cond(COND *cond,
pointer to the transformed condition containing multiple equalities
*/
static
COND
*
build_equal_items
(
COND
*
cond
,
static
COND
*
build_equal_items
(
THD
*
thd
,
COND
*
cond
,
COND_EQUAL
*
inherited
,
List
<
TABLE_LIST
>
*
join_list
,
COND_EQUAL
**
cond_equal_ref
)
...
...
@@ -6542,12 +6536,13 @@ static COND *build_equal_items(COND *cond,
{
if
(
table
->
on_expr
)
{
Item
*
expr
;
List
<
TABLE_LIST
>
*
join_list
=
table
->
nested_join
?
&
table
->
nested_join
->
join_list
:
NULL
;
table
->
on_expr
=
build_equal_items
(
table
->
on_expr
,
inherited
,
join_list
,
&
table
->
cond_equal
);
expr
=
build_equal_items
(
thd
,
table
->
on_expr
,
inherited
,
join_list
,
&
table
->
cond_equal
);
if
(
expr
!=
table
->
on_expr
)
thd
->
change_item_tree
(
&
table
->
on_expr
,
expr
);
}
}
}
...
...
@@ -6555,6 +6550,7 @@ static COND *build_equal_items(COND *cond,
return
cond
;
}
/*
Compare field items by table order in the execution plan
...
...
@@ -6649,10 +6645,7 @@ static Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
List
<
Item
>
eq_list
;
Item_func_eq
*
eq_item
=
0
;
if
(((
Item
*
)
item_equal
)
->
const_item
()
&&
!
item_equal
->
val_int
())
{
cond
=
new
Item_int
((
char
*
)
"FALSE"
,
0
,
1
);
return
cond
;
}
return
new
Item_int
((
longlong
)
0
,
1
);
Item
*
item_const
=
item_equal
->
get_const
();
Item_equal_iterator
it
(
*
item_equal
);
Item
*
head
;
...
...
@@ -6695,9 +6688,14 @@ static Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
}
if
(
!
cond
&&
!
eq_list
.
head
())
{
if
(
!
eq_item
)
return
new
Item_int
((
longlong
)
1
,
1
);
return
eq_item
;
}
eq_list
.
push_back
(
eq_item
);
if
(
eq_item
)
eq_list
.
push_back
(
eq_item
);
if
(
!
cond
)
cond
=
new
Item_cond_and
(
eq_list
);
else
...
...
@@ -6799,14 +6797,16 @@ static COND* substitute_for_best_equal_field(COND *cond,
return
cond
;
}
/*
change field = field to field = const for each found field = const in the
and_level
*/
static
void
change_cond_ref_to_const
(
I_List
<
COND_CMP
>
*
save_list
,
Item
*
and_father
,
Item
*
cond
,
Item
*
field
,
Item
*
value
)
change_cond_ref_to_const
(
THD
*
thd
,
I_List
<
COND_CMP
>
*
save_list
,
Item
*
and_father
,
Item
*
cond
,
Item
*
field
,
Item
*
value
)
{
if
(
cond
->
type
()
==
Item
::
COND_ITEM
)
{
...
...
@@ -6815,7 +6815,7 @@ change_cond_ref_to_const(I_List<COND_CMP> *save_list,Item *and_father,
List_iterator
<
Item
>
li
(
*
((
Item_cond
*
)
cond
)
->
argument_list
());
Item
*
item
;
while
((
item
=
li
++
))
change_cond_ref_to_const
(
save_list
,
and_level
?
cond
:
item
,
item
,
change_cond_ref_to_const
(
thd
,
save_list
,
and_level
?
cond
:
item
,
item
,
field
,
value
);
return
;
}
...
...
@@ -6823,8 +6823,9 @@ change_cond_ref_to_const(I_List<COND_CMP> *save_list,Item *and_father,
return
;
// Not a boolean function
Item_bool_func2
*
func
=
(
Item_bool_func2
*
)
cond
;
Item
*
left_item
=
func
->
arguments
()[
0
];
Item
*
right_item
=
func
->
arguments
()[
1
];
Item
**
args
=
func
->
arguments
();
Item
*
left_item
=
args
[
0
];
Item
*
right_item
=
args
[
1
];
Item_func
::
Functype
functype
=
func
->
functype
();
if
(
right_item
->
eq
(
field
,
0
)
&&
left_item
!=
value
&&
...
...
@@ -6835,7 +6836,7 @@ change_cond_ref_to_const(I_List<COND_CMP> *save_list,Item *and_father,
Item
*
tmp
=
value
->
new_item
();
if
(
tmp
)
{
func
->
arguments
()[
1
]
=
tmp
;
thd
->
change_item_tree
(
args
+
1
,
tmp
)
;
func
->
update_used_tables
();
if
((
functype
==
Item_func
::
EQ_FUNC
||
functype
==
Item_func
::
EQUAL_FUNC
)
&&
and_father
!=
cond
&&
!
left_item
->
const_item
())
...
...
@@ -6856,13 +6857,14 @@ change_cond_ref_to_const(I_List<COND_CMP> *save_list,Item *and_father,
Item
*
tmp
=
value
->
new_item
();
if
(
tmp
)
{
func
->
arguments
()[
0
]
=
value
=
tmp
;
thd
->
change_item_tree
(
args
,
tmp
);
value
=
tmp
;
func
->
update_used_tables
();
if
((
functype
==
Item_func
::
EQ_FUNC
||
functype
==
Item_func
::
EQUAL_FUNC
)
&&
and_father
!=
cond
&&
!
right_item
->
const_item
())
{
func
->
arguments
()[
0
]
=
func
->
arguments
()[
1
];
// For easy check
func
->
arguments
()[
1
]
=
value
;
args
[
0
]
=
args
[
1
];
// For easy check
thd
->
change_item_tree
(
args
+
1
,
value
)
;
cond
->
marker
=
1
;
COND_CMP
*
tmp2
;
if
((
tmp2
=
new
COND_CMP
(
and_father
,
func
)))
...
...
@@ -6908,8 +6910,8 @@ static Item *remove_additional_cond(Item* conds)
}
static
void
propagate_cond_constants
(
I_List
<
COND_CMP
>
*
save_list
,
COND
*
and_father
,
COND
*
cond
)
propagate_cond_constants
(
THD
*
thd
,
I_List
<
COND_CMP
>
*
save_list
,
COND
*
and_father
,
COND
*
cond
)
{
if
(
cond
->
type
()
==
Item
::
COND_ITEM
)
{
...
...
@@ -6920,18 +6922,19 @@ propagate_cond_constants(I_List<COND_CMP> *save_list,COND *and_father,
I_List
<
COND_CMP
>
save
;
while
((
item
=
li
++
))
{
propagate_cond_constants
(
&
save
,
and_level
?
cond
:
item
,
item
);
propagate_cond_constants
(
thd
,
&
save
,
and_level
?
cond
:
item
,
item
);
}
if
(
and_level
)
{
// Handle other found items
I_List_iterator
<
COND_CMP
>
cond_itr
(
save
);
COND_CMP
*
cond_cmp
;
while
((
cond_cmp
=
cond_itr
++
))
if
(
!
cond_cmp
->
cmp_func
->
arguments
()[
0
]
->
const_item
())
change_cond_ref_to_const
(
&
save
,
cond_cmp
->
and_level
,
cond_cmp
->
and_level
,
cond_cmp
->
cmp_func
->
arguments
()[
0
],
cond_cmp
->
cmp_func
->
arguments
()[
1
]);
{
Item
**
args
=
cond_cmp
->
cmp_func
->
arguments
();
if
(
!
args
[
0
]
->
const_item
())
change_cond_ref_to_const
(
thd
,
&
save
,
cond_cmp
->
and_level
,
cond_cmp
->
and_level
,
args
[
0
],
args
[
1
]);
}
}
}
else
if
(
and_father
!=
cond
&&
!
cond
->
marker
)
// In a AND group
...
...
@@ -6941,29 +6944,25 @@ propagate_cond_constants(I_List<COND_CMP> *save_list,COND *and_father,
((
Item_func
*
)
cond
)
->
functype
()
==
Item_func
::
EQUAL_FUNC
))
{
Item_func_eq
*
func
=
(
Item_func_eq
*
)
cond
;
bool
left_const
=
func
->
arguments
()[
0
]
->
const_item
();
bool
right_const
=
func
->
arguments
()[
1
]
->
const_item
();
Item
**
args
=
func
->
arguments
();
bool
left_const
=
args
[
0
]
->
const_item
();
bool
right_const
=
args
[
1
]
->
const_item
();
if
(
!
(
left_const
&&
right_const
)
&&
(
func
->
arguments
()[
0
]
->
result_type
()
==
(
func
->
arguments
()[
1
]
->
result_type
())))
args
[
0
]
->
result_type
()
==
args
[
1
]
->
result_type
())
{
if
(
right_const
)
{
func
->
arguments
()[
1
]
=
resolve_const_item
(
func
->
arguments
()[
1
],
func
->
arguments
()[
0
]);
resolve_const_item
(
thd
,
&
args
[
1
],
args
[
0
]);
func
->
update_used_tables
();
change_cond_ref_to_const
(
save_list
,
and_father
,
and_father
,
func
->
arguments
()[
0
],
func
->
arguments
()[
1
]);
change_cond_ref_to_const
(
thd
,
save_list
,
and_father
,
and_father
,
args
[
0
],
args
[
1
]);
}
else
if
(
left_const
)
{
func
->
arguments
()[
0
]
=
resolve_const_item
(
func
->
arguments
()[
0
],
func
->
arguments
()[
1
]);
resolve_const_item
(
thd
,
&
args
[
0
],
args
[
1
]);
func
->
update_used_tables
();
change_cond_ref_to_const
(
save_list
,
and_father
,
and_father
,
func
->
arguments
()[
1
],
func
->
arguments
()[
0
]);
change_cond_ref_to_const
(
thd
,
save_list
,
and_father
,
and_father
,
args
[
1
],
args
[
0
]);
}
}
}
...
...
@@ -7091,6 +7090,7 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
*/
if
(
table
->
on_expr
)
{
Item
*
expr
;
/*
If an on expression E is attached to the table,
check all null rejected predicates in this expression.
...
...
@@ -7099,8 +7099,9 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
the outer join is converted to an inner join and
the corresponding on expression is added to E.
*/
table
->
on_expr
=
simplify_joins
(
join
,
&
nested_join
->
join_list
,
table
->
on_expr
,
FALSE
);
expr
=
simplify_joins
(
join
,
&
nested_join
->
join_list
,
table
->
on_expr
,
FALSE
);
table
->
on_expr
=
expr
;
}
nested_join
->
used_tables
=
(
table_map
)
0
;
nested_join
->
not_null_tables
=
(
table_map
)
0
;
...
...
@@ -7209,8 +7210,10 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
DBUG_RETURN
(
conds
);
}
static
COND
*
optimize_cond
(
JOIN
*
join
,
COND
*
conds
,
Item
::
cond_result
*
cond_value
)
optimize_cond
(
JOIN
*
join
,
COND
*
conds
,
List
<
TABLE_LIST
>
*
join_list
,
Item
::
cond_result
*
cond_value
)
{
THD
*
thd
=
join
->
thd
;
SELECT_LEX
*
select
=
thd
->
lex
->
current_select
;
...
...
@@ -7223,9 +7226,21 @@ optimize_cond(JOIN *join, COND *conds, Item::cond_result *cond_value)
}
else
{
/*
Build all multiple equality predicates and eliminate equality
predicates that can be inferred from these multiple equalities.
For each reference of a field included into a multiple equality
that occurs in a function set a pointer to the multiple equality
predicate. Substitute a constant instead of this field if the
multiple equality contains a constant.
*/
DBUG_EXECUTE
(
"where"
,
print_where
(
conds
,
"original"
););
conds
=
build_equal_items
(
join
->
thd
,
conds
,
NULL
,
join_list
,
&
join
->
cond_equal
);
DBUG_EXECUTE
(
"where"
,
print_where
(
conds
,
"after equal_items"
););
/* change field = field to field = const for each found field = const */
propagate_cond_constants
(
(
I_List
<
COND_CMP
>
*
)
0
,
conds
,
conds
);
propagate_cond_constants
(
thd
,
(
I_List
<
COND_CMP
>
*
)
0
,
conds
,
conds
);
/*
Remove all instances of item == item
Remove all and-levels where CONST item != CONST item
...
...
@@ -7461,21 +7476,28 @@ const_expression_in_where(COND *cond, Item *comp_item, Item **const_item)
the record in the original table.
If modify_item is 0 then fill_record() will update
the temporary table
convert_blob_length If >0 create a varstring(convert_blob_length) field
instead of blob.
RETURN
0 on error
new_created field
*/
static
Field
*
create_tmp_field_from_field
(
THD
*
thd
,
Field
*
org_field
,
Item
*
item
,
TABLE
*
table
,
bool
modify_item
)
static
Field
*
create_tmp_field_from_field
(
THD
*
thd
,
Field
*
org_field
,
Item
*
item
,
TABLE
*
table
,
bool
modify_item
,
uint
convert_blob_length
)
{
Field
*
new_field
;
// The following should always be true
if
((
new_field
=
org_field
->
new_field
(
&
thd
->
mem_root
,
table
)))
if
(
convert_blob_length
&&
org_field
->
flags
&
BLOB_FLAG
)
new_field
=
new
Field_varstring
(
convert_blob_length
,
org_field
->
maybe_null
(),
org_field
->
field_name
,
table
,
org_field
->
charset
());
else
new_field
=
org_field
->
new_field
(
thd
->
mem_root
,
table
);
if
(
new_field
)
{
if
(
modify_item
)
((
Item_field
*
)
item
)
->
result_field
=
new_field
;
...
...
@@ -7506,16 +7528,16 @@ static Field* create_tmp_field_from_field(THD *thd,
the record in the original table.
If modify_item is 0 then fill_record() will update
the temporary table
convert_blob_length If >0 create a varstring(convert_blob_length) field
instead of blob.
RETURN
0 on error
new_created field
*/
static
Field
*
create_tmp_field_from_item
(
THD
*
thd
,
Item
*
item
,
TABLE
*
table
,
Item
***
copy_func
,
bool
modify_item
)
static
Field
*
create_tmp_field_from_item
(
THD
*
thd
,
Item
*
item
,
TABLE
*
table
,
Item
***
copy_func
,
bool
modify_item
,
uint
convert_blob_length
)
{
bool
maybe_null
=
item
->
maybe_null
;
Field
*
new_field
;
...
...
@@ -7532,13 +7554,18 @@ static Field* create_tmp_field_from_item(THD *thd,
break
;
case
STRING_RESULT
:
if
(
item
->
max_length
>
255
)
new_field
=
new
Field_blob
(
item
->
max_length
,
maybe_null
,
item
->
name
,
table
,
item
->
collation
.
collation
);
{
if
(
convert_blob_length
)
new_field
=
new
Field_varstring
(
convert_blob_length
,
maybe_null
,
item
->
name
,
table
,
item
->
collation
.
collation
);
else
new_field
=
new
Field_blob
(
item
->
max_length
,
maybe_null
,
item
->
name
,
table
,
item
->
collation
.
collation
);
}
else
new_field
=
new
Field_string
(
item
->
max_length
,
maybe_null
,
item
->
name
,
table
,
item
->
collation
.
collation
);
new_field
=
new
Field_string
(
item
->
max_length
,
maybe_null
,
item
->
name
,
table
,
item
->
collation
.
collation
);
break
;
case
ROW_RESULT
:
default:
...
...
@@ -7575,6 +7602,8 @@ static Field* create_tmp_field_from_item(THD *thd,
the record in the original table.
If modify_item is 0 then fill_record() will update
the temporary table
convert_blob_length If >0 create a varstring(convert_blob_length) field
instead of blob.
RETURN
0 on error
...
...
@@ -7582,8 +7611,8 @@ static Field* create_tmp_field_from_item(THD *thd,
*/
Field
*
create_tmp_field
(
THD
*
thd
,
TABLE
*
table
,
Item
*
item
,
Item
::
Type
type
,
Item
***
copy_func
,
Field
**
from_field
,
bool
group
,
bool
modify_item
)
Item
***
copy_func
,
Field
**
from_field
,
bool
group
,
bool
modify_item
,
uint
convert_blob_length
)
{
switch
(
type
)
{
case
Item
:
:
SUM_FUNC_ITEM
:
...
...
@@ -7618,8 +7647,15 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
item
->
name
,
table
,
item
->
unsigned_flag
);
case
STRING_RESULT
:
if
(
item_sum
->
max_length
>
255
)
return
new
Field_blob
(
item_sum
->
max_length
,
maybe_null
,
item
->
name
,
table
,
item
->
collation
.
collation
);
{
if
(
convert_blob_length
)
return
new
Field_varstring
(
convert_blob_length
,
maybe_null
,
item
->
name
,
table
,
item
->
collation
.
collation
);
else
return
new
Field_blob
(
item_sum
->
max_length
,
maybe_null
,
item
->
name
,
table
,
item
->
collation
.
collation
);
}
return
new
Field_string
(
item_sum
->
max_length
,
maybe_null
,
item
->
name
,
table
,
item
->
collation
.
collation
);
case
ROW_RESULT
:
...
...
@@ -7636,8 +7672,8 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
case
Item
:
:
DEFAULT_VALUE_ITEM
:
{
Item_field
*
field
=
(
Item_field
*
)
item
;
return
create_tmp_field_from_field
(
thd
,
(
*
from_field
=
field
->
field
),
item
,
table
,
modify_item
);
return
create_tmp_field_from_field
(
thd
,
(
*
from_field
=
field
->
field
),
item
,
table
,
modify_item
,
convert_blob_length
);
}
case
Item
:
:
FUNC_ITEM
:
case
Item
:
:
COND_ITEM
:
...
...
@@ -7652,14 +7688,16 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
case
Item
:
:
REF_ITEM
:
case
Item
:
:
NULL_ITEM
:
case
Item
:
:
VARBIN_ITEM
:
return
create_tmp_field_from_item
(
thd
,
item
,
table
,
copy_func
,
modify_item
);
return
create_tmp_field_from_item
(
thd
,
item
,
table
,
copy_func
,
modify_item
,
convert_blob_length
);
case
Item
:
:
TYPE_HOLDER
:
{
Field
*
example
=
((
Item_type_holder
*
)
item
)
->
example
();
if
(
example
)
return
create_tmp_field_from_field
(
thd
,
example
,
item
,
table
,
0
);
return
create_tmp_field_from_item
(
thd
,
item
,
table
,
copy_func
,
0
);
return
create_tmp_field_from_field
(
thd
,
example
,
item
,
table
,
0
,
convert_blob_length
);
return
create_tmp_field_from_item
(
thd
,
item
,
table
,
copy_func
,
0
,
convert_blob_length
);
}
default:
// Dosen't have to be stored
return
0
;
...
...
@@ -7818,12 +7856,14 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
((
Item_sum
*
)
item
)
->
result_field
=
0
;
for
(
i
=
0
;
i
<
((
Item_sum
*
)
item
)
->
arg_count
;
i
++
)
{
Item
*
arg
=
((
Item_sum
*
)
item
)
->
args
[
i
];
Item
**
argp
=
((
Item_sum
*
)
item
)
->
args
+
i
;
Item
*
arg
=
*
argp
;
if
(
!
arg
->
const_item
())
{
Field
*
new_field
=
create_tmp_field
(
thd
,
table
,
arg
,
arg
->
type
(),
&
copy_func
,
tmp_from_field
,
group
!=
0
,
not_all_columns
);
create_tmp_field
(
thd
,
table
,
arg
,
arg
->
type
(),
&
copy_func
,
tmp_from_field
,
group
!=
0
,
not_all_columns
,
param
->
convert_blob_length
);
if
(
!
new_field
)
goto
err
;
// Should be OOM
tmp_from_field
++
;
...
...
@@ -7834,7 +7874,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
*
blob_field
++=
new_field
;
blob_count
++
;
}
((
Item_sum
*
)
item
)
->
args
[
i
]
=
new
Item_field
(
new_field
);
thd
->
change_item_tree
(
argp
,
new
Item_field
(
new_field
)
);
if
(
!
(
new_field
->
flags
&
NOT_NULL_FLAG
))
{
null_count
++
;
...
...
@@ -7842,7 +7882,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
new_field->maybe_null() is still false, it will be
changed below. But we have to setup Item_field correctly
*/
(
(
Item_sum
*
)
item
)
->
args
[
i
]
->
maybe_null
=
1
;
(
*
argp
)
->
maybe_null
=
1
;
}
}
}
...
...
@@ -7859,9 +7899,10 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
We here distinguish between UNION and multi-table-updates by the fact
that in the later case group is set to the row pointer.
*/
Field
*
new_field
=
create_tmp_field
(
thd
,
table
,
item
,
type
,
&
copy_func
,
tmp_from_field
,
group
!=
0
,
not_all_columns
||
group
!=
0
);
Field
*
new_field
=
create_tmp_field
(
thd
,
table
,
item
,
type
,
&
copy_func
,
tmp_from_field
,
group
!=
0
,
not_all_columns
||
group
!=
0
,
param
->
convert_blob_length
);
if
(
!
new_field
)
{
if
(
thd
->
is_fatal_error
)
...
...
@@ -8058,7 +8099,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
if
(
!
using_unique_constraint
)
{
group
->
buff
=
(
char
*
)
group_buff
;
if
(
!
(
group
->
field
=
field
->
new_field
(
&
thd
->
mem_root
,
table
)))
if
(
!
(
group
->
field
=
field
->
new_field
(
thd
->
mem_root
,
table
)))
goto
err
;
/* purecov: inspected */
if
(
maybe_null
)
{
...
...
@@ -8569,7 +8610,7 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
DBUG_PRINT
(
"error"
,(
"Error: do_select() failed"
));
}
#endif
DBUG_RETURN
(
error
||
join
->
thd
->
net
.
report_
error
);
DBUG_RETURN
(
join
->
thd
->
net
.
report_error
?
-
1
:
error
);
}
...
...
@@ -9050,6 +9091,7 @@ join_read_const_table(JOIN_TAB *tab, POSITION *pos)
{
table
->
key_read
=
1
;
table
->
file
->
extra
(
HA_EXTRA_KEYREAD
);
tab
->
index
=
tab
->
ref
.
key
;
}
if
((
error
=
join_read_const
(
tab
)))
{
...
...
@@ -10037,10 +10079,23 @@ part_of_refkey(TABLE *table,Field *field)
/*****************************************************************************
Test if one can use the key to resolve ORDER BY
Returns: 1 if key is ok.
0 if key can't be used
-1 if reverse key can be used
used_key_parts is set to key parts used if length != 0
SYNOPSIS
test_if_order_by_key()
order Sort order
table Table to sort
idx Index to check
used_key_parts Return value for used key parts.
NOTES
used_key_parts is set to correct key parts used if return value != 0
(On other cases, used_key_part may be changed)
RETURN
1 key is ok.
0 Key can't be used
-1 Reverse key can be used
*****************************************************************************/
static
int
test_if_order_by_key
(
ORDER
*
order
,
TABLE
*
table
,
uint
idx
,
...
...
@@ -10069,13 +10124,17 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
DBUG_RETURN
(
0
);
/* set flag to 1 if we can use read-next on key, else to -1 */
flag
=
((
order
->
asc
==
!
(
key_part
->
key_part_flag
&
HA_REVERSE_SORT
))
?
1
:
-
1
);
flag
=
((
order
->
asc
==
!
(
key_part
->
key_part_flag
&
HA_REVERSE_SORT
))
?
1
:
-
1
);
if
(
reverse
&&
flag
!=
reverse
)
DBUG_RETURN
(
0
);
reverse
=
flag
;
// Remember if reverse
key_part
++
;
}
*
used_key_parts
=
(
uint
)
(
key_part
-
table
->
key_info
[
idx
].
key_part
);
if
(
reverse
==
-
1
&&
!
(
table
->
file
->
index_flags
(
idx
,
*
used_key_parts
-
1
,
1
)
&
HA_READ_PREV
))
reverse
=
0
;
// Index can't be used
DBUG_RETURN
(
reverse
);
}
...
...
@@ -10288,14 +10347,11 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
if
(
!
select
->
quick
->
reverse_sorted
())
{
int
quick_type
=
select
->
quick
->
get_type
();
/* here used_key_parts >0 */
if
(
!
(
table
->
file
->
index_flags
(
ref_key
,
used_key_parts
-
1
,
1
)
&
HA_READ_PREV
)
||
quick_type
==
QUICK_SELECT_I
::
QS_TYPE_INDEX_MERGE
||
if
(
quick_type
==
QUICK_SELECT_I
::
QS_TYPE_INDEX_MERGE
||
quick_type
==
QUICK_SELECT_I
::
QS_TYPE_ROR_INTERSECT
||
quick_type
==
QUICK_SELECT_I
::
QS_TYPE_ROR_UNION
||
quick_type
==
QUICK_SELECT_I
::
QS_TYPE_GROUP_MIN_MAX
)
DBUG_RETURN
(
0
);
// Use filesort
DBUG_RETURN
(
0
);
// Use filesort
/* ORDER BY range_key DESC */
QUICK_SELECT_DESC
*
tmp
=
new
QUICK_SELECT_DESC
((
QUICK_RANGE_SELECT
*
)(
select
->
quick
),
...
...
@@ -10317,9 +10373,6 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
Use a traversal function that starts by reading the last row
with key part (A) and then traverse the index backwards.
*/
if
(
!
(
table
->
file
->
index_flags
(
ref_key
,
used_key_parts
-
1
,
1
)
&
HA_READ_PREV
))
DBUG_RETURN
(
0
);
// Use filesort
tab
->
read_first_record
=
join_read_last_key
;
tab
->
read_record
.
read_record
=
join_read_prev_same
;
/* fall through */
...
...
@@ -10365,7 +10418,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
if
(
keys
.
is_set
(
nr
))
{
int
flag
;
if
((
flag
=
test_if_order_by_key
(
order
,
table
,
nr
,
&
not_used
)))
if
((
flag
=
test_if_order_by_key
(
order
,
table
,
nr
,
&
not_used
)))
{
if
(
!
no_changes
)
{
...
...
@@ -11150,7 +11203,7 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
ORDER
*
order
,
List
<
Item
>
&
fields
,
List
<
Item
>
&
all_fields
,
bool
is_group_field
)
{
Item
*
order_item
=*
order
->
item
;
/* The item from the GROUP/ORDER caluse. */
Item
*
order_item
=
*
order
->
item
;
/* The item from the GROUP/ORDER caluse. */
Item
::
Type
order_item_type
;
Item
**
select_item
;
/* The corresponding item from the SELECT clause. */
Field
*
from_field
;
/* The corresponding field from the FROM clause. */
...
...
@@ -11161,8 +11214,7 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
if
(
!
count
||
count
>
fields
.
elements
)
{
my_printf_error
(
ER_BAD_FIELD_ERROR
,
ER
(
ER_BAD_FIELD_ERROR
),
MYF
(
0
),
order_item
->
full_name
(),
thd
->
where
);
MYF
(
0
),
order_item
->
full_name
(),
thd
->
where
);
return
1
;
}
order
->
item
=
ref_pointer_array
+
count
-
1
;
...
...
@@ -11173,8 +11225,9 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
}
/* Lookup the current GROUP/ORDER field in the SELECT clause. */
uint
counter
;
bool
unaliased
;
select_item
=
find_item_in_list
(
order_item
,
fields
,
&
counter
,
REPORT_EXCEPT_NOT_FOUND
);
REPORT_EXCEPT_NOT_FOUND
,
&
unaliased
);
if
(
!
select_item
)
return
1
;
/* Some error occured. */
...
...
@@ -11182,6 +11235,14 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
/* Check whether the resolved field is not ambiguos. */
if
(
select_item
!=
not_found_item
)
{
/*
If we have found field not by its alias in select list but by its
original field name, we should additionaly check if we have conflict
for this name (in case if we would perform lookup in all tables).
*/
if
(
unaliased
&&
!
order_item
->
fixed
&&
order_item
->
fix_fields
(
thd
,
tables
,
order
->
item
))
return
1
;
/* Lookup the current GROUP field in the FROM clause. */
order_item_type
=
order_item
->
type
();
if
(
is_group_field
&&
...
...
@@ -11215,16 +11276,15 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
}
order
->
in_field_list
=
0
;
Item
*
it
=
*
order
->
item
;
/*
We check
it
->fixed because Item_func_group_concat can put
We check
order_item
->fixed because Item_func_group_concat can put
arguments for which fix_fields already was called.
'it' reassigned in if condition because fix_field can change it.
*/
if
(
!
it
->
fixed
&&
(
it
->
fix_fields
(
thd
,
tables
,
order
->
item
)
||
(
it
=
*
order
->
item
)
->
check_cols
(
1
)
||
if
(
!
order_item
->
fixed
&&
(
order_item
->
fix_fields
(
thd
,
tables
,
order
->
item
)
||
(
order_item
=
*
order
->
item
)
->
check_cols
(
1
)
||
thd
->
is_fatal_error
))
return
1
;
// Wrong field
uint
el
=
all_fields
.
elements
;
...
...
@@ -11234,6 +11294,7 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
return
0
;
}
/*
Change order to point at item in select list. If item isn't a number
and doesn't exits in the select list, add it the the field list.
...
...
@@ -11344,10 +11405,11 @@ setup_new_fields(THD *thd,TABLE_LIST *tables,List<Item> &fields,
thd
->
set_query_id
=
1
;
// Not really needed, but...
uint
counter
;
bool
not_used
;
for
(;
new_field
;
new_field
=
new_field
->
next
)
{
if
((
item
=
find_item_in_list
(
*
new_field
->
item
,
fields
,
&
counter
,
IGNORE_ERRORS
)))
IGNORE_ERRORS
,
&
not_used
)))
new_field
->
item
=
item
;
/* Change to shared Item */
else
{
...
...
@@ -11695,7 +11757,7 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
saved value
*/
Field
*
field
=
item
->
field
;
item
->
result_field
=
field
->
new_field
(
&
thd
->
mem_root
,
field
->
table
);
item
->
result_field
=
field
->
new_field
(
thd
->
mem_root
,
field
->
table
);
char
*
tmp
=
(
char
*
)
sql_alloc
(
field
->
pack_length
()
+
1
);
if
(
!
tmp
)
goto
err
;
...
...
@@ -11705,6 +11767,8 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
}
}
else
if
((
pos
->
type
()
==
Item
::
FUNC_ITEM
||
pos
->
type
()
==
Item
::
SUBSELECT_ITEM
||
pos
->
type
()
==
Item
::
CACHE_ITEM
||
pos
->
type
()
==
Item
::
COND_ITEM
)
&&
!
pos
->
with_sum_func
)
{
// Save for send fields
...
...
@@ -11812,9 +11876,6 @@ bool JOIN::alloc_func_list()
before_group_by Set to 1 if this is called before GROUP BY handling
recompute Set to TRUE if sum_funcs must be recomputed
NOTES
Calls ::setup() for all item_sum objects in field_list
RETURN
0 ok
1 error
...
...
@@ -11835,12 +11896,7 @@ bool JOIN::make_sum_func_list(List<Item> &field_list, List<Item> &send_fields,
while
((
item
=
it
++
))
{
if
(
item
->
type
()
==
Item
::
SUM_FUNC_ITEM
&&
!
item
->
const_item
())
{
*
func
++=
(
Item_sum
*
)
item
;
/* let COUNT(DISTINCT) create the temporary table */
if
(((
Item_sum
*
)
item
)
->
setup
(
thd
))
DBUG_RETURN
(
TRUE
);
}
}
if
(
before_group_by
&&
rollup
.
state
==
ROLLUP
::
STATE_INITED
)
{
...
...
@@ -11985,6 +12041,30 @@ change_refs_to_tmp_fields(THD *thd, Item **ref_pointer_array,
Code for calculating functions
******************************************************************************/
/*
Call ::setup for all sum functions
SYNOPSIS
setup_sum_funcs()
thd thread handler
func_ptr sum function list
RETURN
FALSE ok
TRUE error
*/
static
bool
setup_sum_funcs
(
THD
*
thd
,
Item_sum
**
func_ptr
)
{
Item_sum
*
func
;
while
((
func
=
*
(
func_ptr
++
)))
if
(
func
->
setup
(
thd
))
return
TRUE
;
return
FALSE
;
}
static
void
init_tmptable_sum_functions
(
Item_sum
**
func_ptr
)
{
...
...
@@ -12140,7 +12220,7 @@ bool JOIN::rollup_init()
return
1
;
rollup
.
ref_pointer_arrays
=
(
Item
***
)
(
rollup
.
fields
+
send_group_parts
);
ref_array
=
(
Item
**
)
(
rollup
.
ref_pointer_arrays
+
send_group_parts
);
rollup
.
item_null
=
new
(
&
thd
->
mem_root
)
Item_null
();
rollup
.
item_null
=
new
(
thd
->
mem_root
)
Item_null
();
/*
Prepare space for field list for the different levels
...
...
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