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
350d8a21
Commit
350d8a21
authored
May 26, 2004
by
bell@sanja.is.com.ua
Browse files
Options
Browse Files
Download
Plain Diff
Merge sanja.is.com.ua:/home/bell/mysql/bk/mysql-5.0
into sanja.is.com.ua:/home/bell/mysql/bk/work-sp2_bak-5.0
parents
c0643063
e822f61d
Changes
22
Show whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
331 additions
and
280 deletions
+331
-280
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
+53
-104
sql/sp_head.h
sql/sp_head.h
+9
-12
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 @
350d8a21
...
...
@@ -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 table t1;
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 @
350d8a21
...
...
@@ -1450,3 +1450,15 @@ drop procedure bar|
delimiter
;
|
drop
table
t1
;
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 @
350d8a21
...
...
@@ -104,7 +104,7 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref)
{
DBUG_ASSERT
(
fixed
==
0
);
engine
->
set_thd
((
thd
=
thd_param
));
stmt
=
thd
->
current_statement
;
arena
=
thd
->
current_arena
;
char
const
*
save_where
=
thd
->
where
;
int
res
=
engine
->
prepare
();
...
...
@@ -316,8 +316,8 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
if
(
join
->
conds
||
join
->
having
)
{
Item
*
cond
;
if
(
stmt
)
thd
->
set_n_backup_item_arena
(
stmt
,
&
backup
);
if
(
arena
)
thd
->
set_n_backup_item_arena
(
arena
,
&
backup
);
if
(
!
join
->
having
)
cond
=
join
->
conds
;
...
...
@@ -330,15 +330,15 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
new
Item_null
())))
goto
err
;
}
if
(
stmt
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
if
(
arena
)
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
return
RES_REDUCE
;
}
return
RES_OK
;
err:
if
(
stmt
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
if
(
arena
)
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
return
RES_ERROR
;
}
...
...
@@ -618,8 +618,8 @@ Item_in_subselect::single_value_transformer(JOIN *join,
Statement
backup
;
thd
->
where
=
"scalar IN/ALL/ANY subquery"
;
if
(
stmt
)
thd
->
set_n_backup_item_arena
(
stmt
,
&
backup
);
if
(
arena
)
thd
->
set_n_backup_item_arena
(
arena
,
&
backup
);
if
(
select_lex
->
item_list
.
elements
>
1
)
{
...
...
@@ -823,21 +823,21 @@ Item_in_subselect::single_value_transformer(JOIN *join,
push_warning
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_NOTE
,
ER_SELECT_REDUCED
,
warn_buff
);
}
if
(
stmt
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
if
(
arena
)
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
DBUG_RETURN
(
RES_REDUCE
);
}
}
}
ok:
if
(
stmt
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
if
(
arena
)
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
DBUG_RETURN
(
RES_OK
);
err:
if
(
stmt
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
if
(
arena
)
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
DBUG_RETURN
(
RES_ERROR
);
}
...
...
@@ -855,8 +855,8 @@ Item_in_subselect::row_value_transformer(JOIN *join)
Item
*
item
=
0
;
thd
->
where
=
"row IN/ALL/ANY subquery"
;
if
(
stmt
)
thd
->
set_n_backup_item_arena
(
stmt
,
&
backup
);
if
(
arena
)
thd
->
set_n_backup_item_arena
(
arena
,
&
backup
);
SELECT_LEX
*
select_lex
=
join
->
select_lex
;
...
...
@@ -940,13 +940,13 @@ Item_in_subselect::row_value_transformer(JOIN *join)
if
(
join
->
conds
->
fix_fields
(
thd
,
join
->
tables_list
,
0
))
goto
err
;
}
if
(
stmt
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
if
(
arena
)
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
DBUG_RETURN
(
RES_OK
);
err:
if
(
stmt
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
if
(
arena
)
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
DBUG_RETURN
(
RES_ERROR
);
}
...
...
sql/item_subselect.h
View file @
350d8a21
...
...
@@ -26,7 +26,7 @@ class JOIN;
class
select_subselect
;
class
subselect_engine
;
class
Item_bool_func2
;
class
Statement
;
class
Item_arena
;
/* base class for subselects */
...
...
@@ -36,8 +36,8 @@ class Item_subselect :public Item_result_field
protected:
/* thread handler, will be assigned in fix_fields only */
THD
*
thd
;
/*
prepared statement,
or 0 */
Statement
*
stmt
;
/*
Item_arena used
or 0 */
Item_arena
*
arena
;
/* substitution instead of subselect in case of optimization */
Item
*
substitution
;
/* unit of subquery */
...
...
sql/item_sum.cc
View file @
350d8a21
...
...
@@ -77,15 +77,15 @@ Item_sum::Item_sum(THD *thd, Item_sum *item):
*/
bool
Item_sum
::
save_args_for_prepared_statements
(
THD
*
thd
)
{
if
(
thd
->
current_
statement
)
return
save_args
(
thd
->
current_
statement
);
if
(
thd
->
current_
arena
&&
args_copy
==
0
)
return
save_args
(
thd
->
current_
arena
);
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
;
memcpy
(
args_copy
,
args
,
sizeof
(
Item
*
)
*
arg_count
);
return
0
;
...
...
sql/item_sum.h
View file @
350d8a21
...
...
@@ -23,6 +23,8 @@
#include <my_tree.h>
class
Item_arena
;
class
Item_sum
:
public
Item_result_field
{
public:
...
...
@@ -93,7 +95,7 @@ class Item_sum :public Item_result_field
virtual
void
make_unique
()
{}
Item
*
get_tmp_table_item
(
THD
*
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
);
};
...
...
sql/mysql_priv.h
View file @
350d8a21
...
...
@@ -681,6 +681,7 @@ void mysql_stmt_reset(THD *thd, char *packet);
void
mysql_stmt_get_longdata
(
THD
*
thd
,
char
*
pos
,
ulong
packet_length
);
int
check_insert_fields
(
THD
*
thd
,
TABLE
*
table
,
List
<
Item
>
&
fields
,
List
<
Item
>
&
values
,
ulong
counter
);
void
reset_stmt_for_execute
(
THD
*
thd
,
LEX
*
lex
);
/* sql_error.cc */
MYSQL_ERROR
*
push_warning
(
THD
*
thd
,
MYSQL_ERROR
::
enum_warning_level
level
,
uint
code
,
...
...
sql/sp_head.cc
View file @
350d8a21
...
...
@@ -186,8 +186,8 @@ sp_head::operator new(size_t size)
bzero
((
char
*
)
&
own_root
,
sizeof
(
own_root
));
init_alloc_root
(
&
own_root
,
MEM_ROOT_BLOCK_SIZE
,
MEM_ROOT_PREALLOC
);
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
);
}
...
...
@@ -198,16 +198,18 @@ sp_head::operator delete(void *ptr, size_t size)
MEM_ROOT
own_root
;
sp_head
*
sp
=
(
sp_head
*
)
ptr
;
DBUG_PRINT
(
"info"
,
(
"root: %lx"
,
&
sp
->
m_mem_root
));
memcpy
(
&
own_root
,
(
const
void
*
)
&
sp
->
m_mem_root
,
sizeof
(
MEM_ROOT
));
memcpy
(
&
own_root
,
(
const
void
*
)
&
sp
->
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
));
DBUG_VOID_RETURN
;
}
sp_head
::
sp_head
()
:
Sql_alloc
(),
m_returns_cs
(
NULL
),
m_has_return
(
FALSE
),
m_simple_case
(
FALSE
),
m_multi_results
(
FALSE
),
m_free_list
(
NULL
)
:
Item_arena
((
bool
)
FALSE
),
m_returns_cs
(
NULL
),
m_has_return
(
FALSE
),
m_simple_case
(
FALSE
),
m_multi_results
(
FALSE
)
{
DBUG_ENTER
(
"sp_head::sp_head"
);
...
...
@@ -216,6 +218,7 @@ sp_head::sp_head()
DBUG_VOID_RETURN
;
}
void
sp_head
::
init
(
LEX
*
lex
)
{
...
...
@@ -359,7 +362,7 @@ sp_head::destroy()
delete
i
;
delete_dynamic
(
&
m_instr
);
m_pcont
->
destroy
();
free_items
(
m_
free_list
);
free_items
(
free_list
);
while
((
lex
=
(
LEX
*
)
m_lex
.
pop
()))
{
if
(
lex
!=
&
m_thd
->
main_lex
)
// We got interrupted and have lex'es left
...
...
@@ -392,6 +395,7 @@ sp_head::execute(THD *thd)
if
(
ctx
)
ctx
->
clear_handler
();
thd
->
query_error
=
0
;
thd
->
current_arena
=
this
;
do
{
sp_instr
*
i
;
...
...
@@ -402,6 +406,8 @@ sp_head::execute(THD *thd)
break
;
DBUG_PRINT
(
"execute"
,
(
"Instruction %u"
,
ip
));
ret
=
i
->
execute
(
thd
,
&
ip
);
if
(
i
->
free_list
)
cleanup_items
(
i
->
free_list
);
// Check if an exception has occurred and a handler has been found
// Note: We havo to check even if ret==0, since warnings (and some
// errors don't return a non-zero value.
...
...
@@ -430,6 +436,11 @@ sp_head::execute(THD *thd)
done:
DBUG_PRINT
(
"info"
,
(
"ret=%d killed=%d query_error=%d"
,
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
)
ret
=
-
1
;
/* If the DB has changed, the pointer has changed too, but the
...
...
@@ -687,21 +698,6 @@ sp_head::restore_lex(THD *thd)
// Update some state in the old one first
oldlex
->
ptr
=
sublex
->
ptr
;
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.
sp_merge_funs
(
oldlex
,
sublex
);
...
...
@@ -792,19 +788,19 @@ sp_head::set_info(char *definer, uint definerlen,
if
(
!
p
)
p
=
definer
;
// Weird...
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
;
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_created
=
created
;
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
));
if
(
m_chistics
->
comment
.
length
==
0
)
m_chistics
->
comment
.
str
=
0
;
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
.
length
);
}
...
...
@@ -812,26 +808,33 @@ sp_head::set_info(char *definer, uint definerlen,
void
sp_head
::
reset_thd_mem_root
(
THD
*
thd
)
{
DBUG_ENTER
(
"sp_head::reset_thd_mem_root"
);
m_thd_root
=
thd
->
mem_root
;
thd
->
mem_root
=
m_mem_root
;
m_free_list
=
thd
->
free_list
;
// Keep the old list
thd
->
mem_root
=
mem_root
;
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
/* Copy the db, since substatements will point to it */
m_thd_db
=
thd
->
db
;
thd
->
db
=
strmake_root
(
&
thd
->
mem_root
,
thd
->
db
,
thd
->
db_length
);
m_thd
=
thd
;
DBUG_VOID_RETURN
;
}
void
sp_head
::
restore_thd_mem_root
(
THD
*
thd
)
{
Item
*
flist
=
m_free_list
;
// The old list
m_free_list
=
thd
->
free_list
;
// Get the new one
DBUG_ENTER
(
"sp_head::restore_thd_mem_root"
);
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
->
db
=
m_thd_db
;
// Restore the original db pointer
m_mem_root
=
thd
->
mem_root
;
thd
->
mem_root
=
m_thd_root
;
m_thd
=
NULL
;
DBUG_VOID_RETURN
;
}
...
...
@@ -861,6 +864,23 @@ sp_head::show_create_procedure(THD *thd)
DBUG_RETURN
(
res
);
}
/*
Add instruction to SP
SYNOPSIS
sp_head::add_instr()
instr Instruction
*/
void
sp_head
::
add_instr
(
sp_instr
*
instr
)
{
instr
->
free_list
=
m_thd
->
free_list
;
m_thd
->
free_list
=
0
;
insert_dynamic
(
&
m_instr
,
(
gptr
)
&
instr
);
}
int
sp_head
::
show_create_function
(
THD
*
thd
)
{
...
...
@@ -919,7 +939,6 @@ int
sp_instr_stmt
::
exec_stmt
(
THD
*
thd
,
LEX
*
lex
)
{
LEX
*
olex
;
// The other lex
Item
*
freelist
;
SELECT_LEX
*
sl
;
int
res
;
...
...
@@ -927,94 +946,24 @@ sp_instr_stmt::exec_stmt(THD *thd, LEX *lex)
thd
->
lex
=
lex
;
// Use my own lex
thd
->
lex
->
thd
=
thd
;
// QQ Not reentrant!
thd
->
lex
->
unit
.
thd
=
thd
;
// QQ Not reentrant
freelist
=
thd
->
free_list
;
thd
->
free_list
=
NULL
;
VOID
(
pthread_mutex_lock
(
&
LOCK_thread_count
));
thd
->
query_id
=
query_id
++
;
VOID
(
pthread_mutex_unlock
(
&
LOCK_thread_count
));
// Copy WHERE clause pointers to avoid damaging by optimisation
// 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
;
}
}
reset_stmt_for_execute
(
thd
,
lex
);
res
=
mysql_execute_command
(
thd
);
lex
->
unit
.
cleanup
();
if
(
thd
->
lock
||
thd
->
open_tables
||
thd
->
derived_tables
)
{
thd
->
proc_info
=
"closing 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
->
free_list
=
freelist
;
return
res
;
}
...
...
sql/sp_head.h
View file @
350d8a21
...
...
@@ -70,7 +70,7 @@ sp_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 */
void
operator
=
(
sp_head
&
);
...
...
@@ -142,11 +142,8 @@ class sp_head : public Sql_alloc
int
show_create_function
(
THD
*
thd
);
inline
void
add_instr
(
sp_instr
*
i
)
{
insert_dynamic
(
&
m_instr
,
(
gptr
)
&
i
);
}
void
add_instr
(
sp_instr
*
instr
);
inline
uint
instructions
()
...
...
@@ -206,9 +203,7 @@ class sp_head : public Sql_alloc
private:
MEM_ROOT
m_mem_root
;
// My own 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
char
*
m_thd_db
;
// Original thd->db pointer
...
...
@@ -251,13 +246,15 @@ class sp_instr : public Sql_alloc
public:
Item
*
free_list
;
// My Items
// Should give each a name or type code for debugging purposes?
sp_instr
(
uint
ip
)
:
Sql_alloc
(
),
m_ip
(
ip
)
:
Sql_alloc
(),
free_list
(
0
),
m_ip
(
ip
)
{}
virtual
~
sp_instr
()
{}
{
free_items
(
free_list
);
}
// Execute this instrution. '*nextp' will be set to the index of the next
// instruction to execute. (For most instruction this will be the
...
...
sql/sql_base.cc
View file @
350d8a21
...
...
@@ -2158,14 +2158,14 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
{
if
(
!
wild_num
)
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
temporary mem_root to statement mem root to save changes of SELECT list
*/
if
(
stmt
)
thd
->
set_n_backup_item_arena
(
stmt
,
&
backup
);
if
(
arena
)
thd
->
set_n_backup_item_arena
(
arena
,
&
backup
);
reg2
Item
*
item
;
List_iterator
<
Item
>
it
(
fields
);
while
(
wild_num
&&
(
item
=
it
++
))
...
...
@@ -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
,
((
Item_field
*
)
item
)
->
table_name
,
&
it
))
{
if
(
stmt
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
if
(
arena
)
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
return
(
-
1
);
}
if
(
sum_func_list
)
...
...
@@ -2194,8 +2194,15 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
wild_num
--
;
}
}
if
(
stmt
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
if
(
arena
)
{
/* 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
;
}
...
...
@@ -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
)
{
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"
);
thd
->
set_query_id
=
1
;
thd
->
lex
->
current_select
->
cond_count
=
0
;
select_lex
->
cond_count
=
0
;
if
(
*
conds
)
{
thd
->
where
=
"where clause"
;
...
...
@@ -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
->
check_cols
(
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
...
...
@@ -2447,12 +2459,12 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
!
(
specialflag
&
SPECIAL_NO_NEW_FUNC
)))
{
table
->
outer_join
=
0
;
if
(
stmt
)
thd
->
set_n_backup_item_arena
(
stmt
,
&
backup
);
if
(
arena
)
thd
->
set_n_backup_item_arena
(
arena
,
&
backup
);
*
conds
=
and_conds
(
*
conds
,
table
->
on_expr
);
table
->
on_expr
=
0
;
if
(
stmt
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
if
(
arena
)
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
if
((
*
conds
)
&&
!
(
*
conds
)
->
fixed
&&
(
*
conds
)
->
fix_fields
(
thd
,
tables
,
conds
))
DBUG_RETURN
(
1
);
...
...
@@ -2460,8 +2472,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
}
if
(
table
->
natural_join
)
{
if
(
stmt
)
thd
->
set_n_backup_item_arena
(
stmt
,
&
backup
);
if
(
arena
)
thd
->
set_n_backup_item_arena
(
arena
,
&
backup
);
/* Make a join of all fields with have the same name */
TABLE
*
t1
=
table
->
table
;
TABLE
*
t2
=
table
->
natural_join
->
table
;
...
...
@@ -2491,7 +2503,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
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
table
->
natural_join
=
0
;
...
...
@@ -2500,8 +2512,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
{
*
conds
=
and_conds
(
*
conds
,
cond_and
);
// fix_fields() should be made with temporary memory pool
if
(
stmt
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
if
(
arena
)
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
if
(
*
conds
&&
!
(
*
conds
)
->
fixed
)
{
if
((
*
conds
)
->
fix_fields
(
thd
,
tables
,
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
);
// fix_fields() should be made with temporary memory pool
if
(
stmt
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
if
(
arena
)
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
if
(
table
->
on_expr
&&
!
table
->
on_expr
->
fixed
)
{
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)
}
}
if
(
stmt
)
if
(
arena
)
{
/*
We are in prepared statement preparation code => we should store
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
));
err:
if
(
stmt
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
if
(
arena
)
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
DBUG_RETURN
(
1
);
}
...
...
sql/sql_class.cc
View file @
350d8a21
...
...
@@ -86,7 +86,7 @@ extern "C" void free_user_var(user_var_entry *entry)
** 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
),
insert_id_used
(
0
),
rand_used
(
0
),
in_lock_tables
(
0
),
global_read_lock
(
0
),
bootstrap
(
0
),
spcont
(
NULL
)
...
...
@@ -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
::
Statement
(
THD
*
thd
)
:
id
(
++
thd
->
statement_id_counter
),
:
Item_arena
(
thd
),
id
(
++
thd
->
statement_id_counter
),
set_query_id
(
1
),
allow_sum_func
(
0
),
lex
(
&
main_lex
),
query
(
0
),
query_length
(
0
),
free_list
(
0
)
{
init_sql_alloc
(
&
mem_root
,
thd
->
variables
.
query_alloc_block_size
,
thd
->
variables
.
query_prealloc_size
);
}
query_length
(
0
)
{}
/*
This constructor is called when statement is a subobject of THD:
...
...
@@ -1235,15 +1259,14 @@ Statement::Statement(THD *thd)
*/
Statement
::
Statement
()
:
id
(
0
),
:
Item_arena
(),
id
(
0
),
set_query_id
(
1
),
allow_sum_func
(
0
),
/* initialized later */
lex
(
&
main_lex
),
query
(
0
),
/* these two are set */
query_length
(
0
),
/* in alloc_query() */
free_list
(
0
)
query_length
(
0
)
/* in alloc_query() */
{
bzero
((
char
*
)
&
mem_root
,
sizeof
(
mem_root
));
}
...
...
@@ -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
);
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_item_arena
(
backup
);
...
...
@@ -1279,7 +1302,7 @@ void Statement::restore_backup_item_arena(Statement *set, Statement *backup)
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
;
free_list
=
set
->
free_list
;
...
...
sql/sql_class.h
View file @
350d8a21
...
...
@@ -434,6 +434,48 @@ struct system_variables
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.
One connection can contain a lot of simultaneously running statements,
...
...
@@ -448,7 +490,7 @@ void free_tmp_table(THD *thd, TABLE *entry);
be used explicitly.
*/
class
Statement
class
Statement
:
public
Item_arena
{
Statement
(
const
Statement
&
rhs
);
/* not implemented: */
Statement
&
operator
=
(
const
Statement
&
rhs
);
/* non-copyable */
...
...
@@ -489,12 +531,6 @@ class Statement
*/
char
*
query
;
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:
/* We build without RTTI, so dynamic_cast can't be used. */
...
...
@@ -518,31 +554,6 @@ class Statement
/* return class type */
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,
Vio
*
active_vio
;
#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
generated auto_increment value in handler.cc
...
...
@@ -969,7 +980,7 @@ class THD :public ilink,
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,
which will be created by preparation => substitute memory
...
...
@@ -978,7 +989,7 @@ class THD :public ilink,
We know that PS memory pool is now copied to THD, we move it back
to allow some code use it.
*/
current_
statement
->
set_item_arena
(
this
);
current_
arena
->
set_item_arena
(
this
);
init_sql_alloc
(
&
mem_root
,
variables
.
query_alloc_block_size
,
variables
.
query_prealloc_size
);
...
...
@@ -986,12 +997,16 @@ class THD :public ilink,
}
inline
void
free_temporary_memory_pool_for_ps_preparing
()
{
DBUG_ASSERT
(
current_
statement
!=
0
);
cleanup_items
(
current_
statement
->
free_list
);
DBUG_ASSERT
(
current_
arena
!=
0
);
cleanup_items
(
current_
arena
->
free_list
);
free_items
(
free_list
);
close_thread_tables
(
this
);
// to close derived tables
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 @
350d8a21
...
...
@@ -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
->
select_lex
.
table_list
.
first
);
SELECT_LEX
*
select_lex
=
&
thd
->
lex
->
select_lex
;
DBUG_ENTER
(
"mysql_prepare_delete"
);
if
(
setup_conds
(
thd
,
delete_table_list
,
conds
)
||
setup_ftfuncs
(
&
thd
->
lex
->
select_lex
))
setup_ftfuncs
(
select_lex
))
DBUG_RETURN
(
-
1
);
if
(
find_real_table_in_list
(
table_list
->
next
,
table_list
->
db
,
table_list
->
real_name
))
...
...
@@ -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
);
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
);
}
...
...
sql/sql_derived.cc
View file @
350d8a21
...
...
@@ -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
can skip execution (and parameters is not defined, too)
*/
if
(
!
thd
->
current_statement
)
if
(
!
thd
->
only_prepare
()
)
{
if
(
is_union
)
{
...
...
sql/sql_insert.cc
View file @
350d8a21
...
...
@@ -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
);
DBUG_RETURN
(
-
1
);
}
thd
->
lex
->
select_lex
.
first_execution
=
0
;
DBUG_RETURN
(
0
);
}
...
...
sql/sql_lex.cc
View file @
350d8a21
...
...
@@ -1011,10 +1011,12 @@ void st_select_lex::init_query()
having_fix_field
=
0
;
resolve_mode
=
NOMATTER_MODE
;
cond_count
=
with_wild
=
0
;
conds_processed_with_permanent_arena
=
0
;
ref_pointer_array
=
0
;
select_n_having_items
=
0
;
prep_where
=
0
;
explicit_limit
=
0
;
first_execution
=
1
;
}
void
st_select_lex
::
init_select
()
...
...
@@ -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
)
{
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)
We have to create array in prepared statement memory if it is
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
=
(
Item
**
)
stmt
->
alloc
(
sizeof
(
Item
*
)
*
(
Item
**
)
arena
->
alloc
(
sizeof
(
Item
*
)
*
(
item_list
.
elements
+
select_n_having_items
+
order_group_num
)
*
5
))
==
0
;
...
...
sql/sql_lex.h
View file @
350d8a21
...
...
@@ -405,8 +405,6 @@ class st_select_lex: public st_select_lex_node
enum
olap_type
olap
;
SQL_LIST
table_list
,
group_list
;
/* FROM & GROUP BY clauses */
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
,
ignore_index
,
*
ignore_index_ptr
;
/*
...
...
@@ -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 */
enum_parsing_place
parsing_place
;
/* where we are parsing expression */
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
;
uint
in_sum_expr
;
...
...
@@ -445,6 +448,7 @@ class st_select_lex: public st_select_lex_node
bool
having_fix_field
;
/* explicit LIMIT clause was used */
bool
explicit_limit
;
bool
first_execution
;
/* first execution in SP or PS */
/*
SELECT for SELECT command st_select_lex. Used to privent scaning
...
...
sql/sql_parse.cc
View file @
350d8a21
...
...
@@ -4182,12 +4182,14 @@ void mysql_parse(THD *thd, char *inBuf, uint length)
query_cache_end_of_result
(
thd
);
}
}
lex
->
unit
.
cleanup
();
}
else
{
DBUG_PRINT
(
"info"
,(
"Command aborted. Fatal_error: %d"
,
thd
->
is_fatal_error
));
query_cache_abort
(
&
thd
->
net
);
lex
->
unit
.
cleanup
();
if
(
thd
->
lex
->
sphead
)
{
/* Clean up after failed stored procedure/function */
...
...
sql/sql_prepare.cc
View file @
350d8a21
...
...
@@ -1357,7 +1357,7 @@ void mysql_stmt_prepare(THD *thd, char *packet, uint packet_length)
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
);
mysql_init_query
(
thd
);
lex
->
safe_to_cache_query
=
0
;
...
...
@@ -1381,7 +1381,7 @@ void mysql_stmt_prepare(THD *thd, char *packet, uint packet_length)
stmt
->
set_item_arena
(
thd
);
thd
->
set_statement
(
&
thd
->
stmt_backup
);
thd
->
set_item_arena
(
&
thd
->
stmt_backup
);
thd
->
current_
statement
=
0
;
thd
->
current_
arena
=
0
;
if
(
error
)
{
...
...
@@ -1389,29 +1389,18 @@ void mysql_stmt_prepare(THD *thd, char *packet, uint packet_length)
thd
->
stmt_map
.
erase
(
stmt
);
/* 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
;
}
/* 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
=
stmt
->
lex
->
all_selects_list
;
SELECT_LEX
*
sl
=
lex
->
all_selects_list
;
for
(;
sl
;
sl
=
sl
->
next_select_in_list
())
{
if
(
!
sl
->
first_execution
)
{
/*
Copy WHERE clause pointers to avoid damaging they by optimisation
...
...
@@ -1426,6 +1415,7 @@ static void reset_stmt_for_execute(Prepared_statement *stmt)
/* Fix ORDER list */
for
(
order
=
(
ORDER
*
)
sl
->
order_list
.
first
;
order
;
order
=
order
->
next
)
order
->
item
=
&
order
->
item_ptr
;
}
/*
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)
tables
->
table
=
0
;
tables
->
table_list
=
0
;
}
{
SELECT_LEX_UNIT
*
unit
=
sl
->
master_unit
();
unit
->
unclean
();
...
...
@@ -1506,7 +1495,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
thd
->
stmt_backup
.
set_statement
(
thd
);
thd
->
set_statement
(
stmt
);
reset_stmt_for_execute
(
stmt
);
reset_stmt_for_execute
(
thd
,
stmt
->
lex
);
#ifndef EMBEDDED_LIBRARY
if
(
stmt
->
param_count
)
{
...
...
sql/sql_select.cc
View file @
350d8a21
...
...
@@ -367,9 +367,16 @@ JOIN::prepare(Item ***rref_pointer_array,
Item_subselect
::
trans_res
res
;
if
((
res
=
subselect
->
select_transformer
(
this
))
!=
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
));
}
}
}
if
(
setup_ftfuncs
(
select_lex
))
/* should be after having->fix_fields */
DBUG_RETURN
(
-
1
);
...
...
@@ -470,6 +477,11 @@ JOIN::prepare(Item ***rref_pointer_array,
if
(
alloc_func_list
())
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
err:
...
...
sql/sql_union.cc
View file @
350d8a21
...
...
@@ -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
;
if
(
!
item_list
.
elements
)
{
Statement
*
stmt
=
thd
->
current_statement
;
Statement
backup
;
if
(
stmt
)
thd
->
set_n_backup_item_arena
(
stmt
,
&
backup
);
Item_arena
*
arena
=
thd
->
current_arena
;
Item_arena
backup
;
if
(
arena
)
thd
->
set_n_backup_item_arena
(
arena
,
&
backup
);
Field
**
field
;
for
(
field
=
table
->
field
;
*
field
;
field
++
)
{
Item_field
*
item
=
new
Item_field
(
*
field
);
if
(
!
item
||
item_list
.
push_back
(
item
))
{
if
(
stmt
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
if
(
arena
)
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
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 */
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
,
result
)))
{
...
...
sql/sql_update.cc
View file @
350d8a21
...
...
@@ -425,6 +425,7 @@ int mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
TABLE
*
table
=
table_list
->
table
;
TABLE_LIST
tables
;
List
<
Item
>
all_fields
;
SELECT_LEX
*
select_lex
=
&
thd
->
lex
->
select_lex
;
DBUG_ENTER
(
"mysql_prepare_update"
);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
...
...
@@ -437,10 +438,10 @@ int mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
if
(
setup_tables
(
update_table_list
)
||
setup_conds
(
thd
,
update_table_list
,
conds
)
||
thd
->
lex
->
select_lex
.
setup_ref_array
(
thd
,
order_num
)
||
setup_order
(
thd
,
thd
->
lex
->
select_lex
.
ref_pointer_array
,
select_lex
->
setup_ref_array
(
thd
,
order_num
)
||
setup_order
(
thd
,
select_lex
->
ref_pointer_array
,
update_table_list
,
all_fields
,
all_fields
,
order
)
||
setup_ftfuncs
(
&
thd
->
lex
->
select_lex
))
setup_ftfuncs
(
select_lex
))
DBUG_RETURN
(
-
1
);
/* 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,
my_error
(
ER_UPDATE_TABLE_USED
,
MYF
(
0
),
table_list
->
real_name
);
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
);
}
...
...
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