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
c7396f8d
Commit
c7396f8d
authored
May 20, 2004
by
bell@sanja.is.com.ua
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
PS and SP made compatible in mechanism used for preparing query for rexecutions (Bug #2266)
parent
96207156
Changes
22
Show whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
302 additions
and
271 deletions
+302
-271
mysql-test/r/sp.result
mysql-test/r/sp.result
+10
-0
mysql-test/t/sp.test
mysql-test/t/sp.test
+12
-0
sql/item_subselect.cc
sql/item_subselect.cc
+21
-21
sql/item_subselect.h
sql/item_subselect.h
+3
-3
sql/item_sum.cc
sql/item_sum.cc
+4
-4
sql/item_sum.h
sql/item_sum.h
+3
-1
sql/mysql_priv.h
sql/mysql_priv.h
+1
-0
sql/sp_head.cc
sql/sp_head.cc
+32
-104
sql/sp_head.h
sql/sp_head.h
+1
-3
sql/sql_base.cc
sql/sql_base.cc
+40
-27
sql/sql_class.cc
sql/sql_class.cc
+39
-16
sql/sql_class.h
sql/sql_class.h
+54
-39
sql/sql_delete.cc
sql/sql_delete.cc
+7
-1
sql/sql_derived.cc
sql/sql_derived.cc
+1
-1
sql/sql_insert.cc
sql/sql_insert.cc
+1
-0
sql/sql_lex.cc
sql/sql_lex.cc
+10
-6
sql/sql_lex.h
sql/sql_lex.h
+6
-2
sql/sql_parse.cc
sql/sql_parse.cc
+2
-0
sql/sql_prepare.cc
sql/sql_prepare.cc
+21
-32
sql/sql_select.cc
sql/sql_select.cc
+12
-0
sql/sql_union.cc
sql/sql_union.cc
+13
-8
sql/sql_update.cc
sql/sql_update.cc
+9
-3
No files found.
mysql-test/r/sp.result
View file @
c7396f8d
...
@@ -1305,3 +1305,13 @@ test bar PROCEDURE root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINE
...
@@ -1305,3 +1305,13 @@ test bar PROCEDURE root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINE
drop procedure bar|
drop procedure bar|
drop table t1;
drop table t1;
drop table t2;
drop table t2;
create procedure p1 () select (select s1 from t1) from t1;
create table t1 (s1 int);
call p1();
(select s1 from t1)
insert into t1 values (1);
call p1();
(select s1 from t1)
1
drop procedure p1;
drop table t1;
mysql-test/t/sp.test
View file @
c7396f8d
...
@@ -1444,3 +1444,15 @@ drop procedure bar|
...
@@ -1444,3 +1444,15 @@ drop procedure bar|
delimiter
;
|
delimiter
;
|
drop
table
t1
;
drop
table
t1
;
drop
table
t2
;
drop
table
t2
;
#
# rexecution
#
create
procedure
p1
()
select
(
select
s1
from
t1
)
from
t1
;
create
table
t1
(
s1
int
);
call
p1
();
insert
into
t1
values
(
1
);
call
p1
();
drop
procedure
p1
;
drop
table
t1
;
sql/item_subselect.cc
View file @
c7396f8d
...
@@ -104,7 +104,7 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref)
...
@@ -104,7 +104,7 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref)
{
{
DBUG_ASSERT
(
fixed
==
0
);
DBUG_ASSERT
(
fixed
==
0
);
engine
->
set_thd
((
thd
=
thd_param
));
engine
->
set_thd
((
thd
=
thd_param
));
stmt
=
thd
->
current_statement
;
arena
=
thd
->
current_arena
;
char
const
*
save_where
=
thd
->
where
;
char
const
*
save_where
=
thd
->
where
;
int
res
=
engine
->
prepare
();
int
res
=
engine
->
prepare
();
...
@@ -316,8 +316,8 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
...
@@ -316,8 +316,8 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
if
(
join
->
conds
||
join
->
having
)
if
(
join
->
conds
||
join
->
having
)
{
{
Item
*
cond
;
Item
*
cond
;
if
(
stmt
)
if
(
arena
)
thd
->
set_n_backup_item_arena
(
stmt
,
&
backup
);
thd
->
set_n_backup_item_arena
(
arena
,
&
backup
);
if
(
!
join
->
having
)
if
(
!
join
->
having
)
cond
=
join
->
conds
;
cond
=
join
->
conds
;
...
@@ -330,15 +330,15 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
...
@@ -330,15 +330,15 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
new
Item_null
())))
new
Item_null
())))
goto
err
;
goto
err
;
}
}
if
(
stmt
)
if
(
arena
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
return
RES_REDUCE
;
return
RES_REDUCE
;
}
}
return
RES_OK
;
return
RES_OK
;
err:
err:
if
(
stmt
)
if
(
arena
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
return
RES_ERROR
;
return
RES_ERROR
;
}
}
...
@@ -618,8 +618,8 @@ Item_in_subselect::single_value_transformer(JOIN *join,
...
@@ -618,8 +618,8 @@ Item_in_subselect::single_value_transformer(JOIN *join,
Statement
backup
;
Statement
backup
;
thd
->
where
=
"scalar IN/ALL/ANY subquery"
;
thd
->
where
=
"scalar IN/ALL/ANY subquery"
;
if
(
stmt
)
if
(
arena
)
thd
->
set_n_backup_item_arena
(
stmt
,
&
backup
);
thd
->
set_n_backup_item_arena
(
arena
,
&
backup
);
if
(
select_lex
->
item_list
.
elements
>
1
)
if
(
select_lex
->
item_list
.
elements
>
1
)
{
{
...
@@ -823,21 +823,21 @@ Item_in_subselect::single_value_transformer(JOIN *join,
...
@@ -823,21 +823,21 @@ Item_in_subselect::single_value_transformer(JOIN *join,
push_warning
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_NOTE
,
push_warning
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_NOTE
,
ER_SELECT_REDUCED
,
warn_buff
);
ER_SELECT_REDUCED
,
warn_buff
);
}
}
if
(
stmt
)
if
(
arena
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
DBUG_RETURN
(
RES_REDUCE
);
DBUG_RETURN
(
RES_REDUCE
);
}
}
}
}
}
}
ok:
ok:
if
(
stmt
)
if
(
arena
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
DBUG_RETURN
(
RES_OK
);
DBUG_RETURN
(
RES_OK
);
err:
err:
if
(
stmt
)
if
(
arena
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
DBUG_RETURN
(
RES_ERROR
);
DBUG_RETURN
(
RES_ERROR
);
}
}
...
@@ -855,8 +855,8 @@ Item_in_subselect::row_value_transformer(JOIN *join)
...
@@ -855,8 +855,8 @@ Item_in_subselect::row_value_transformer(JOIN *join)
Item
*
item
=
0
;
Item
*
item
=
0
;
thd
->
where
=
"row IN/ALL/ANY subquery"
;
thd
->
where
=
"row IN/ALL/ANY subquery"
;
if
(
stmt
)
if
(
arena
)
thd
->
set_n_backup_item_arena
(
stmt
,
&
backup
);
thd
->
set_n_backup_item_arena
(
arena
,
&
backup
);
SELECT_LEX
*
select_lex
=
join
->
select_lex
;
SELECT_LEX
*
select_lex
=
join
->
select_lex
;
...
@@ -940,13 +940,13 @@ Item_in_subselect::row_value_transformer(JOIN *join)
...
@@ -940,13 +940,13 @@ Item_in_subselect::row_value_transformer(JOIN *join)
if
(
join
->
conds
->
fix_fields
(
thd
,
join
->
tables_list
,
0
))
if
(
join
->
conds
->
fix_fields
(
thd
,
join
->
tables_list
,
0
))
goto
err
;
goto
err
;
}
}
if
(
stmt
)
if
(
arena
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
DBUG_RETURN
(
RES_OK
);
DBUG_RETURN
(
RES_OK
);
err:
err:
if
(
stmt
)
if
(
arena
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
DBUG_RETURN
(
RES_ERROR
);
DBUG_RETURN
(
RES_ERROR
);
}
}
...
...
sql/item_subselect.h
View file @
c7396f8d
...
@@ -26,7 +26,7 @@ class JOIN;
...
@@ -26,7 +26,7 @@ class JOIN;
class
select_subselect
;
class
select_subselect
;
class
subselect_engine
;
class
subselect_engine
;
class
Item_bool_func2
;
class
Item_bool_func2
;
class
Statement
;
class
Item_arena
;
/* base class for subselects */
/* base class for subselects */
...
@@ -36,8 +36,8 @@ class Item_subselect :public Item_result_field
...
@@ -36,8 +36,8 @@ class Item_subselect :public Item_result_field
protected:
protected:
/* thread handler, will be assigned in fix_fields only */
/* thread handler, will be assigned in fix_fields only */
THD
*
thd
;
THD
*
thd
;
/*
prepared statement,
or 0 */
/*
Item_arena used
or 0 */
Statement
*
stmt
;
Item_arena
*
arena
;
/* substitution instead of subselect in case of optimization */
/* substitution instead of subselect in case of optimization */
Item
*
substitution
;
Item
*
substitution
;
/* unit of subquery */
/* unit of subquery */
...
...
sql/item_sum.cc
View file @
c7396f8d
...
@@ -77,15 +77,15 @@ Item_sum::Item_sum(THD *thd, Item_sum *item):
...
@@ -77,15 +77,15 @@ Item_sum::Item_sum(THD *thd, Item_sum *item):
*/
*/
bool
Item_sum
::
save_args_for_prepared_statements
(
THD
*
thd
)
bool
Item_sum
::
save_args_for_prepared_statements
(
THD
*
thd
)
{
{
if
(
thd
->
current_
statement
)
if
(
thd
->
current_
arena
&&
args_copy
==
0
)
return
save_args
(
thd
->
current_
statement
);
return
save_args
(
thd
->
current_
arena
);
return
0
;
return
0
;
}
}
bool
Item_sum
::
save_args
(
Statement
*
stmt
)
bool
Item_sum
::
save_args
(
Item_arena
*
arena
)
{
{
if
(
!
(
args_copy
=
(
Item
**
)
stmt
->
alloc
(
sizeof
(
Item
*
)
*
arg_count
)))
if
(
!
(
args_copy
=
(
Item
**
)
arena
->
alloc
(
sizeof
(
Item
*
)
*
arg_count
)))
return
1
;
return
1
;
memcpy
(
args_copy
,
args
,
sizeof
(
Item
*
)
*
arg_count
);
memcpy
(
args_copy
,
args
,
sizeof
(
Item
*
)
*
arg_count
);
return
0
;
return
0
;
...
...
sql/item_sum.h
View file @
c7396f8d
...
@@ -23,6 +23,8 @@
...
@@ -23,6 +23,8 @@
#include <my_tree.h>
#include <my_tree.h>
class
Item_arena
;
class
Item_sum
:
public
Item_result_field
class
Item_sum
:
public
Item_result_field
{
{
public:
public:
...
@@ -93,7 +95,7 @@ class Item_sum :public Item_result_field
...
@@ -93,7 +95,7 @@ class Item_sum :public Item_result_field
virtual
void
make_unique
()
{}
virtual
void
make_unique
()
{}
Item
*
get_tmp_table_item
(
THD
*
thd
);
Item
*
get_tmp_table_item
(
THD
*
thd
);
bool
save_args_for_prepared_statements
(
THD
*
);
bool
save_args_for_prepared_statements
(
THD
*
);
bool
save_args
(
Statement
*
stmt
);
bool
save_args
(
Item_arena
*
stmt
);
bool
walk
(
Item_processor
processor
,
byte
*
argument
);
bool
walk
(
Item_processor
processor
,
byte
*
argument
);
};
};
...
...
sql/mysql_priv.h
View file @
c7396f8d
...
@@ -681,6 +681,7 @@ void mysql_stmt_reset(THD *thd, char *packet);
...
@@ -681,6 +681,7 @@ void mysql_stmt_reset(THD *thd, char *packet);
void
mysql_stmt_get_longdata
(
THD
*
thd
,
char
*
pos
,
ulong
packet_length
);
void
mysql_stmt_get_longdata
(
THD
*
thd
,
char
*
pos
,
ulong
packet_length
);
int
check_insert_fields
(
THD
*
thd
,
TABLE
*
table
,
List
<
Item
>
&
fields
,
int
check_insert_fields
(
THD
*
thd
,
TABLE
*
table
,
List
<
Item
>
&
fields
,
List
<
Item
>
&
values
,
ulong
counter
);
List
<
Item
>
&
values
,
ulong
counter
);
void
reset_stmt_for_execute
(
THD
*
thd
,
LEX
*
lex
);
/* sql_error.cc */
/* sql_error.cc */
MYSQL_ERROR
*
push_warning
(
THD
*
thd
,
MYSQL_ERROR
::
enum_warning_level
level
,
uint
code
,
MYSQL_ERROR
*
push_warning
(
THD
*
thd
,
MYSQL_ERROR
::
enum_warning_level
level
,
uint
code
,
...
...
sql/sp_head.cc
View file @
c7396f8d
...
@@ -186,8 +186,8 @@ sp_head::operator new(size_t size)
...
@@ -186,8 +186,8 @@ sp_head::operator new(size_t size)
bzero
((
char
*
)
&
own_root
,
sizeof
(
own_root
));
bzero
((
char
*
)
&
own_root
,
sizeof
(
own_root
));
init_alloc_root
(
&
own_root
,
MEM_ROOT_BLOCK_SIZE
,
MEM_ROOT_PREALLOC
);
init_alloc_root
(
&
own_root
,
MEM_ROOT_BLOCK_SIZE
,
MEM_ROOT_PREALLOC
);
sp
=
(
sp_head
*
)
alloc_root
(
&
own_root
,
size
);
sp
=
(
sp_head
*
)
alloc_root
(
&
own_root
,
size
);
sp
->
m
_m
em_root
=
own_root
;
sp
->
mem_root
=
own_root
;
DBUG_PRINT
(
"info"
,
(
"mem_root 0x%lx"
,
(
ulong
)
&
sp
->
mem_root
));
DBUG_RETURN
(
sp
);
DBUG_RETURN
(
sp
);
}
}
...
@@ -198,16 +198,18 @@ sp_head::operator delete(void *ptr, size_t size)
...
@@ -198,16 +198,18 @@ sp_head::operator delete(void *ptr, size_t size)
MEM_ROOT
own_root
;
MEM_ROOT
own_root
;
sp_head
*
sp
=
(
sp_head
*
)
ptr
;
sp_head
*
sp
=
(
sp_head
*
)
ptr
;
DBUG_PRINT
(
"info"
,
(
"root: %lx"
,
&
sp
->
m_mem_root
));
memcpy
(
&
own_root
,
(
const
void
*
)
&
sp
->
mem_root
,
sizeof
(
MEM_ROOT
));
memcpy
(
&
own_root
,
(
const
void
*
)
&
sp
->
m_mem_root
,
sizeof
(
MEM_ROOT
));
DBUG_PRINT
(
"info"
,
(
"mem_root 0x%lx moved to 0x%lx"
,
(
ulong
)
&
sp
->
mem_root
,
(
ulong
)
&
own_root
));
free_root
(
&
own_root
,
MYF
(
0
));
free_root
(
&
own_root
,
MYF
(
0
));
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
sp_head
::
sp_head
()
sp_head
::
sp_head
()
:
Sql_alloc
(),
m_returns_cs
(
NULL
),
m_has_return
(
FALSE
),
m_simple_case
(
FALSE
),
:
Item_arena
((
bool
)
FALSE
),
m_returns_cs
(
NULL
),
m_has_return
(
FALSE
),
m_multi_results
(
FALSE
),
m_free_list
(
NULL
)
m_simple_case
(
FALSE
),
m_multi_results
(
FALSE
)
{
{
DBUG_ENTER
(
"sp_head::sp_head"
);
DBUG_ENTER
(
"sp_head::sp_head"
);
...
@@ -216,6 +218,7 @@ sp_head::sp_head()
...
@@ -216,6 +218,7 @@ sp_head::sp_head()
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
void
void
sp_head
::
init
(
LEX
*
lex
)
sp_head
::
init
(
LEX
*
lex
)
{
{
...
@@ -359,7 +362,7 @@ sp_head::destroy()
...
@@ -359,7 +362,7 @@ sp_head::destroy()
delete
i
;
delete
i
;
delete_dynamic
(
&
m_instr
);
delete_dynamic
(
&
m_instr
);
m_pcont
->
destroy
();
m_pcont
->
destroy
();
free_items
(
m_
free_list
);
free_items
(
free_list
);
while
((
lex
=
(
LEX
*
)
m_lex
.
pop
()))
while
((
lex
=
(
LEX
*
)
m_lex
.
pop
()))
{
{
if
(
lex
!=
&
m_thd
->
main_lex
)
// We got interrupted and have lex'es left
if
(
lex
!=
&
m_thd
->
main_lex
)
// We got interrupted and have lex'es left
...
@@ -392,6 +395,7 @@ sp_head::execute(THD *thd)
...
@@ -392,6 +395,7 @@ sp_head::execute(THD *thd)
if
(
ctx
)
if
(
ctx
)
ctx
->
clear_handler
();
ctx
->
clear_handler
();
thd
->
query_error
=
0
;
thd
->
query_error
=
0
;
thd
->
current_arena
=
this
;
do
do
{
{
sp_instr
*
i
;
sp_instr
*
i
;
...
@@ -430,6 +434,9 @@ sp_head::execute(THD *thd)
...
@@ -430,6 +434,9 @@ sp_head::execute(THD *thd)
done:
done:
DBUG_PRINT
(
"info"
,
(
"ret=%d killed=%d query_error=%d"
,
DBUG_PRINT
(
"info"
,
(
"ret=%d killed=%d query_error=%d"
,
ret
,
thd
->
killed
,
thd
->
query_error
));
ret
,
thd
->
killed
,
thd
->
query_error
));
if
(
thd
->
current_arena
)
cleanup_items
(
thd
->
current_arena
->
free_list
);
thd
->
current_arena
=
0
;
if
(
thd
->
killed
||
thd
->
query_error
||
thd
->
net
.
report_error
)
if
(
thd
->
killed
||
thd
->
query_error
||
thd
->
net
.
report_error
)
ret
=
-
1
;
ret
=
-
1
;
/* If the DB has changed, the pointer has changed too, but the
/* If the DB has changed, the pointer has changed too, but the
...
@@ -687,21 +694,6 @@ sp_head::restore_lex(THD *thd)
...
@@ -687,21 +694,6 @@ sp_head::restore_lex(THD *thd)
// Update some state in the old one first
// Update some state in the old one first
oldlex
->
ptr
=
sublex
->
ptr
;
oldlex
->
ptr
=
sublex
->
ptr
;
oldlex
->
next_state
=
sublex
->
next_state
;
oldlex
->
next_state
=
sublex
->
next_state
;
for
(
sl
=
sublex
->
all_selects_list
;
sl
;
sl
=
sl
->
next_select_in_list
())
{
// Save WHERE clause pointers to avoid damaging by optimisation
sl
->
prep_where
=
sl
->
where
;
if
(
sl
->
with_wild
)
{
// Copy item_list. We will restore it before calling the
// sub-statement, so it's ok to pop them.
sl
->
item_list_copy
.
empty
();
while
(
Item
*
it
=
sl
->
item_list
.
pop
())
sl
->
item_list_copy
.
push_back
(
it
);
}
}
// Collect some data from the sub statement lex.
// Collect some data from the sub statement lex.
sp_merge_funs
(
oldlex
,
sublex
);
sp_merge_funs
(
oldlex
,
sublex
);
...
@@ -792,19 +784,19 @@ sp_head::set_info(char *definer, uint definerlen,
...
@@ -792,19 +784,19 @@ sp_head::set_info(char *definer, uint definerlen,
if
(
!
p
)
if
(
!
p
)
p
=
definer
;
// Weird...
p
=
definer
;
// Weird...
len
=
p
-
definer
;
len
=
p
-
definer
;
m_definer_user
.
str
=
strmake_root
(
&
m
_m
em_root
,
definer
,
len
);
m_definer_user
.
str
=
strmake_root
(
&
mem_root
,
definer
,
len
);
m_definer_user
.
length
=
len
;
m_definer_user
.
length
=
len
;
len
=
definerlen
-
len
-
1
;
len
=
definerlen
-
len
-
1
;
m_definer_host
.
str
=
strmake_root
(
&
m
_m
em_root
,
p
+
1
,
len
);
m_definer_host
.
str
=
strmake_root
(
&
mem_root
,
p
+
1
,
len
);
m_definer_host
.
length
=
len
;
m_definer_host
.
length
=
len
;
m_created
=
created
;
m_created
=
created
;
m_modified
=
modified
;
m_modified
=
modified
;
m_chistics
=
(
st_sp_chistics
*
)
alloc_root
(
&
m
_m
em_root
,
sizeof
(
st_sp_chistics
));
m_chistics
=
(
st_sp_chistics
*
)
alloc_root
(
&
mem_root
,
sizeof
(
st_sp_chistics
));
memcpy
(
m_chistics
,
chistics
,
sizeof
(
st_sp_chistics
));
memcpy
(
m_chistics
,
chistics
,
sizeof
(
st_sp_chistics
));
if
(
m_chistics
->
comment
.
length
==
0
)
if
(
m_chistics
->
comment
.
length
==
0
)
m_chistics
->
comment
.
str
=
0
;
m_chistics
->
comment
.
str
=
0
;
else
else
m_chistics
->
comment
.
str
=
strmake_root
(
&
m
_m
em_root
,
m_chistics
->
comment
.
str
=
strmake_root
(
&
mem_root
,
m_chistics
->
comment
.
str
,
m_chistics
->
comment
.
str
,
m_chistics
->
comment
.
length
);
m_chistics
->
comment
.
length
);
}
}
...
@@ -812,26 +804,33 @@ sp_head::set_info(char *definer, uint definerlen,
...
@@ -812,26 +804,33 @@ sp_head::set_info(char *definer, uint definerlen,
void
void
sp_head
::
reset_thd_mem_root
(
THD
*
thd
)
sp_head
::
reset_thd_mem_root
(
THD
*
thd
)
{
{
DBUG_ENTER
(
"sp_head::reset_thd_mem_root"
);
m_thd_root
=
thd
->
mem_root
;
m_thd_root
=
thd
->
mem_root
;
thd
->
mem_root
=
m_mem_root
;
thd
->
mem_root
=
mem_root
;
m_free_list
=
thd
->
free_list
;
// Keep the old list
DBUG_PRINT
(
"info"
,
(
"mem_root 0x%lx moved to thd mem root 0x%lx"
,
(
ulong
)
&
mem_root
,
(
ulong
)
&
thd
->
mem_root
));
free_list
=
thd
->
free_list
;
// Keep the old list
thd
->
free_list
=
NULL
;
// Start a new one
thd
->
free_list
=
NULL
;
// Start a new one
/* Copy the db, since substatements will point to it */
/* Copy the db, since substatements will point to it */
m_thd_db
=
thd
->
db
;
m_thd_db
=
thd
->
db
;
thd
->
db
=
strmake_root
(
&
thd
->
mem_root
,
thd
->
db
,
thd
->
db_length
);
thd
->
db
=
strmake_root
(
&
thd
->
mem_root
,
thd
->
db
,
thd
->
db_length
);
m_thd
=
thd
;
m_thd
=
thd
;
DBUG_VOID_RETURN
;
}
}
void
void
sp_head
::
restore_thd_mem_root
(
THD
*
thd
)
sp_head
::
restore_thd_mem_root
(
THD
*
thd
)
{
{
Item
*
flist
=
m_free_list
;
// The old list
DBUG_ENTER
(
"sp_head::restore_thd_mem_root"
);
m_free_list
=
thd
->
free_list
;
// Get the new one
Item
*
flist
=
free_list
;
// The old list
set_item_arena
(
thd
);
// Get new fre_list and mem_root
DBUG_PRINT
(
"info"
,
(
"mem_root 0x%lx returned from thd mem root 0x%lx"
,
(
ulong
)
&
mem_root
,
(
ulong
)
&
thd
->
mem_root
));
thd
->
free_list
=
flist
;
// Restore the old one
thd
->
free_list
=
flist
;
// Restore the old one
thd
->
db
=
m_thd_db
;
// Restore the original db pointer
thd
->
db
=
m_thd_db
;
// Restore the original db pointer
m_mem_root
=
thd
->
mem_root
;
thd
->
mem_root
=
m_thd_root
;
thd
->
mem_root
=
m_thd_root
;
m_thd
=
NULL
;
m_thd
=
NULL
;
DBUG_VOID_RETURN
;
}
}
...
@@ -919,7 +918,6 @@ int
...
@@ -919,7 +918,6 @@ int
sp_instr_stmt
::
exec_stmt
(
THD
*
thd
,
LEX
*
lex
)
sp_instr_stmt
::
exec_stmt
(
THD
*
thd
,
LEX
*
lex
)
{
{
LEX
*
olex
;
// The other lex
LEX
*
olex
;
// The other lex
Item
*
freelist
;
SELECT_LEX
*
sl
;
SELECT_LEX
*
sl
;
int
res
;
int
res
;
...
@@ -927,94 +925,24 @@ sp_instr_stmt::exec_stmt(THD *thd, LEX *lex)
...
@@ -927,94 +925,24 @@ sp_instr_stmt::exec_stmt(THD *thd, LEX *lex)
thd
->
lex
=
lex
;
// Use my own lex
thd
->
lex
=
lex
;
// Use my own lex
thd
->
lex
->
thd
=
thd
;
// QQ Not reentrant!
thd
->
lex
->
thd
=
thd
;
// QQ Not reentrant!
thd
->
lex
->
unit
.
thd
=
thd
;
// QQ Not reentrant
thd
->
lex
->
unit
.
thd
=
thd
;
// QQ Not reentrant
freelist
=
thd
->
free_list
;
thd
->
free_list
=
NULL
;
thd
->
free_list
=
NULL
;
VOID
(
pthread_mutex_lock
(
&
LOCK_thread_count
));
VOID
(
pthread_mutex_lock
(
&
LOCK_thread_count
));
thd
->
query_id
=
query_id
++
;
thd
->
query_id
=
query_id
++
;
VOID
(
pthread_mutex_unlock
(
&
LOCK_thread_count
));
VOID
(
pthread_mutex_unlock
(
&
LOCK_thread_count
));
// Copy WHERE clause pointers to avoid damaging by optimisation
reset_stmt_for_execute
(
thd
,
lex
);
// Also clear ref_pointer_arrays.
for
(
sl
=
lex
->
all_selects_list
;
sl
;
sl
=
sl
->
next_select_in_list
())
{
if
(
lex
->
sql_command
==
SQLCOM_CREATE_TABLE
||
lex
->
sql_command
==
SQLCOM_INSERT_SELECT
)
{
// Destroys sl->table_list.first
sl
->
table_list_first_copy
=
sl
->
table_list
.
first
;
}
if
(
sl
->
with_wild
)
{
// Restore item_list
// Note: We have to do this before executing the sub-statement,
// to make sure that the list nodes are in the right
// memroot.
List_iterator_fast
<
Item
>
li
(
sl
->
item_list_copy
);
sl
->
item_list
.
empty
();
while
(
Item
*
it
=
li
++
)
sl
->
item_list
.
push_back
(
it
);
}
sl
->
ref_pointer_array
=
0
;
if
(
sl
->
prep_where
)
sl
->
where
=
sl
->
prep_where
->
copy_andor_structure
(
thd
);
for
(
ORDER
*
order
=
(
ORDER
*
)
sl
->
order_list
.
first
;
order
;
order
=
order
->
next
)
{
order
->
item_copy
=
order
->
item
;
}
for
(
ORDER
*
group
=
(
ORDER
*
)
sl
->
group_list
.
first
;
group
;
group
=
group
->
next
)
{
group
->
item_copy
=
group
->
item
;
}
}
res
=
mysql_execute_command
(
thd
);
res
=
mysql_execute_command
(
thd
);
lex
->
unit
.
cleanup
();
if
(
thd
->
lock
||
thd
->
open_tables
||
thd
->
derived_tables
)
if
(
thd
->
lock
||
thd
->
open_tables
||
thd
->
derived_tables
)
{
{
thd
->
proc_info
=
"closing tables"
;
thd
->
proc_info
=
"closing tables"
;
close_thread_tables
(
thd
);
/* Free tables */
close_thread_tables
(
thd
);
/* Free tables */
}
}
for
(
sl
=
lex
->
all_selects_list
;
sl
;
sl
=
sl
->
next_select_in_list
())
{
TABLE_LIST
*
tabs
;
if
(
lex
->
sql_command
==
SQLCOM_CREATE_TABLE
||
lex
->
sql_command
==
SQLCOM_INSERT_SELECT
)
{
// Restore sl->table_list.first
sl
->
table_list
.
first
=
sl
->
table_list_first_copy
;
}
// We have closed all tables, get rid of pointers to them
for
(
tabs
=
(
TABLE_LIST
*
)
sl
->
table_list
.
first
;
tabs
;
tabs
=
tabs
->
next
)
{
tabs
->
table
=
NULL
;
}
for
(
ORDER
*
order
=
(
ORDER
*
)
sl
->
order_list
.
first
;
order
;
order
=
order
->
next
)
{
order
->
item
=
order
->
item_copy
;
}
for
(
ORDER
*
group
=
(
ORDER
*
)
sl
->
group_list
.
first
;
group
;
group
=
group
->
next
)
{
group
->
item
=
group
->
item_copy
;
}
}
thd
->
lex
=
olex
;
// Restore the other lex
thd
->
lex
=
olex
;
// Restore the other lex
thd
->
free_list
=
freelist
;
return
res
;
return
res
;
}
}
...
...
sql/sp_head.h
View file @
c7396f8d
...
@@ -70,7 +70,7 @@ sp_name *
...
@@ -70,7 +70,7 @@ sp_name *
sp_name_current_db_new
(
THD
*
thd
,
LEX_STRING
name
);
sp_name_current_db_new
(
THD
*
thd
,
LEX_STRING
name
);
class
sp_head
:
public
Sql_alloc
class
sp_head
:
private
Item_arena
{
{
sp_head
(
const
sp_head
&
);
/* Prevent use of these */
sp_head
(
const
sp_head
&
);
/* Prevent use of these */
void
operator
=
(
sp_head
&
);
void
operator
=
(
sp_head
&
);
...
@@ -206,9 +206,7 @@ class sp_head : public Sql_alloc
...
@@ -206,9 +206,7 @@ class sp_head : public Sql_alloc
private:
private:
MEM_ROOT
m_mem_root
;
// My own mem_root
MEM_ROOT
m_thd_root
;
// Temp. store for thd's mem_root
MEM_ROOT
m_thd_root
;
// Temp. store for thd's mem_root
Item
*
m_free_list
;
// Where the items go
THD
*
m_thd
;
// Set if we have reset mem_root
THD
*
m_thd
;
// Set if we have reset mem_root
char
*
m_thd_db
;
// Original thd->db pointer
char
*
m_thd_db
;
// Original thd->db pointer
...
...
sql/sql_base.cc
View file @
c7396f8d
...
@@ -2158,14 +2158,14 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
...
@@ -2158,14 +2158,14 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
{
{
if
(
!
wild_num
)
if
(
!
wild_num
)
return
0
;
return
0
;
Statement
*
stmt
=
thd
->
current_statement
,
backup
;
Item_arena
*
arena
=
thd
->
current_arena
,
backup
;
/*
/*
If we are in preparing prepared statement phase then we have change
If we are in preparing prepared statement phase then we have change
temporary mem_root to statement mem root to save changes of SELECT list
temporary mem_root to statement mem root to save changes of SELECT list
*/
*/
if
(
stmt
)
if
(
arena
)
thd
->
set_n_backup_item_arena
(
stmt
,
&
backup
);
thd
->
set_n_backup_item_arena
(
arena
,
&
backup
);
reg2
Item
*
item
;
reg2
Item
*
item
;
List_iterator
<
Item
>
it
(
fields
);
List_iterator
<
Item
>
it
(
fields
);
while
(
wild_num
&&
(
item
=
it
++
))
while
(
wild_num
&&
(
item
=
it
++
))
...
@@ -2178,8 +2178,8 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
...
@@ -2178,8 +2178,8 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
if
(
insert_fields
(
thd
,
tables
,((
Item_field
*
)
item
)
->
db_name
,
if
(
insert_fields
(
thd
,
tables
,((
Item_field
*
)
item
)
->
db_name
,
((
Item_field
*
)
item
)
->
table_name
,
&
it
))
((
Item_field
*
)
item
)
->
table_name
,
&
it
))
{
{
if
(
stmt
)
if
(
arena
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
return
(
-
1
);
return
(
-
1
);
}
}
if
(
sum_func_list
)
if
(
sum_func_list
)
...
@@ -2194,8 +2194,15 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
...
@@ -2194,8 +2194,15 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
wild_num
--
;
wild_num
--
;
}
}
}
}
if
(
stmt
)
if
(
arena
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
{
/* make * substituting permanent */
SELECT_LEX
*
select_lex
=
thd
->
lex
->
current_select
;
select_lex
->
with_wild
=
0
;
select_lex
->
item_list
=
fields
;
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
}
return
0
;
return
0
;
}
}
...
@@ -2408,12 +2415,17 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name,
...
@@ -2408,12 +2415,17 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name,
int
setup_conds
(
THD
*
thd
,
TABLE_LIST
*
tables
,
COND
**
conds
)
int
setup_conds
(
THD
*
thd
,
TABLE_LIST
*
tables
,
COND
**
conds
)
{
{
table_map
not_null_tables
=
0
;
table_map
not_null_tables
=
0
;
Statement
*
stmt
=
thd
->
current_statement
,
backup
;
SELECT_LEX
*
select_lex
=
thd
->
lex
->
current_select
;
Item_arena
*
arena
=
((
thd
->
current_arena
&&
!
select_lex
->
conds_processed_with_permanent_arena
)
?
thd
->
current_arena
:
0
);
Item_arena
backup
;
DBUG_ENTER
(
"setup_conds"
);
DBUG_ENTER
(
"setup_conds"
);
thd
->
set_query_id
=
1
;
thd
->
set_query_id
=
1
;
thd
->
lex
->
current_select
->
cond_count
=
0
;
select_lex
->
cond_count
=
0
;
if
(
*
conds
)
if
(
*
conds
)
{
{
thd
->
where
=
"where clause"
;
thd
->
where
=
"where clause"
;
...
@@ -2436,7 +2448,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
...
@@ -2436,7 +2448,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
table
->
on_expr
->
fix_fields
(
thd
,
tables
,
&
table
->
on_expr
)
||
table
->
on_expr
->
fix_fields
(
thd
,
tables
,
&
table
->
on_expr
)
||
table
->
on_expr
->
check_cols
(
1
))
table
->
on_expr
->
check_cols
(
1
))
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
thd
->
lex
->
current_select
->
cond_count
++
;
select_lex
->
cond_count
++
;
/*
/*
If it's a normal join or a LEFT JOIN which can be optimized away
If it's a normal join or a LEFT JOIN which can be optimized away
...
@@ -2447,12 +2459,12 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
...
@@ -2447,12 +2459,12 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
!
(
specialflag
&
SPECIAL_NO_NEW_FUNC
)))
!
(
specialflag
&
SPECIAL_NO_NEW_FUNC
)))
{
{
table
->
outer_join
=
0
;
table
->
outer_join
=
0
;
if
(
stmt
)
if
(
arena
)
thd
->
set_n_backup_item_arena
(
stmt
,
&
backup
);
thd
->
set_n_backup_item_arena
(
arena
,
&
backup
);
*
conds
=
and_conds
(
*
conds
,
table
->
on_expr
);
*
conds
=
and_conds
(
*
conds
,
table
->
on_expr
);
table
->
on_expr
=
0
;
table
->
on_expr
=
0
;
if
(
stmt
)
if
(
arena
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
if
((
*
conds
)
&&
!
(
*
conds
)
->
fixed
&&
if
((
*
conds
)
&&
!
(
*
conds
)
->
fixed
&&
(
*
conds
)
->
fix_fields
(
thd
,
tables
,
conds
))
(
*
conds
)
->
fix_fields
(
thd
,
tables
,
conds
))
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
...
@@ -2460,8 +2472,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
...
@@ -2460,8 +2472,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
}
}
if
(
table
->
natural_join
)
if
(
table
->
natural_join
)
{
{
if
(
stmt
)
if
(
arena
)
thd
->
set_n_backup_item_arena
(
stmt
,
&
backup
);
thd
->
set_n_backup_item_arena
(
arena
,
&
backup
);
/* Make a join of all fields with have the same name */
/* Make a join of all fields with have the same name */
TABLE
*
t1
=
table
->
table
;
TABLE
*
t1
=
table
->
table
;
TABLE
*
t2
=
table
->
natural_join
->
table
;
TABLE
*
t2
=
table
->
natural_join
->
table
;
...
@@ -2491,7 +2503,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
...
@@ -2491,7 +2503,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
t2
->
used_keys
.
intersect
(
t2_field
->
part_of_key
);
t2
->
used_keys
.
intersect
(
t2_field
->
part_of_key
);
}
}
}
}
thd
->
lex
->
current_select
->
cond_count
+=
cond_and
->
list
.
elements
;
select_lex
->
cond_count
+=
cond_and
->
list
.
elements
;
// to prevent natural join processing during PS re-execution
// to prevent natural join processing during PS re-execution
table
->
natural_join
=
0
;
table
->
natural_join
=
0
;
...
@@ -2500,8 +2512,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
...
@@ -2500,8 +2512,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
{
{
*
conds
=
and_conds
(
*
conds
,
cond_and
);
*
conds
=
and_conds
(
*
conds
,
cond_and
);
// fix_fields() should be made with temporary memory pool
// fix_fields() should be made with temporary memory pool
if
(
stmt
)
if
(
arena
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
if
(
*
conds
&&
!
(
*
conds
)
->
fixed
)
if
(
*
conds
&&
!
(
*
conds
)
->
fixed
)
{
{
if
((
*
conds
)
->
fix_fields
(
thd
,
tables
,
conds
))
if
((
*
conds
)
->
fix_fields
(
thd
,
tables
,
conds
))
...
@@ -2512,8 +2524,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
...
@@ -2512,8 +2524,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
{
{
table
->
on_expr
=
and_conds
(
table
->
on_expr
,
cond_and
);
table
->
on_expr
=
and_conds
(
table
->
on_expr
,
cond_and
);
// fix_fields() should be made with temporary memory pool
// fix_fields() should be made with temporary memory pool
if
(
stmt
)
if
(
arena
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
if
(
table
->
on_expr
&&
!
table
->
on_expr
->
fixed
)
if
(
table
->
on_expr
&&
!
table
->
on_expr
->
fixed
)
{
{
if
(
table
->
on_expr
->
fix_fields
(
thd
,
tables
,
&
table
->
on_expr
))
if
(
table
->
on_expr
->
fix_fields
(
thd
,
tables
,
&
table
->
on_expr
))
...
@@ -2523,21 +2535,22 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
...
@@ -2523,21 +2535,22 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
}
}
}
}
if
(
stmt
)
if
(
arena
)
{
{
/*
/*
We are in prepared statement preparation code => we should store
We are in prepared statement preparation code => we should store
WHERE clause changing for next executions.
WHERE clause changing for next executions.
We do this ON -> WHERE transformation only once per PS statement.
We do this ON -> WHERE transformation only once per PS
/SP
statement.
*/
*/
thd
->
lex
->
current_select
->
where
=
*
conds
;
select_lex
->
where
=
*
conds
;
select_lex
->
conds_processed_with_permanent_arena
=
1
;
}
}
DBUG_RETURN
(
test
(
thd
->
net
.
report_error
));
DBUG_RETURN
(
test
(
thd
->
net
.
report_error
));
err:
err:
if
(
stmt
)
if
(
arena
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
}
}
...
...
sql/sql_class.cc
View file @
c7396f8d
...
@@ -86,7 +86,7 @@ extern "C" void free_user_var(user_var_entry *entry)
...
@@ -86,7 +86,7 @@ extern "C" void free_user_var(user_var_entry *entry)
** Thread specific functions
** Thread specific functions
****************************************************************************/
****************************************************************************/
THD
::
THD
()
:
user_time
(
0
),
current_
statement
(
0
),
is_fatal_error
(
0
),
THD
::
THD
()
:
user_time
(
0
),
current_
arena
(
0
),
is_fatal_error
(
0
),
last_insert_id_used
(
0
),
last_insert_id_used
(
0
),
insert_id_used
(
0
),
rand_used
(
0
),
in_lock_tables
(
0
),
insert_id_used
(
0
),
rand_used
(
0
),
in_lock_tables
(
0
),
global_read_lock
(
0
),
bootstrap
(
0
),
spcont
(
NULL
)
global_read_lock
(
0
),
bootstrap
(
0
),
spcont
(
NULL
)
...
@@ -1210,23 +1210,47 @@ int select_dumpvar::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
...
@@ -1210,23 +1210,47 @@ int select_dumpvar::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
}
}
Item_arena
::
Item_arena
(
THD
*
thd
)
:
free_list
(
0
)
{
init_sql_alloc
(
&
mem_root
,
thd
->
variables
.
query_alloc_block_size
,
thd
->
variables
.
query_prealloc_size
);
}
Item_arena
::
Item_arena
()
:
free_list
(
0
)
{
bzero
((
char
*
)
&
mem_root
,
sizeof
(
mem_root
));
}
Item_arena
::
Item_arena
(
bool
init_mem_root
)
:
free_list
(
0
)
{
if
(
init_mem_root
)
bzero
((
char
*
)
&
mem_root
,
sizeof
(
mem_root
));
}
Item_arena
::~
Item_arena
()
{}
/*
/*
Statement functions
Statement functions
*/
*/
Statement
::
Statement
(
THD
*
thd
)
Statement
::
Statement
(
THD
*
thd
)
:
id
(
++
thd
->
statement_id_counter
),
:
Item_arena
(
thd
),
id
(
++
thd
->
statement_id_counter
),
set_query_id
(
1
),
set_query_id
(
1
),
allow_sum_func
(
0
),
allow_sum_func
(
0
),
lex
(
&
main_lex
),
lex
(
&
main_lex
),
query
(
0
),
query
(
0
),
query_length
(
0
),
query_length
(
0
)
free_list
(
0
)
{}
{
init_sql_alloc
(
&
mem_root
,
thd
->
variables
.
query_alloc_block_size
,
thd
->
variables
.
query_prealloc_size
);
}
/*
/*
This constructor is called when statement is a subobject of THD:
This constructor is called when statement is a subobject of THD:
...
@@ -1235,15 +1259,14 @@ Statement::Statement(THD *thd)
...
@@ -1235,15 +1259,14 @@ Statement::Statement(THD *thd)
*/
*/
Statement
::
Statement
()
Statement
::
Statement
()
:
id
(
0
),
:
Item_arena
(),
id
(
0
),
set_query_id
(
1
),
set_query_id
(
1
),
allow_sum_func
(
0
),
/* initialized later */
allow_sum_func
(
0
),
/* initialized later */
lex
(
&
main_lex
),
lex
(
&
main_lex
),
query
(
0
),
/* these two are set */
query
(
0
),
/* these two are set */
query_length
(
0
),
/* in alloc_query() */
query_length
(
0
)
/* in alloc_query() */
free_list
(
0
)
{
{
bzero
((
char
*
)
&
mem_root
,
sizeof
(
mem_root
));
}
}
...
@@ -1264,14 +1287,14 @@ void Statement::set_statement(Statement *stmt)
...
@@ -1264,14 +1287,14 @@ void Statement::set_statement(Statement *stmt)
}
}
void
Statement
::
set_n_backup_item_arena
(
Statement
*
set
,
Statement
*
backup
)
void
Item_arena
::
set_n_backup_item_arena
(
Item_arena
*
set
,
Item_arena
*
backup
)
{
{
backup
->
set_item_arena
(
this
);
backup
->
set_item_arena
(
this
);
set_item_arena
(
set
);
set_item_arena
(
set
);
}
}
void
Statement
::
restore_backup_item_arena
(
Statement
*
set
,
Statement
*
backup
)
void
Item_arena
::
restore_backup_item_arena
(
Item_arena
*
set
,
Item_arena
*
backup
)
{
{
set
->
set_item_arena
(
this
);
set
->
set_item_arena
(
this
);
set_item_arena
(
backup
);
set_item_arena
(
backup
);
...
@@ -1279,7 +1302,7 @@ void Statement::restore_backup_item_arena(Statement *set, Statement *backup)
...
@@ -1279,7 +1302,7 @@ void Statement::restore_backup_item_arena(Statement *set, Statement *backup)
init_alloc_root
(
&
backup
->
mem_root
,
0
,
0
);
init_alloc_root
(
&
backup
->
mem_root
,
0
,
0
);
}
}
void
Statement
::
set_item_arena
(
Statement
*
set
)
void
Item_arena
::
set_item_arena
(
Item_arena
*
set
)
{
{
mem_root
=
set
->
mem_root
;
mem_root
=
set
->
mem_root
;
free_list
=
set
->
free_list
;
free_list
=
set
->
free_list
;
...
...
sql/sql_class.h
View file @
c7396f8d
...
@@ -434,6 +434,48 @@ struct system_variables
...
@@ -434,6 +434,48 @@ struct system_variables
void
free_tmp_table
(
THD
*
thd
,
TABLE
*
entry
);
void
free_tmp_table
(
THD
*
thd
,
TABLE
*
entry
);
class
Item_arena
{
public:
/*
List of items created in the parser for this query. Every item puts
itself to the list on creation (see Item::Item() for details))
*/
Item
*
free_list
;
MEM_ROOT
mem_root
;
Item_arena
(
THD
*
thd
);
Item_arena
();
Item_arena
(
bool
init_mem_root
);
~
Item_arena
();
inline
gptr
alloc
(
unsigned
int
size
)
{
return
alloc_root
(
&
mem_root
,
size
);
}
inline
gptr
calloc
(
unsigned
int
size
)
{
gptr
ptr
;
if
((
ptr
=
alloc_root
(
&
mem_root
,
size
)))
bzero
((
char
*
)
ptr
,
size
);
return
ptr
;
}
inline
char
*
strdup
(
const
char
*
str
)
{
return
strdup_root
(
&
mem_root
,
str
);
}
inline
char
*
strmake
(
const
char
*
str
,
uint
size
)
{
return
strmake_root
(
&
mem_root
,
str
,
size
);
}
inline
char
*
memdup
(
const
char
*
str
,
uint
size
)
{
return
memdup_root
(
&
mem_root
,
str
,
size
);
}
inline
char
*
memdup_w_gap
(
const
char
*
str
,
uint
size
,
uint
gap
)
{
gptr
ptr
;
if
((
ptr
=
alloc_root
(
&
mem_root
,
size
+
gap
)))
memcpy
(
ptr
,
str
,
size
);
return
ptr
;
}
void
set_n_backup_item_arena
(
Item_arena
*
set
,
Item_arena
*
backup
);
void
restore_backup_item_arena
(
Item_arena
*
set
,
Item_arena
*
backup
);
void
set_item_arena
(
Item_arena
*
set
);
};
/*
/*
State of a single command executed against this connection.
State of a single command executed against this connection.
One connection can contain a lot of simultaneously running statements,
One connection can contain a lot of simultaneously running statements,
...
@@ -448,7 +490,7 @@ void free_tmp_table(THD *thd, TABLE *entry);
...
@@ -448,7 +490,7 @@ void free_tmp_table(THD *thd, TABLE *entry);
be used explicitly.
be used explicitly.
*/
*/
class
Statement
class
Statement
:
public
Item_arena
{
{
Statement
(
const
Statement
&
rhs
);
/* not implemented: */
Statement
(
const
Statement
&
rhs
);
/* not implemented: */
Statement
&
operator
=
(
const
Statement
&
rhs
);
/* non-copyable */
Statement
&
operator
=
(
const
Statement
&
rhs
);
/* non-copyable */
...
@@ -489,12 +531,6 @@ class Statement
...
@@ -489,12 +531,6 @@ class Statement
*/
*/
char
*
query
;
char
*
query
;
uint32
query_length
;
// current query length
uint32
query_length
;
// current query length
/*
List of items created in the parser for this query. Every item puts
itself to the list on creation (see Item::Item() for details))
*/
Item
*
free_list
;
MEM_ROOT
mem_root
;
public:
public:
/* We build without RTTI, so dynamic_cast can't be used. */
/* We build without RTTI, so dynamic_cast can't be used. */
...
@@ -518,31 +554,6 @@ class Statement
...
@@ -518,31 +554,6 @@ class Statement
/* return class type */
/* return class type */
virtual
Type
type
()
const
;
virtual
Type
type
()
const
;
inline
gptr
alloc
(
unsigned
int
size
)
{
return
alloc_root
(
&
mem_root
,
size
);
}
inline
gptr
calloc
(
unsigned
int
size
)
{
gptr
ptr
;
if
((
ptr
=
alloc_root
(
&
mem_root
,
size
)))
bzero
((
char
*
)
ptr
,
size
);
return
ptr
;
}
inline
char
*
strdup
(
const
char
*
str
)
{
return
strdup_root
(
&
mem_root
,
str
);
}
inline
char
*
strmake
(
const
char
*
str
,
uint
size
)
{
return
strmake_root
(
&
mem_root
,
str
,
size
);
}
inline
char
*
memdup
(
const
char
*
str
,
uint
size
)
{
return
memdup_root
(
&
mem_root
,
str
,
size
);
}
inline
char
*
memdup_w_gap
(
const
char
*
str
,
uint
size
,
uint
gap
)
{
gptr
ptr
;
if
((
ptr
=
alloc_root
(
&
mem_root
,
size
+
gap
)))
memcpy
(
ptr
,
str
,
size
);
return
ptr
;
}
void
set_n_backup_item_arena
(
Statement
*
set
,
Statement
*
backup
);
void
restore_backup_item_arena
(
Statement
*
set
,
Statement
*
backup
);
void
set_item_arena
(
Statement
*
set
);
};
};
...
@@ -746,9 +757,9 @@ class THD :public ilink,
...
@@ -746,9 +757,9 @@ class THD :public ilink,
Vio
*
active_vio
;
Vio
*
active_vio
;
#endif
#endif
/*
/*
Current prepared
Statement
if there one, or 0
Current prepared
Item_arena
if there one, or 0
*/
*/
Statement
*
current_statement
;
Item_arena
*
current_arena
;
/*
/*
next_insert_id is set on SET INSERT_ID= #. This is used as the next
next_insert_id is set on SET INSERT_ID= #. This is used as the next
generated auto_increment value in handler.cc
generated auto_increment value in handler.cc
...
@@ -969,7 +980,7 @@ class THD :public ilink,
...
@@ -969,7 +980,7 @@ class THD :public ilink,
inline
void
allocate_temporary_memory_pool_for_ps_preparing
()
inline
void
allocate_temporary_memory_pool_for_ps_preparing
()
{
{
DBUG_ASSERT
(
current_
statement
!=
0
);
DBUG_ASSERT
(
current_
arena
!=
0
);
/*
/*
We do not want to have in PS memory all that junk,
We do not want to have in PS memory all that junk,
which will be created by preparation => substitute memory
which will be created by preparation => substitute memory
...
@@ -978,7 +989,7 @@ class THD :public ilink,
...
@@ -978,7 +989,7 @@ class THD :public ilink,
We know that PS memory pool is now copied to THD, we move it back
We know that PS memory pool is now copied to THD, we move it back
to allow some code use it.
to allow some code use it.
*/
*/
current_
statement
->
set_item_arena
(
this
);
current_
arena
->
set_item_arena
(
this
);
init_sql_alloc
(
&
mem_root
,
init_sql_alloc
(
&
mem_root
,
variables
.
query_alloc_block_size
,
variables
.
query_alloc_block_size
,
variables
.
query_prealloc_size
);
variables
.
query_prealloc_size
);
...
@@ -986,12 +997,16 @@ class THD :public ilink,
...
@@ -986,12 +997,16 @@ class THD :public ilink,
}
}
inline
void
free_temporary_memory_pool_for_ps_preparing
()
inline
void
free_temporary_memory_pool_for_ps_preparing
()
{
{
DBUG_ASSERT
(
current_
statement
!=
0
);
DBUG_ASSERT
(
current_
arena
!=
0
);
cleanup_items
(
current_
statement
->
free_list
);
cleanup_items
(
current_
arena
->
free_list
);
free_items
(
free_list
);
free_items
(
free_list
);
close_thread_tables
(
this
);
// to close derived tables
close_thread_tables
(
this
);
// to close derived tables
free_root
(
&
mem_root
,
MYF
(
0
));
free_root
(
&
mem_root
,
MYF
(
0
));
set_item_arena
(
current_statement
);
set_item_arena
(
current_arena
);
}
inline
bool
only_prepare
()
{
return
command
==
COM_PREPARE
;
}
}
};
};
...
...
sql/sql_delete.cc
View file @
c7396f8d
...
@@ -264,10 +264,11 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds)
...
@@ -264,10 +264,11 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds)
{
{
TABLE_LIST
*
delete_table_list
=
((
TABLE_LIST
*
)
thd
->
lex
->
TABLE_LIST
*
delete_table_list
=
((
TABLE_LIST
*
)
thd
->
lex
->
select_lex
.
table_list
.
first
);
select_lex
.
table_list
.
first
);
SELECT_LEX
*
select_lex
=
&
thd
->
lex
->
select_lex
;
DBUG_ENTER
(
"mysql_prepare_delete"
);
DBUG_ENTER
(
"mysql_prepare_delete"
);
if
(
setup_conds
(
thd
,
delete_table_list
,
conds
)
||
if
(
setup_conds
(
thd
,
delete_table_list
,
conds
)
||
setup_ftfuncs
(
&
thd
->
lex
->
select_lex
))
setup_ftfuncs
(
select_lex
))
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
if
(
find_real_table_in_list
(
table_list
->
next
,
if
(
find_real_table_in_list
(
table_list
->
next
,
table_list
->
db
,
table_list
->
real_name
))
table_list
->
db
,
table_list
->
real_name
))
...
@@ -275,6 +276,11 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds)
...
@@ -275,6 +276,11 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds)
my_error
(
ER_UPDATE_TABLE_USED
,
MYF
(
0
),
table_list
->
real_name
);
my_error
(
ER_UPDATE_TABLE_USED
,
MYF
(
0
),
table_list
->
real_name
);
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
if
(
thd
->
current_arena
&&
select_lex
->
first_execution
)
{
select_lex
->
prep_where
=
select_lex
->
where
;
select_lex
->
first_execution
=
0
;
}
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
}
}
...
...
sql/sql_derived.cc
View file @
c7396f8d
...
@@ -152,7 +152,7 @@ static int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
...
@@ -152,7 +152,7 @@ static int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
if it is preparation PS only then we do not need real data and we
if it is preparation PS only then we do not need real data and we
can skip execution (and parameters is not defined, too)
can skip execution (and parameters is not defined, too)
*/
*/
if
(
!
thd
->
current_statement
)
if
(
!
thd
->
only_prepare
()
)
{
{
if
(
is_union
)
if
(
is_union
)
{
{
...
...
sql/sql_insert.cc
View file @
c7396f8d
...
@@ -460,6 +460,7 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
...
@@ -460,6 +460,7 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
my_error
(
ER_UPDATE_TABLE_USED
,
MYF
(
0
),
table_list
->
real_name
);
my_error
(
ER_UPDATE_TABLE_USED
,
MYF
(
0
),
table_list
->
real_name
);
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
thd
->
lex
->
select_lex
.
first_execution
=
0
;
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
}
}
...
...
sql/sql_lex.cc
View file @
c7396f8d
...
@@ -1011,10 +1011,12 @@ void st_select_lex::init_query()
...
@@ -1011,10 +1011,12 @@ void st_select_lex::init_query()
having_fix_field
=
0
;
having_fix_field
=
0
;
resolve_mode
=
NOMATTER_MODE
;
resolve_mode
=
NOMATTER_MODE
;
cond_count
=
with_wild
=
0
;
cond_count
=
with_wild
=
0
;
conds_processed_with_permanent_arena
=
0
;
ref_pointer_array
=
0
;
ref_pointer_array
=
0
;
select_n_having_items
=
0
;
select_n_having_items
=
0
;
prep_where
=
0
;
prep_where
=
0
;
explicit_limit
=
0
;
explicit_limit
=
0
;
first_execution
=
1
;
}
}
void
st_select_lex
::
init_select
()
void
st_select_lex
::
init_select
()
...
@@ -1414,7 +1416,9 @@ bool st_select_lex::add_order_to_list(THD *thd, Item *item, bool asc)
...
@@ -1414,7 +1416,9 @@ bool st_select_lex::add_order_to_list(THD *thd, Item *item, bool asc)
bool
st_select_lex
::
add_item_to_list
(
THD
*
thd
,
Item
*
item
)
bool
st_select_lex
::
add_item_to_list
(
THD
*
thd
,
Item
*
item
)
{
{
return
item_list
.
push_back
(
item
);
DBUG_ENTER
(
"st_select_lex::add_item_to_list"
);
DBUG_PRINT
(
"info"
,
(
"Item: %p"
,
item
));
DBUG_RETURN
(
item_list
.
push_back
(
item
));
}
}
...
@@ -1500,9 +1504,9 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
...
@@ -1500,9 +1504,9 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
We have to create array in prepared statement memory if it is
We have to create array in prepared statement memory if it is
prepared statement
prepared statement
*/
*/
Statement
*
stmt
=
thd
->
current_statement
?
thd
->
current_statement
:
thd
;
Item_arena
*
arena
=
thd
->
current_arena
?
thd
->
current_arena
:
thd
;
return
(
ref_pointer_array
=
return
(
ref_pointer_array
=
(
Item
**
)
stmt
->
alloc
(
sizeof
(
Item
*
)
*
(
Item
**
)
arena
->
alloc
(
sizeof
(
Item
*
)
*
(
item_list
.
elements
+
(
item_list
.
elements
+
select_n_having_items
+
select_n_having_items
+
order_group_num
)
*
5
))
==
0
;
order_group_num
)
*
5
))
==
0
;
...
...
sql/sql_lex.h
View file @
c7396f8d
...
@@ -405,8 +405,6 @@ class st_select_lex: public st_select_lex_node
...
@@ -405,8 +405,6 @@ class st_select_lex: public st_select_lex_node
enum
olap_type
olap
;
enum
olap_type
olap
;
SQL_LIST
table_list
,
group_list
;
/* FROM & GROUP BY clauses */
SQL_LIST
table_list
,
group_list
;
/* FROM & GROUP BY clauses */
List
<
Item
>
item_list
;
/* list of fields & expressions */
List
<
Item
>
item_list
;
/* list of fields & expressions */
List
<
Item
>
item_list_copy
;
/* For SPs */
byte
*
table_list_first_copy
;
/* For SPs */
List
<
String
>
interval_list
,
use_index
,
*
use_index_ptr
,
List
<
String
>
interval_list
,
use_index
,
*
use_index_ptr
,
ignore_index
,
*
ignore_index_ptr
;
ignore_index
,
*
ignore_index_ptr
;
/*
/*
...
@@ -435,6 +433,11 @@ class st_select_lex: public st_select_lex_node
...
@@ -435,6 +433,11 @@ class st_select_lex: public st_select_lex_node
uint
cond_count
;
/* number of arguments of and/or/xor in where/having */
uint
cond_count
;
/* number of arguments of and/or/xor in where/having */
enum_parsing_place
parsing_place
;
/* where we are parsing expression */
enum_parsing_place
parsing_place
;
/* where we are parsing expression */
bool
with_sum_func
;
/* sum function indicator */
bool
with_sum_func
;
/* sum function indicator */
/*
PS or SP cond natural joins was alredy processed with permanent
arena and all additional items which we need alredy stored in it
*/
bool
conds_processed_with_permanent_arena
;
ulong
table_join_options
;
ulong
table_join_options
;
uint
in_sum_expr
;
uint
in_sum_expr
;
...
@@ -445,6 +448,7 @@ class st_select_lex: public st_select_lex_node
...
@@ -445,6 +448,7 @@ class st_select_lex: public st_select_lex_node
bool
having_fix_field
;
bool
having_fix_field
;
/* explicit LIMIT clause was used */
/* explicit LIMIT clause was used */
bool
explicit_limit
;
bool
explicit_limit
;
bool
first_execution
;
/* first execution in SP or PS */
/*
/*
SELECT for SELECT command st_select_lex. Used to privent scaning
SELECT for SELECT command st_select_lex. Used to privent scaning
...
...
sql/sql_parse.cc
View file @
c7396f8d
...
@@ -4182,12 +4182,14 @@ void mysql_parse(THD *thd, char *inBuf, uint length)
...
@@ -4182,12 +4182,14 @@ void mysql_parse(THD *thd, char *inBuf, uint length)
query_cache_end_of_result
(
thd
);
query_cache_end_of_result
(
thd
);
}
}
}
}
lex
->
unit
.
cleanup
();
}
}
else
else
{
{
DBUG_PRINT
(
"info"
,(
"Command aborted. Fatal_error: %d"
,
DBUG_PRINT
(
"info"
,(
"Command aborted. Fatal_error: %d"
,
thd
->
is_fatal_error
));
thd
->
is_fatal_error
));
query_cache_abort
(
&
thd
->
net
);
query_cache_abort
(
&
thd
->
net
);
lex
->
unit
.
cleanup
();
if
(
thd
->
lex
->
sphead
)
if
(
thd
->
lex
->
sphead
)
{
{
/* Clean up after failed stored procedure/function */
/* Clean up after failed stored procedure/function */
...
...
sql/sql_prepare.cc
View file @
c7396f8d
...
@@ -1357,7 +1357,7 @@ void mysql_stmt_prepare(THD *thd, char *packet, uint packet_length)
...
@@ -1357,7 +1357,7 @@ void mysql_stmt_prepare(THD *thd, char *packet, uint packet_length)
mysql_log
.
write
(
thd
,
COM_PREPARE
,
"%s"
,
packet
);
mysql_log
.
write
(
thd
,
COM_PREPARE
,
"%s"
,
packet
);
thd
->
current_
statement
=
stmt
;
thd
->
current_
arena
=
stmt
;
lex
=
lex_start
(
thd
,
(
uchar
*
)
thd
->
query
,
thd
->
query_length
);
lex
=
lex_start
(
thd
,
(
uchar
*
)
thd
->
query
,
thd
->
query_length
);
mysql_init_query
(
thd
);
mysql_init_query
(
thd
);
lex
->
safe_to_cache_query
=
0
;
lex
->
safe_to_cache_query
=
0
;
...
@@ -1381,7 +1381,7 @@ void mysql_stmt_prepare(THD *thd, char *packet, uint packet_length)
...
@@ -1381,7 +1381,7 @@ void mysql_stmt_prepare(THD *thd, char *packet, uint packet_length)
stmt
->
set_item_arena
(
thd
);
stmt
->
set_item_arena
(
thd
);
thd
->
set_statement
(
&
thd
->
stmt_backup
);
thd
->
set_statement
(
&
thd
->
stmt_backup
);
thd
->
set_item_arena
(
&
thd
->
stmt_backup
);
thd
->
set_item_arena
(
&
thd
->
stmt_backup
);
thd
->
current_
statement
=
0
;
thd
->
current_
arena
=
0
;
if
(
error
)
if
(
error
)
{
{
...
@@ -1389,29 +1389,18 @@ void mysql_stmt_prepare(THD *thd, char *packet, uint packet_length)
...
@@ -1389,29 +1389,18 @@ void mysql_stmt_prepare(THD *thd, char *packet, uint packet_length)
thd
->
stmt_map
.
erase
(
stmt
);
thd
->
stmt_map
.
erase
(
stmt
);
/* error is sent inside yyparse/send_prepare_results */
/* error is sent inside yyparse/send_prepare_results */
}
}
else
{
SELECT_LEX
*
sl
=
stmt
->
lex
->
all_selects_list
;
/*
Save WHERE clause pointers, because they may be changed during query
optimisation.
*/
for
(;
sl
;
sl
=
sl
->
next_select_in_list
())
{
sl
->
prep_where
=
sl
->
where
;
}
}
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
/* Reinit statement before execution */
/* Reinit statement before execution */
static
void
reset_stmt_for_execute
(
Prepared_statement
*
stmt
)
void
reset_stmt_for_execute
(
THD
*
thd
,
LEX
*
lex
)
{
{
THD
*
thd
=
stmt
->
thd
;
SELECT_LEX
*
sl
=
lex
->
all_selects_list
;
SELECT_LEX
*
sl
=
stmt
->
lex
->
all_selects_list
;
for
(;
sl
;
sl
=
sl
->
next_select_in_list
())
for
(;
sl
;
sl
=
sl
->
next_select_in_list
())
{
if
(
!
sl
->
first_execution
)
{
{
/*
/*
Copy WHERE clause pointers to avoid damaging they by optimisation
Copy WHERE clause pointers to avoid damaging they by optimisation
...
@@ -1426,6 +1415,7 @@ static void reset_stmt_for_execute(Prepared_statement *stmt)
...
@@ -1426,6 +1415,7 @@ static void reset_stmt_for_execute(Prepared_statement *stmt)
/* Fix ORDER list */
/* Fix ORDER list */
for
(
order
=
(
ORDER
*
)
sl
->
order_list
.
first
;
order
;
order
=
order
->
next
)
for
(
order
=
(
ORDER
*
)
sl
->
order_list
.
first
;
order
;
order
=
order
->
next
)
order
->
item
=
&
order
->
item_ptr
;
order
->
item
=
&
order
->
item_ptr
;
}
/*
/*
TODO: When the new table structure is ready, then have a status bit
TODO: When the new table structure is ready, then have a status bit
...
@@ -1443,7 +1433,6 @@ static void reset_stmt_for_execute(Prepared_statement *stmt)
...
@@ -1443,7 +1433,6 @@ static void reset_stmt_for_execute(Prepared_statement *stmt)
tables
->
table
=
0
;
tables
->
table
=
0
;
tables
->
table_list
=
0
;
tables
->
table_list
=
0
;
}
}
{
{
SELECT_LEX_UNIT
*
unit
=
sl
->
master_unit
();
SELECT_LEX_UNIT
*
unit
=
sl
->
master_unit
();
unit
->
unclean
();
unit
->
unclean
();
...
@@ -1506,7 +1495,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
...
@@ -1506,7 +1495,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
thd
->
stmt_backup
.
set_statement
(
thd
);
thd
->
stmt_backup
.
set_statement
(
thd
);
thd
->
set_statement
(
stmt
);
thd
->
set_statement
(
stmt
);
reset_stmt_for_execute
(
stmt
);
reset_stmt_for_execute
(
thd
,
stmt
->
lex
);
#ifndef EMBEDDED_LIBRARY
#ifndef EMBEDDED_LIBRARY
if
(
stmt
->
param_count
)
if
(
stmt
->
param_count
)
{
{
...
...
sql/sql_select.cc
View file @
c7396f8d
...
@@ -367,9 +367,16 @@ JOIN::prepare(Item ***rref_pointer_array,
...
@@ -367,9 +367,16 @@ JOIN::prepare(Item ***rref_pointer_array,
Item_subselect
::
trans_res
res
;
Item_subselect
::
trans_res
res
;
if
((
res
=
subselect
->
select_transformer
(
this
))
!=
if
((
res
=
subselect
->
select_transformer
(
this
))
!=
Item_subselect
::
RES_OK
)
Item_subselect
::
RES_OK
)
{
if
(
thd
->
current_arena
&&
select_lex
->
first_execution
)
{
select_lex
->
prep_where
=
select_lex
->
where
;
select_lex
->
first_execution
=
0
;
}
DBUG_RETURN
((
res
==
Item_subselect
::
RES_ERROR
));
DBUG_RETURN
((
res
==
Item_subselect
::
RES_ERROR
));
}
}
}
}
}
if
(
setup_ftfuncs
(
select_lex
))
/* should be after having->fix_fields */
if
(
setup_ftfuncs
(
select_lex
))
/* should be after having->fix_fields */
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
...
@@ -470,6 +477,11 @@ JOIN::prepare(Item ***rref_pointer_array,
...
@@ -470,6 +477,11 @@ JOIN::prepare(Item ***rref_pointer_array,
if
(
alloc_func_list
())
if
(
alloc_func_list
())
goto
err
;
goto
err
;
if
(
thd
->
current_arena
&&
select_lex
->
first_execution
)
{
select_lex
->
prep_where
=
select_lex
->
where
;
select_lex
->
first_execution
=
0
;
}
DBUG_RETURN
(
0
);
// All OK
DBUG_RETURN
(
0
);
// All OK
err:
err:
...
...
sql/sql_union.cc
View file @
c7396f8d
...
@@ -262,27 +262,32 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
...
@@ -262,27 +262,32 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
thd_arg
->
lex
->
current_select
=
lex_select_save
;
thd_arg
->
lex
->
current_select
=
lex_select_save
;
if
(
!
item_list
.
elements
)
if
(
!
item_list
.
elements
)
{
{
Statement
*
stmt
=
thd
->
current_statement
;
Item_arena
*
arena
=
thd
->
current_arena
;
Statement
backup
;
Item_arena
backup
;
if
(
stmt
)
if
(
arena
)
thd
->
set_n_backup_item_arena
(
stmt
,
&
backup
);
thd
->
set_n_backup_item_arena
(
arena
,
&
backup
);
Field
**
field
;
Field
**
field
;
for
(
field
=
table
->
field
;
*
field
;
field
++
)
for
(
field
=
table
->
field
;
*
field
;
field
++
)
{
{
Item_field
*
item
=
new
Item_field
(
*
field
);
Item_field
*
item
=
new
Item_field
(
*
field
);
if
(
!
item
||
item_list
.
push_back
(
item
))
if
(
!
item
||
item_list
.
push_back
(
item
))
{
{
if
(
stmt
)
if
(
arena
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
}
}
if
(
stmt
)
if
(
arena
)
{
{
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
/* prepare fake select to initialize it correctly */
/* prepare fake select to initialize it correctly */
ulong
options_tmp
=
init_prepare_fake_select_lex
(
thd
);
ulong
options_tmp
=
init_prepare_fake_select_lex
(
thd
);
/*
it should be done only once (because item_list builds only onece
per statement)
*/
DBUG_ASSERT
(
fake_select_lex
->
join
==
0
);
if
(
!
(
fake_select_lex
->
join
=
new
JOIN
(
thd
,
item_list
,
thd
->
options
,
if
(
!
(
fake_select_lex
->
join
=
new
JOIN
(
thd
,
item_list
,
thd
->
options
,
result
)))
result
)))
{
{
...
...
sql/sql_update.cc
View file @
c7396f8d
...
@@ -425,6 +425,7 @@ int mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
...
@@ -425,6 +425,7 @@ int mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
TABLE
*
table
=
table_list
->
table
;
TABLE
*
table
=
table_list
->
table
;
TABLE_LIST
tables
;
TABLE_LIST
tables
;
List
<
Item
>
all_fields
;
List
<
Item
>
all_fields
;
SELECT_LEX
*
select_lex
=
&
thd
->
lex
->
select_lex
;
DBUG_ENTER
(
"mysql_prepare_update"
);
DBUG_ENTER
(
"mysql_prepare_update"
);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
#ifndef NO_EMBEDDED_ACCESS_CHECKS
...
@@ -437,10 +438,10 @@ int mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
...
@@ -437,10 +438,10 @@ int mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
if
(
setup_tables
(
update_table_list
)
||
if
(
setup_tables
(
update_table_list
)
||
setup_conds
(
thd
,
update_table_list
,
conds
)
||
setup_conds
(
thd
,
update_table_list
,
conds
)
||
thd
->
lex
->
select_lex
.
setup_ref_array
(
thd
,
order_num
)
||
select_lex
->
setup_ref_array
(
thd
,
order_num
)
||
setup_order
(
thd
,
thd
->
lex
->
select_lex
.
ref_pointer_array
,
setup_order
(
thd
,
select_lex
->
ref_pointer_array
,
update_table_list
,
all_fields
,
all_fields
,
order
)
||
update_table_list
,
all_fields
,
all_fields
,
order
)
||
setup_ftfuncs
(
&
thd
->
lex
->
select_lex
))
setup_ftfuncs
(
select_lex
))
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
/* Check that we are not using table that we are updating in a sub select */
/* Check that we are not using table that we are updating in a sub select */
...
@@ -450,6 +451,11 @@ int mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
...
@@ -450,6 +451,11 @@ int mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
my_error
(
ER_UPDATE_TABLE_USED
,
MYF
(
0
),
table_list
->
real_name
);
my_error
(
ER_UPDATE_TABLE_USED
,
MYF
(
0
),
table_list
->
real_name
);
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
if
(
thd
->
current_arena
&&
select_lex
->
first_execution
)
{
select_lex
->
prep_where
=
select_lex
->
where
;
select_lex
->
first_execution
=
0
;
}
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
}
}
...
...
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