Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
75454b0a
Commit
75454b0a
authored
Aug 21, 2004
by
konstantin@mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge bk-internal.mysql.com:/home/bk/mysql-4.1
into mysql.com:/home/kostja/work/mysql-4.1-4912
parents
325ea1b9
568c6e85
Changes
17
Show whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
317 additions
and
261 deletions
+317
-261
mysql-test/r/ps.result
mysql-test/r/ps.result
+7
-0
mysql-test/t/ps.test
mysql-test/t/ps.test
+12
-0
sql/item_cmpfunc.cc
sql/item_cmpfunc.cc
+1
-3
sql/item_subselect.cc
sql/item_subselect.cc
+26
-24
sql/item_subselect.h
sql/item_subselect.h
+0
-2
sql/item_sum.cc
sql/item_sum.cc
+10
-10
sql/item_sum.h
sql/item_sum.h
+2
-2
sql/mysql_priv.h
sql/mysql_priv.h
+1
-1
sql/sql_base.cc
sql/sql_base.cc
+22
-21
sql/sql_class.cc
sql/sql_class.cc
+64
-14
sql/sql_class.h
sql/sql_class.h
+60
-68
sql/sql_derived.cc
sql/sql_derived.cc
+1
-1
sql/sql_lex.cc
sql/sql_lex.cc
+2
-2
sql/sql_parse.cc
sql/sql_parse.cc
+3
-0
sql/sql_prepare.cc
sql/sql_prepare.cc
+69
-89
sql/sql_select.cc
sql/sql_select.cc
+30
-16
sql/sql_union.cc
sql/sql_union.cc
+7
-8
No files found.
mysql-test/r/ps.result
View file @
75454b0a
...
@@ -219,3 +219,10 @@ Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length I
...
@@ -219,3 +219,10 @@ Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length I
t1 MyISAM 9 Dynamic 0 0 0 4294967295 1024 0 NULL # # # latin1_swedish_ci NULL
t1 MyISAM 9 Dynamic 0 0 0 4294967295 1024 0 NULL # # # latin1_swedish_ci NULL
deallocate prepare stmt1 ;
deallocate prepare stmt1 ;
drop table t1;
drop table t1;
create table t1(a varchar(2), b varchar(3));
prepare stmt1 from "select a, b from t1 where (not (a='aa' and b < 'zzz'))";
execute stmt1;
a b
execute stmt1;
a b
deallocate prepare stmt1;
mysql-test/t/ps.test
View file @
75454b0a
...
@@ -206,3 +206,15 @@ execute stmt1;
...
@@ -206,3 +206,15 @@ execute stmt1;
show
table
status
from
test
like
't1%'
;
show
table
status
from
test
like
't1%'
;
deallocate
prepare
stmt1
;
deallocate
prepare
stmt1
;
drop
table
t1
;
drop
table
t1
;
#
# Bug#4912 "mysqld crashs in case a statement is executed a second time":
# negation elimination should and prepared statemens
#
create
table
t1
(
a
varchar
(
2
),
b
varchar
(
3
));
prepare
stmt1
from
"select a, b from t1 where (not (a='aa' and b < 'zzz'))"
;
execute
stmt1
;
execute
stmt1
;
deallocate
prepare
stmt1
;
sql/item_cmpfunc.cc
View file @
75454b0a
...
@@ -589,10 +589,8 @@ bool Item_in_optimizer::fix_left(THD *thd,
...
@@ -589,10 +589,8 @@ bool Item_in_optimizer::fix_left(THD *thd,
/*
/*
If it is preparation PS only then we do not know values of parameters =>
If it is preparation PS only then we do not know values of parameters =>
cant't get there values and do not need that values.
cant't get there values and do not need that values.
TODO: during merge with 5.0 it should be changed on !thd->only_prepare()
*/
*/
if
(
!
thd
->
current_statement
)
if
(
!
thd
->
current_arena
->
is_stmt_prepare
()
)
cache
->
store
(
args
[
0
]);
cache
->
store
(
args
[
0
]);
if
(
cache
->
cols
()
==
1
)
if
(
cache
->
cols
()
==
1
)
{
{
...
...
sql/item_subselect.cc
View file @
75454b0a
...
@@ -125,7 +125,6 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref)
...
@@ -125,7 +125,6 @@ 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
;
char
const
*
save_where
=
thd
->
where
;
char
const
*
save_where
=
thd
->
where
;
int
res
;
int
res
;
...
@@ -306,7 +305,10 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
...
@@ -306,7 +305,10 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
return
RES_OK
;
return
RES_OK
;
SELECT_LEX
*
select_lex
=
join
->
select_lex
;
SELECT_LEX
*
select_lex
=
join
->
select_lex
;
Statement
backup
;
/* Juggle with current arena only if we're in prepared statement prepare */
Item_arena
*
arena
=
join
->
thd
->
current_arena
;
Item_arena
backup
;
if
(
!
select_lex
->
master_unit
()
->
first_select
()
->
next_select
()
&&
if
(
!
select_lex
->
master_unit
()
->
first_select
()
->
next_select
()
&&
!
select_lex
->
table_list
.
elements
&&
!
select_lex
->
table_list
.
elements
&&
...
@@ -341,8 +343,8 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
...
@@ -341,8 +343,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
->
is_stmt_prepare
()
)
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
;
...
@@ -355,15 +357,15 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
...
@@ -355,15 +357,15 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
new
Item_null
())))
new
Item_null
())))
goto
err
;
goto
err
;
}
}
if
(
stmt
)
if
(
arena
->
is_stmt_prepare
()
)
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
->
is_stmt_prepare
()
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
return
RES_ERROR
;
return
RES_ERROR
;
}
}
...
@@ -640,11 +642,11 @@ Item_in_subselect::single_value_transformer(JOIN *join,
...
@@ -640,11 +642,11 @@ Item_in_subselect::single_value_transformer(JOIN *join,
}
}
SELECT_LEX
*
select_lex
=
join
->
select_lex
;
SELECT_LEX
*
select_lex
=
join
->
select_lex
;
Statement
backup
;
Item_arena
*
arena
=
join
->
thd
->
current_arena
,
backup
;
thd
->
where
=
"scalar IN/ALL/ANY subquery"
;
thd
->
where
=
"scalar IN/ALL/ANY subquery"
;
if
(
stmt
)
if
(
arena
->
is_stmt_prepare
()
)
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
)
{
{
...
@@ -857,21 +859,21 @@ Item_in_subselect::single_value_transformer(JOIN *join,
...
@@ -857,21 +859,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
->
is_stmt_prepare
()
)
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
->
is_stmt_prepare
()
)
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
->
is_stmt_prepare
()
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
DBUG_RETURN
(
RES_ERROR
);
DBUG_RETURN
(
RES_ERROR
);
}
}
...
@@ -885,12 +887,12 @@ Item_in_subselect::row_value_transformer(JOIN *join)
...
@@ -885,12 +887,12 @@ Item_in_subselect::row_value_transformer(JOIN *join)
{
{
DBUG_RETURN
(
RES_OK
);
DBUG_RETURN
(
RES_OK
);
}
}
Statement
backup
;
Item_arena
*
arena
=
join
->
thd
->
current_arena
,
backup
;
Item
*
item
=
0
;
Item
*
item
=
0
;
thd
->
where
=
"row IN/ALL/ANY subquery"
;
thd
->
where
=
"row IN/ALL/ANY subquery"
;
if
(
stmt
)
if
(
arena
->
is_stmt_prepare
()
)
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
;
...
@@ -974,13 +976,13 @@ Item_in_subselect::row_value_transformer(JOIN *join)
...
@@ -974,13 +976,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
->
is_stmt_prepare
()
)
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
->
is_stmt_prepare
()
)
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 @
75454b0a
...
@@ -36,8 +36,6 @@ class Item_subselect :public Item_result_field
...
@@ -36,8 +36,6 @@ 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 */
Statement
*
stmt
;
/* 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 @
75454b0a
...
@@ -64,28 +64,28 @@ Item_sum::Item_sum(THD *thd, Item_sum *item):
...
@@ -64,28 +64,28 @@ Item_sum::Item_sum(THD *thd, Item_sum *item):
/*
/*
Save copy of arguments if we
are
prepare prepared statement
Save copy of arguments if we prepare prepared statement
(arguments can be rewritten in get_tmp_table_item())
(arguments can be rewritten in get_tmp_table_item())
SYNOPSIS
SYNOPSIS
Item_sum::save_args_for_prepared_statement
s
()
Item_sum::save_args_for_prepared_statement()
thd - thread handler
thd - thread handler
RETURN
RETURN
0 - OK
0 - OK
1 - Error
1 - Error
*/
*/
bool
Item_sum
::
save_args_for_prepared_statement
s
(
THD
*
thd
)
bool
Item_sum
::
save_args_for_prepared_statement
(
THD
*
thd
)
{
{
if
(
thd
->
current_
statement
)
if
(
thd
->
current_
arena
->
is_stmt_prepare
()
)
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
;
...
@@ -214,7 +214,7 @@ Item_sum_num::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
...
@@ -214,7 +214,7 @@ Item_sum_num::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{
{
DBUG_ASSERT
(
fixed
==
0
);
DBUG_ASSERT
(
fixed
==
0
);
if
(
save_args_for_prepared_statement
s
(
thd
))
if
(
save_args_for_prepared_statement
(
thd
))
return
1
;
return
1
;
if
(
!
thd
->
allow_sum_func
)
if
(
!
thd
->
allow_sum_func
)
...
@@ -248,7 +248,7 @@ Item_sum_hybrid::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
...
@@ -248,7 +248,7 @@ Item_sum_hybrid::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{
{
DBUG_ASSERT
(
fixed
==
0
);
DBUG_ASSERT
(
fixed
==
0
);
if
(
save_args_for_prepared_statement
s
(
thd
))
if
(
save_args_for_prepared_statement
(
thd
))
return
1
;
return
1
;
Item
*
item
=
args
[
0
];
Item
*
item
=
args
[
0
];
...
@@ -1947,7 +1947,7 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
...
@@ -1947,7 +1947,7 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{
{
DBUG_ASSERT
(
fixed
==
0
);
DBUG_ASSERT
(
fixed
==
0
);
if
(
save_args_for_prepared_statement
s
(
thd
))
if
(
save_args_for_prepared_statement
(
thd
))
return
1
;
return
1
;
uint
i
;
/* for loop variable */
uint
i
;
/* for loop variable */
...
...
sql/item_sum.h
View file @
75454b0a
...
@@ -92,8 +92,8 @@ public:
...
@@ -92,8 +92,8 @@ public:
virtual
bool
setup
(
THD
*
thd
)
{
return
0
;}
virtual
bool
setup
(
THD
*
thd
)
{
return
0
;}
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_statement
s
(
THD
*
);
bool
save_args_for_prepared_statement
(
THD
*
);
bool
save_args
(
Statement
*
stmt
);
bool
save_args
(
Item_arena
*
arena
);
bool
walk
(
Item_processor
processor
,
byte
*
argument
);
bool
walk
(
Item_processor
processor
,
byte
*
argument
);
};
};
...
...
sql/mysql_priv.h
View file @
75454b0a
...
@@ -295,7 +295,7 @@ void debug_sync_point(const char* lock_name, uint lock_timeout);
...
@@ -295,7 +295,7 @@ void debug_sync_point(const char* lock_name, uint lock_timeout);
struct
st_table
;
struct
st_table
;
class
THD
;
class
THD
;
class
Statement
;
class
Item_arena
;
/* Struct to handle simple linked lists */
/* Struct to handle simple linked lists */
...
...
sql/sql_base.cc
View file @
75454b0a
...
@@ -2251,14 +2251,15 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
...
@@ -2251,14 +2251,15 @@ 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
->
is_stmt_prepare
())
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
++
))
...
@@ -2282,8 +2283,8 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
...
@@ -2282,8 +2283,8 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
else
if
(
insert_fields
(
thd
,
tables
,((
Item_field
*
)
item
)
->
db_name
,
else
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
->
is_stmt_prepare
()
)
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
)
...
@@ -2298,8 +2299,8 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
...
@@ -2298,8 +2299,8 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
wild_num
--
;
wild_num
--
;
}
}
}
}
if
(
stmt
)
if
(
arena
->
is_stmt_prepare
()
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
return
0
;
return
0
;
}
}
...
@@ -2512,7 +2513,7 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name,
...
@@ -2512,7 +2513,7 @@ 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
;
Item_arena
*
arena
=
thd
->
current_arena
,
backup
;
DBUG_ENTER
(
"setup_conds"
);
DBUG_ENTER
(
"setup_conds"
);
thd
->
set_query_id
=
1
;
thd
->
set_query_id
=
1
;
...
@@ -2551,12 +2552,12 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
...
@@ -2551,12 +2552,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
->
is_stmt_prepare
()
)
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
->
is_stmt_prepare
()
)
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
);
...
@@ -2564,8 +2565,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
...
@@ -2564,8 +2565,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
}
}
if
(
table
->
natural_join
)
if
(
table
->
natural_join
)
{
{
if
(
stmt
)
if
(
arena
->
is_stmt_prepare
()
)
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
;
...
@@ -2606,8 +2607,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
...
@@ -2606,8 +2607,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
->
is_stmt_prepare
()
)
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
))
...
@@ -2618,8 +2619,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
...
@@ -2618,8 +2619,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
->
is_stmt_prepare
()
)
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
))
...
@@ -2630,7 +2631,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
...
@@ -2630,7 +2631,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
}
}
}
}
if
(
stmt
)
if
(
arena
->
is_stmt_prepare
()
)
{
{
/*
/*
We are in prepared statement preparation code => we should store
We are in prepared statement preparation code => we should store
...
@@ -2643,8 +2644,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
...
@@ -2643,8 +2644,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
DBUG_RETURN
(
test
(
thd
->
net
.
report_error
));
DBUG_RETURN
(
test
(
thd
->
net
.
report_error
));
err:
err:
if
(
stmt
)
if
(
arena
->
is_stmt_prepare
()
)
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 @
75454b0a
...
@@ -155,7 +155,7 @@ bool foreign_key_prefix(Key *a, Key *b)
...
@@ -155,7 +155,7 @@ bool foreign_key_prefix(Key *a, Key *b)
** 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
(
this
),
is_fatal_error
(
0
),
last_insert_id_used
(
0
),
last_insert_id_used
(
0
),
insert_id_used
(
0
),
rand_used
(
0
),
time_zone_used
(
0
),
insert_id_used
(
0
),
rand_used
(
0
),
time_zone_used
(
0
),
in_lock_tables
(
0
),
global_read_lock
(
0
),
bootstrap
(
0
)
in_lock_tables
(
0
),
global_read_lock
(
0
),
bootstrap
(
0
)
...
@@ -1301,23 +1301,59 @@ int select_dumpvar::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
...
@@ -1301,23 +1301,59 @@ int select_dumpvar::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
}
}
Item_arena
::
Item_arena
(
THD
*
thd
)
:
free_list
(
0
),
state
(
INITIALIZED
)
{
init_sql_alloc
(
&
mem_root
,
thd
->
variables
.
query_alloc_block_size
,
thd
->
variables
.
query_prealloc_size
);
}
/* This constructor is called when Item_arena is a subobject of THD */
Item_arena
::
Item_arena
()
:
free_list
(
0
),
state
(
CONVENTIONAL_EXECUTION
)
{
clear_alloc_root
(
&
mem_root
);
}
Item_arena
::
Item_arena
(
bool
init_mem_root
)
:
free_list
(
0
),
state
(
INITIALIZED
)
{
if
(
init_mem_root
)
clear_alloc_root
(
&
mem_root
);
}
Item_arena
::
Type
Item_arena
::
type
()
const
{
DBUG_ASSERT
(
"Item_arena::type()"
==
"abstract"
);
return
STATEMENT
;
}
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
)
{
{
name
.
str
=
NULL
;
name
.
str
=
NULL
;
init_sql_alloc
(
&
mem_root
,
thd
->
variables
.
query_alloc_block_size
,
thd
->
variables
.
query_prealloc_size
);
}
}
/*
/*
...
@@ -1332,14 +1368,12 @@ Statement::Statement()
...
@@ -1332,14 +1368,12 @@ Statement::Statement()
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
));
}
}
Statement
::
Type
Statement
::
type
()
const
Item_arena
::
Type
Statement
::
type
()
const
{
{
return
STATEMENT
;
return
STATEMENT
;
}
}
...
@@ -1356,14 +1390,29 @@ void Statement::set_statement(Statement *stmt)
...
@@ -1356,14 +1390,29 @@ void Statement::set_statement(Statement *stmt)
}
}
void
Statement
::
set_n_backup_item_arena
(
Statement
*
set
,
Statement
*
backup
)
void
Statement
::
set_n_backup_statement
(
Statement
*
stmt
,
Statement
*
backup
)
{
backup
->
set_statement
(
this
);
set_statement
(
stmt
);
}
void
Statement
::
restore_backup_statement
(
Statement
*
stmt
,
Statement
*
backup
)
{
stmt
->
set_statement
(
this
);
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
);
...
@@ -1371,10 +1420,11 @@ void Statement::restore_backup_item_arena(Statement *set, Statement *backup)
...
@@ -1371,10 +1420,11 @@ 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
;
state
=
set
->
state
;
}
}
Statement
::~
Statement
()
Statement
::~
Statement
()
...
...
sql/sql_class.h
View file @
75454b0a
...
@@ -418,6 +418,61 @@ struct system_variables
...
@@ -418,6 +418,61 @@ 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
;
static
const
int
INITIALIZED
=
0
,
PREPARED
=
1
,
EXECUTED
=
3
,
CONVENTIONAL_EXECUTION
=
2
,
ERROR
=
-
1
;
int
state
;
/* We build without RTTI, so dynamic_cast can't be used. */
enum
Type
{
STATEMENT
,
PREPARED_STATEMENT
,
STORED_PROCEDURE
};
Item_arena
(
THD
*
thd
);
Item_arena
();
Item_arena
(
bool
init_mem_root
);
virtual
Type
type
()
const
;
virtual
~
Item_arena
();
inline
bool
is_stmt_prepare
()
const
{
return
state
<
PREPARED
;
}
inline
bool
is_first_stmt_execute
()
const
{
return
state
==
PREPARED
;
}
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,
...
@@ -432,7 +487,7 @@ void free_tmp_table(THD *thd, TABLE *entry);
...
@@ -432,7 +487,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 */
...
@@ -474,20 +529,8 @@ public:
...
@@ -474,20 +529,8 @@ public:
*/
*/
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. */
enum
Type
{
STATEMENT
,
PREPARED_STATEMENT
};
/*
/*
This constructor is called when statement is a subobject of THD:
This constructor is called when statement is a subobject of THD:
...
@@ -500,34 +543,10 @@ public:
...
@@ -500,34 +543,10 @@ public:
/* Assign execution context (note: not all members) of given stmt to self */
/* Assign execution context (note: not all members) of given stmt to self */
void
set_statement
(
Statement
*
stmt
);
void
set_statement
(
Statement
*
stmt
);
void
set_n_backup_statement
(
Statement
*
stmt
,
Statement
*
backup
);
void
restore_backup_statement
(
Statement
*
stmt
,
Statement
*
backup
);
/* 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
);
};
};
...
@@ -760,9 +779,9 @@ public:
...
@@ -760,9 +779,9 @@ public:
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
...
@@ -983,33 +1002,6 @@ public:
...
@@ -983,33 +1002,6 @@ public:
}
}
inline
CHARSET_INFO
*
charset
()
{
return
variables
.
character_set_client
;
}
inline
CHARSET_INFO
*
charset
()
{
return
variables
.
character_set_client
;
}
void
update_charset
();
void
update_charset
();
inline
void
allocate_temporary_memory_pool_for_ps_preparing
()
{
DBUG_ASSERT
(
current_statement
!=
0
);
/*
We do not want to have in PS memory all that junk,
which will be created by preparation => substitute memory
from original thread pool.
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
);
init_sql_alloc
(
&
mem_root
,
variables
.
query_alloc_block_size
,
variables
.
query_prealloc_size
);
free_list
=
0
;
}
inline
void
free_temporary_memory_pool_for_ps_preparing
()
{
DBUG_ASSERT
(
current_statement
!=
0
);
cleanup_items
(
current_statement
->
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
);
}
};
};
/* Flags for the THD::system_thread (bitmap) variable */
/* Flags for the THD::system_thread (bitmap) variable */
...
...
sql/sql_derived.cc
View file @
75454b0a
...
@@ -151,7 +151,7 @@ static int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
...
@@ -151,7 +151,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
->
current_arena
->
is_stmt_prepare
()
)
{
{
if
(
is_union
)
if
(
is_union
)
{
{
...
...
sql/sql_lex.cc
View file @
75454b0a
...
@@ -1527,9 +1527,9 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
...
@@ -1527,9 +1527,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
;
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_parse.cc
View file @
75454b0a
...
@@ -1543,6 +1543,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
...
@@ -1543,6 +1543,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
break
;
break
;
mysqld_list_fields
(
thd
,
&
table_list
,
fields
);
mysqld_list_fields
(
thd
,
&
table_list
,
fields
);
free_items
(
thd
->
free_list
);
free_items
(
thd
->
free_list
);
thd
->
free_list
=
0
;
break
;
break
;
}
}
#endif
#endif
...
@@ -4047,6 +4048,7 @@ void mysql_parse(THD *thd, char *inBuf, uint length)
...
@@ -4047,6 +4048,7 @@ void mysql_parse(THD *thd, char *inBuf, uint length)
}
}
thd
->
proc_info
=
"freeing items"
;
thd
->
proc_info
=
"freeing items"
;
free_items
(
thd
->
free_list
);
/* Free strings used by items */
free_items
(
thd
->
free_list
);
/* Free strings used by items */
thd
->
free_list
=
0
;
lex_end
(
lex
);
lex_end
(
lex
);
}
}
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
...
@@ -4073,6 +4075,7 @@ bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length)
...
@@ -4073,6 +4075,7 @@ bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length)
all_tables_not_ok
(
thd
,(
TABLE_LIST
*
)
lex
->
select_lex
.
table_list
.
first
))
all_tables_not_ok
(
thd
,(
TABLE_LIST
*
)
lex
->
select_lex
.
table_list
.
first
))
error
=
1
;
/* Ignore question */
error
=
1
;
/* Ignore question */
free_items
(
thd
->
free_list
);
/* Free strings used by items */
free_items
(
thd
->
free_list
);
/* Free strings used by items */
thd
->
free_list
=
0
;
lex_end
(
lex
);
lex_end
(
lex
);
return
error
;
return
error
;
...
...
sql/sql_prepare.cc
View file @
75454b0a
...
@@ -88,7 +88,6 @@ public:
...
@@ -88,7 +88,6 @@ public:
uint
param_count
;
uint
param_count
;
uint
last_errno
;
uint
last_errno
;
char
last_error
[
MYSQL_ERRMSG_SIZE
];
char
last_error
[
MYSQL_ERRMSG_SIZE
];
bool
get_longdata_error
;
#ifndef EMBEDDED_LIBRARY
#ifndef EMBEDDED_LIBRARY
bool
(
*
set_params
)(
Prepared_statement
*
st
,
uchar
*
data
,
uchar
*
data_end
,
bool
(
*
set_params
)(
Prepared_statement
*
st
,
uchar
*
data
,
uchar
*
data_end
,
uchar
*
read_pos
,
String
*
expanded_query
);
uchar
*
read_pos
,
String
*
expanded_query
);
...
@@ -102,7 +101,7 @@ public:
...
@@ -102,7 +101,7 @@ public:
Prepared_statement
(
THD
*
thd_arg
);
Prepared_statement
(
THD
*
thd_arg
);
virtual
~
Prepared_statement
();
virtual
~
Prepared_statement
();
void
setup_set_params
();
void
setup_set_params
();
virtual
Statement
::
Type
type
()
const
;
virtual
Item_arena
::
Type
type
()
const
;
};
};
static
void
execute_stmt
(
THD
*
thd
,
Prepared_statement
*
stmt
,
static
void
execute_stmt
(
THD
*
thd
,
Prepared_statement
*
stmt
,
...
@@ -133,7 +132,7 @@ find_prepared_statement(THD *thd, ulong id, const char *where,
...
@@ -133,7 +132,7 @@ find_prepared_statement(THD *thd, ulong id, const char *where,
{
{
Statement
*
stmt
=
thd
->
stmt_map
.
find
(
id
);
Statement
*
stmt
=
thd
->
stmt_map
.
find
(
id
);
if
(
stmt
==
0
||
stmt
->
type
()
!=
Statement
::
PREPARED_STATEMENT
)
if
(
stmt
==
0
||
stmt
->
type
()
!=
Item_arena
::
PREPARED_STATEMENT
)
{
{
char
llbuf
[
22
];
char
llbuf
[
22
];
my_error
(
ER_UNKNOWN_STMT_HANDLER
,
MYF
(
0
),
22
,
llstr
(
id
,
llbuf
),
where
);
my_error
(
ER_UNKNOWN_STMT_HANDLER
,
MYF
(
0
),
22
,
llstr
(
id
,
llbuf
),
where
);
...
@@ -896,10 +895,8 @@ static int mysql_test_insert(Prepared_statement *stmt,
...
@@ -896,10 +895,8 @@ static int mysql_test_insert(Prepared_statement *stmt,
open temporary memory pool for temporary data allocated by derived
open temporary memory pool for temporary data allocated by derived
tables & preparation procedure
tables & preparation procedure
*/
*/
thd
->
allocate_temporary_memory_pool_for_ps_preparing
();
if
(
open_and_lock_tables
(
thd
,
table_list
))
if
(
open_and_lock_tables
(
thd
,
table_list
))
{
{
thd
->
free_temporary_memory_pool_for_ps_preparing
();
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
...
@@ -934,7 +931,6 @@ static int mysql_test_insert(Prepared_statement *stmt,
...
@@ -934,7 +931,6 @@ static int mysql_test_insert(Prepared_statement *stmt,
res
=
0
;
res
=
0
;
error:
error:
lex
->
unit
.
cleanup
();
lex
->
unit
.
cleanup
();
thd
->
free_temporary_memory_pool_for_ps_preparing
();
DBUG_RETURN
(
res
);
DBUG_RETURN
(
res
);
}
}
...
@@ -963,12 +959,6 @@ static int mysql_test_update(Prepared_statement *stmt,
...
@@ -963,12 +959,6 @@ static int mysql_test_update(Prepared_statement *stmt,
if
((
res
=
update_precheck
(
thd
,
table_list
)))
if
((
res
=
update_precheck
(
thd
,
table_list
)))
DBUG_RETURN
(
res
);
DBUG_RETURN
(
res
);
/*
open temporary memory pool for temporary data allocated by derived
tables & preparation procedure
*/
thd
->
allocate_temporary_memory_pool_for_ps_preparing
();
if
(
open_and_lock_tables
(
thd
,
table_list
))
if
(
open_and_lock_tables
(
thd
,
table_list
))
res
=
-
1
;
res
=
-
1
;
else
else
...
@@ -988,7 +978,6 @@ static int mysql_test_update(Prepared_statement *stmt,
...
@@ -988,7 +978,6 @@ static int mysql_test_update(Prepared_statement *stmt,
}
}
stmt
->
lex
->
unit
.
cleanup
();
stmt
->
lex
->
unit
.
cleanup
();
}
}
thd
->
free_temporary_memory_pool_for_ps_preparing
();
/* TODO: here we should send types of placeholders to the client. */
/* TODO: here we should send types of placeholders to the client. */
DBUG_RETURN
(
res
);
DBUG_RETURN
(
res
);
}
}
...
@@ -1018,12 +1007,6 @@ static int mysql_test_delete(Prepared_statement *stmt,
...
@@ -1018,12 +1007,6 @@ static int mysql_test_delete(Prepared_statement *stmt,
if
((
res
=
delete_precheck
(
thd
,
table_list
)))
if
((
res
=
delete_precheck
(
thd
,
table_list
)))
DBUG_RETURN
(
res
);
DBUG_RETURN
(
res
);
/*
open temporary memory pool for temporary data allocated by derived
tables & preparation procedure
*/
thd
->
allocate_temporary_memory_pool_for_ps_preparing
();
if
(
open_and_lock_tables
(
thd
,
table_list
))
if
(
open_and_lock_tables
(
thd
,
table_list
))
res
=
-
1
;
res
=
-
1
;
else
else
...
@@ -1031,7 +1014,6 @@ static int mysql_test_delete(Prepared_statement *stmt,
...
@@ -1031,7 +1014,6 @@ static int mysql_test_delete(Prepared_statement *stmt,
res
=
mysql_prepare_delete
(
thd
,
table_list
,
&
lex
->
select_lex
.
where
);
res
=
mysql_prepare_delete
(
thd
,
table_list
,
&
lex
->
select_lex
.
where
);
lex
->
unit
.
cleanup
();
lex
->
unit
.
cleanup
();
}
}
thd
->
free_temporary_memory_pool_for_ps_preparing
();
/* TODO: here we should send types of placeholders to the client. */
/* TODO: here we should send types of placeholders to the client. */
DBUG_RETURN
(
res
);
DBUG_RETURN
(
res
);
}
}
...
@@ -1073,11 +1055,6 @@ static int mysql_test_select(Prepared_statement *stmt,
...
@@ -1073,11 +1055,6 @@ static int mysql_test_select(Prepared_statement *stmt,
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
#endif
#endif
/*
open temporary memory pool for temporary data allocated by derived
tables & preparation procedure
*/
thd
->
allocate_temporary_memory_pool_for_ps_preparing
();
if
(
open_and_lock_tables
(
thd
,
tables
))
if
(
open_and_lock_tables
(
thd
,
tables
))
{
{
send_error
(
thd
);
send_error
(
thd
);
...
@@ -1092,15 +1069,14 @@ static int mysql_test_select(Prepared_statement *stmt,
...
@@ -1092,15 +1069,14 @@ static int mysql_test_select(Prepared_statement *stmt,
send_error
(
thd
);
send_error
(
thd
);
goto
err_prep
;
goto
err_prep
;
}
}
if
(
!
text_protocol
)
{
if
(
lex
->
describe
)
if
(
lex
->
describe
)
{
{
if
(
!
text_protocol
&&
send_prep_stmt
(
stmt
,
0
))
if
(
send_prep_stmt
(
stmt
,
0
))
goto
err_prep
;
goto
err_prep
;
unit
->
cleanup
();
}
}
else
else
{
if
(
!
text_protocol
)
{
{
if
(
send_prep_stmt
(
stmt
,
lex
->
select_lex
.
item_list
.
elements
)
||
if
(
send_prep_stmt
(
stmt
,
lex
->
select_lex
.
item_list
.
elements
)
||
thd
->
protocol_simple
.
send_fields
(
&
lex
->
select_lex
.
item_list
,
0
)
thd
->
protocol_simple
.
send_fields
(
&
lex
->
select_lex
.
item_list
,
0
)
...
@@ -1110,15 +1086,13 @@ static int mysql_test_select(Prepared_statement *stmt,
...
@@ -1110,15 +1086,13 @@ static int mysql_test_select(Prepared_statement *stmt,
)
)
goto
err_prep
;
goto
err_prep
;
}
}
unit
->
cleanup
();
}
}
thd
->
free_temporary_memory_pool_for_ps_preparing
();
unit
->
cleanup
();
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
err_prep:
err_prep:
unit
->
cleanup
();
unit
->
cleanup
();
err:
err:
thd
->
free_temporary_memory_pool_for_ps_preparing
();
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
}
}
...
@@ -1147,19 +1121,13 @@ static int mysql_test_do_fields(Prepared_statement *stmt,
...
@@ -1147,19 +1121,13 @@ static int mysql_test_do_fields(Prepared_statement *stmt,
int
res
=
0
;
int
res
=
0
;
if
(
tables
&&
(
res
=
check_table_access
(
thd
,
SELECT_ACL
,
tables
,
0
)))
if
(
tables
&&
(
res
=
check_table_access
(
thd
,
SELECT_ACL
,
tables
,
0
)))
DBUG_RETURN
(
res
);
DBUG_RETURN
(
res
);
/*
open temporary memory pool for temporary data allocated by derived
tables & preparation procedure
*/
thd
->
allocate_temporary_memory_pool_for_ps_preparing
();
if
(
tables
&&
(
res
=
open_and_lock_tables
(
thd
,
tables
)))
if
(
tables
&&
(
res
=
open_and_lock_tables
(
thd
,
tables
)))
{
{
thd
->
free_temporary_memory_pool_for_ps_preparing
();
DBUG_RETURN
(
res
);
DBUG_RETURN
(
res
);
}
}
res
=
setup_fields
(
thd
,
0
,
0
,
*
values
,
0
,
0
,
0
);
res
=
setup_fields
(
thd
,
0
,
0
,
*
values
,
0
,
0
,
0
);
stmt
->
lex
->
unit
.
cleanup
();
stmt
->
lex
->
unit
.
cleanup
();
thd
->
free_temporary_memory_pool_for_ps_preparing
();
if
(
res
)
if
(
res
)
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
...
@@ -1192,11 +1160,7 @@ static int mysql_test_set_fields(Prepared_statement *stmt,
...
@@ -1192,11 +1160,7 @@ static int mysql_test_set_fields(Prepared_statement *stmt,
if
(
tables
&&
(
res
=
check_table_access
(
thd
,
SELECT_ACL
,
tables
,
0
)))
if
(
tables
&&
(
res
=
check_table_access
(
thd
,
SELECT_ACL
,
tables
,
0
)))
DBUG_RETURN
(
res
);
DBUG_RETURN
(
res
);
/*
open temporary memory pool for temporary data allocated by derived
tables & preparation procedure
*/
thd
->
allocate_temporary_memory_pool_for_ps_preparing
();
if
(
tables
&&
(
res
=
open_and_lock_tables
(
thd
,
tables
)))
if
(
tables
&&
(
res
=
open_and_lock_tables
(
thd
,
tables
)))
goto
error
;
goto
error
;
while
((
var
=
it
++
))
while
((
var
=
it
++
))
...
@@ -1210,7 +1174,6 @@ static int mysql_test_set_fields(Prepared_statement *stmt,
...
@@ -1210,7 +1174,6 @@ static int mysql_test_set_fields(Prepared_statement *stmt,
}
}
error:
error:
stmt
->
lex
->
unit
.
cleanup
();
stmt
->
lex
->
unit
.
cleanup
();
thd
->
free_temporary_memory_pool_for_ps_preparing
();
DBUG_RETURN
(
res
);
DBUG_RETURN
(
res
);
}
}
...
@@ -1235,11 +1198,7 @@ static int select_like_statement_test(Prepared_statement *stmt,
...
@@ -1235,11 +1198,7 @@ static int select_like_statement_test(Prepared_statement *stmt,
THD
*
thd
=
stmt
->
thd
;
THD
*
thd
=
stmt
->
thd
;
LEX
*
lex
=
stmt
->
lex
;
LEX
*
lex
=
stmt
->
lex
;
int
res
=
0
;
int
res
=
0
;
/*
open temporary memory pool for temporary data allocated by derived
tables & preparation procedure
*/
thd
->
allocate_temporary_memory_pool_for_ps_preparing
();
if
(
tables
&&
(
res
=
open_and_lock_tables
(
thd
,
tables
)))
if
(
tables
&&
(
res
=
open_and_lock_tables
(
thd
,
tables
)))
goto
end
;
goto
end
;
...
@@ -1252,7 +1211,6 @@ static int select_like_statement_test(Prepared_statement *stmt,
...
@@ -1252,7 +1211,6 @@ static int select_like_statement_test(Prepared_statement *stmt,
}
}
end:
end:
lex
->
unit
.
cleanup
();
lex
->
unit
.
cleanup
();
thd
->
free_temporary_memory_pool_for_ps_preparing
();
DBUG_RETURN
(
res
);
DBUG_RETURN
(
res
);
}
}
...
@@ -1596,17 +1554,13 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
...
@@ -1596,17 +1554,13 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
}
}
thd
->
stmt_backup
.
set_statement
(
thd
);
thd
->
set_n_backup_statement
(
stmt
,
&
thd
->
stmt_backup
);
thd
->
stmt_backup
.
set_item_arena
(
thd
);
thd
->
set_n_backup_item_arena
(
stmt
,
&
thd
->
stmt_backup
);
thd
->
set_statement
(
stmt
);
thd
->
set_item_arena
(
stmt
);
if
(
alloc_query
(
thd
,
packet
,
packet_length
))
if
(
alloc_query
(
thd
,
packet
,
packet_length
))
{
{
stmt
->
set_statement
(
thd
);
thd
->
restore_backup_statement
(
stmt
,
&
thd
->
stmt_backup
);
stmt
->
set_item_arena
(
thd
);
thd
->
restore_backup_item_arena
(
stmt
,
&
thd
->
stmt_backup
);
thd
->
set_statement
(
&
thd
->
stmt_backup
);
thd
->
set_item_arena
(
&
thd
->
stmt_backup
);
/* Statement map deletes statement on erase */
/* Statement map deletes statement on erase */
thd
->
stmt_map
.
erase
(
stmt
);
thd
->
stmt_map
.
erase
(
stmt
);
send_error
(
thd
,
ER_OUT_OF_RESOURCES
);
send_error
(
thd
,
ER_OUT_OF_RESOURCES
);
...
@@ -1615,24 +1569,36 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
...
@@ -1615,24 +1569,36 @@ int 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
;
mysql_init_query
(
thd
,
(
uchar
*
)
thd
->
query
,
thd
->
query_length
);
mysql_init_query
(
thd
,
(
uchar
*
)
thd
->
query
,
thd
->
query_length
);
lex
=
thd
->
lex
;
lex
=
thd
->
lex
;
lex
->
safe_to_cache_query
=
0
;
lex
->
safe_to_cache_query
=
0
;
error
=
yyparse
((
void
*
)
thd
)
||
thd
->
is_fatal_error
||
error
=
yyparse
((
void
*
)
thd
)
||
thd
->
is_fatal_error
||
init_param_array
(
stmt
)
||
init_param_array
(
stmt
);
send_prepare_results
(
stmt
,
test
(
name
));
/*
While doing context analysis of the query (in send_prepare_results) we
allocate a lot of additional memory: for open tables, JOINs, derived
tables, etc. Let's save a snapshot of current parse tree to the
statement and restore original THD. In cases when some tree
transformation can be reused on execute, we set again thd->mem_root from
stmt->mem_root (see setup_wild for one place where we do that).
*/
thd
->
restore_backup_item_arena
(
stmt
,
&
thd
->
stmt_backup
);
if
(
!
error
)
error
=
send_prepare_results
(
stmt
,
test
(
name
));
/* restore to WAIT_PRIOR: QUERY_PRIOR is set inside alloc_query */
/* restore to WAIT_PRIOR: QUERY_PRIOR is set inside alloc_query */
if
(
!
(
specialflag
&
SPECIAL_NO_PRIOR
))
if
(
!
(
specialflag
&
SPECIAL_NO_PRIOR
))
my_pthread_setprio
(
pthread_self
(),
WAIT_PRIOR
);
my_pthread_setprio
(
pthread_self
(),
WAIT_PRIOR
);
lex_end
(
lex
);
lex_end
(
lex
);
stmt
->
set_statement
(
thd
);
thd
->
restore_backup_statement
(
stmt
,
&
thd
->
stmt_backup
);
stmt
->
set_item_arena
(
thd
);
cleanup_items
(
stmt
->
free_list
);
thd
->
set_statement
(
&
thd
->
stmt_backup
);
close_thread_tables
(
thd
);
thd
->
set_item_arena
(
&
thd
->
stmt_backup
);
free_items
(
thd
->
free_list
);
thd
->
current_statement
=
0
;
thd
->
free_list
=
0
;
thd
->
current_arena
=
thd
;
if
(
error
)
if
(
error
)
{
{
...
@@ -1653,7 +1619,7 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
...
@@ -1653,7 +1619,7 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
{
{
sl
->
prep_where
=
sl
->
where
;
sl
->
prep_where
=
sl
->
where
;
}
}
stmt
->
state
=
Prepared_statement
::
PREPARED
;
}
}
DBUG_RETURN
(
!
stmt
);
DBUG_RETURN
(
!
stmt
);
...
@@ -1767,7 +1733,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
...
@@ -1767,7 +1733,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
DBUG_PRINT
(
"exec_query:"
,
(
"%s"
,
stmt
->
query
));
DBUG_PRINT
(
"exec_query:"
,
(
"%s"
,
stmt
->
query
));
/* Check if we got an error when sending long data */
/* Check if we got an error when sending long data */
if
(
stmt
->
get_longdata_error
)
if
(
stmt
->
state
==
Item_arena
::
ERROR
)
{
{
send_error
(
thd
,
stmt
->
last_errno
,
stmt
->
last_error
);
send_error
(
thd
,
stmt
->
last_errno
,
stmt
->
last_error
);
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
...
@@ -1791,6 +1757,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
...
@@ -1791,6 +1757,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
if
(
stmt
->
param_count
&&
stmt
->
set_params_data
(
stmt
,
&
expanded_query
))
if
(
stmt
->
param_count
&&
stmt
->
set_params_data
(
stmt
,
&
expanded_query
))
goto
set_params_data_err
;
goto
set_params_data_err
;
#endif
#endif
DBUG_ASSERT
(
thd
->
free_list
==
NULL
);
thd
->
protocol
=
&
thd
->
protocol_prep
;
// Switch to binary protocol
thd
->
protocol
=
&
thd
->
protocol_prep
;
// Switch to binary protocol
execute_stmt
(
thd
,
stmt
,
&
expanded_query
,
true
);
execute_stmt
(
thd
,
stmt
,
&
expanded_query
,
true
);
thd
->
protocol
=
&
thd
->
protocol_simple
;
// Use normal protocol
thd
->
protocol
=
&
thd
->
protocol_simple
;
// Use normal protocol
...
@@ -1834,9 +1801,9 @@ void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name)
...
@@ -1834,9 +1801,9 @@ void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name)
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
thd
->
free_list
=
NULL
;
DBUG_ASSERT
(
thd
->
free_list
==
NULL
)
;
thd
->
stmt_backup
.
set_statement
(
thd
);
thd
->
set_
statement
(
stmt
);
thd
->
set_
n_backup_statement
(
stmt
,
&
thd
->
stmt_backup
);
if
(
stmt
->
set_params_from_vars
(
stmt
,
if
(
stmt
->
set_params_from_vars
(
stmt
,
thd
->
stmt_backup
.
lex
->
prepared_stmt_params
,
thd
->
stmt_backup
.
lex
->
prepared_stmt_params
,
&
expanded_query
))
&
expanded_query
))
...
@@ -1868,11 +1835,7 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt,
...
@@ -1868,11 +1835,7 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt,
{
{
DBUG_ENTER
(
"execute_stmt"
);
DBUG_ENTER
(
"execute_stmt"
);
if
(
set_context
)
if
(
set_context
)
{
thd
->
set_n_backup_statement
(
stmt
,
&
thd
->
stmt_backup
);
thd
->
free_list
=
NULL
;
thd
->
stmt_backup
.
set_statement
(
thd
);
thd
->
set_statement
(
stmt
);
}
reset_stmt_for_execute
(
stmt
);
reset_stmt_for_execute
(
stmt
);
if
(
expanded_query
->
length
()
&&
if
(
expanded_query
->
length
()
&&
...
@@ -1882,6 +1845,13 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt,
...
@@ -1882,6 +1845,13 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt,
my_error
(
ER_OUTOFMEMORY
,
0
,
expanded_query
->
length
());
my_error
(
ER_OUTOFMEMORY
,
0
,
expanded_query
->
length
());
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
/*
At first execution of prepared statement we will perform logical
transformations of the query tree (i.e. negations elimination).
This should be done permanently on the parse tree of this statement.
*/
if
(
stmt
->
state
==
Item_arena
::
PREPARED
)
thd
->
current_arena
=
stmt
;
if
(
!
(
specialflag
&
SPECIAL_NO_PRIOR
))
if
(
!
(
specialflag
&
SPECIAL_NO_PRIOR
))
my_pthread_setprio
(
pthread_self
(),
QUERY_PRIOR
);
my_pthread_setprio
(
pthread_self
(),
QUERY_PRIOR
);
...
@@ -1892,6 +1862,12 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt,
...
@@ -1892,6 +1862,12 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt,
/* Free Items that were created during this execution of the PS. */
/* Free Items that were created during this execution of the PS. */
free_items
(
thd
->
free_list
);
free_items
(
thd
->
free_list
);
thd
->
free_list
=
0
;
if
(
stmt
->
state
==
Item_arena
::
PREPARED
)
{
thd
->
current_arena
=
thd
;
stmt
->
state
=
Item_arena
::
EXECUTED
;
}
cleanup_items
(
stmt
->
free_list
);
cleanup_items
(
stmt
->
free_list
);
reset_stmt_params
(
stmt
);
reset_stmt_params
(
stmt
);
close_thread_tables
(
thd
);
// to close derived tables
close_thread_tables
(
thd
);
// to close derived tables
...
@@ -1929,7 +1905,7 @@ void mysql_stmt_reset(THD *thd, char *packet)
...
@@ -1929,7 +1905,7 @@ void mysql_stmt_reset(THD *thd, char *packet)
SEND_ERROR
)))
SEND_ERROR
)))
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
stmt
->
get_longdata_error
=
0
;
stmt
->
state
=
Item_arena
::
PREPARED
;
/*
/*
Clear parameters from data which could be set by
Clear parameters from data which could be set by
...
@@ -2017,7 +1993,7 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length)
...
@@ -2017,7 +1993,7 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length)
if
(
param_number
>=
stmt
->
param_count
)
if
(
param_number
>=
stmt
->
param_count
)
{
{
/* Error will be sent in execute call */
/* Error will be sent in execute call */
stmt
->
get_longdata_error
=
1
;
stmt
->
state
=
Item_arena
::
ERROR
;
stmt
->
last_errno
=
ER_WRONG_ARGUMENTS
;
stmt
->
last_errno
=
ER_WRONG_ARGUMENTS
;
sprintf
(
stmt
->
last_error
,
ER
(
ER_WRONG_ARGUMENTS
),
sprintf
(
stmt
->
last_error
,
ER
(
ER_WRONG_ARGUMENTS
),
"mysql_stmt_send_long_data"
);
"mysql_stmt_send_long_data"
);
...
@@ -2028,10 +2004,15 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length)
...
@@ -2028,10 +2004,15 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length)
param
=
stmt
->
param_array
[
param_number
];
param
=
stmt
->
param_array
[
param_number
];
#ifndef EMBEDDED_LIBRARY
#ifndef EMBEDDED_LIBRARY
param
->
set_longdata
(
packet
,
(
ulong
)
(
packet_end
-
packet
));
if
(
param
->
set_longdata
(
packet
,
(
ulong
)
(
packet_end
-
packet
)))
#else
#else
param
->
set_longdata
(
thd
->
extra_data
,
thd
->
extra_length
);
if
(
param
->
set_longdata
(
thd
->
extra_data
,
thd
->
extra_length
))
#endif
#endif
{
stmt
->
state
=
Item_arena
::
ERROR
;
stmt
->
last_errno
=
ER_OUTOFMEMORY
;
sprintf
(
stmt
->
last_error
,
ER
(
ER_OUTOFMEMORY
),
0
);
}
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
...
@@ -2041,8 +2022,7 @@ Prepared_statement::Prepared_statement(THD *thd_arg)
...
@@ -2041,8 +2022,7 @@ Prepared_statement::Prepared_statement(THD *thd_arg)
thd
(
thd_arg
),
thd
(
thd_arg
),
param_array
(
0
),
param_array
(
0
),
param_count
(
0
),
param_count
(
0
),
last_errno
(
0
),
last_errno
(
0
)
get_longdata_error
(
0
)
{
{
*
last_error
=
'\0'
;
*
last_error
=
'\0'
;
}
}
...
@@ -2076,7 +2056,7 @@ Prepared_statement::~Prepared_statement()
...
@@ -2076,7 +2056,7 @@ Prepared_statement::~Prepared_statement()
}
}
Statement
::
Type
Prepared_statement
::
type
()
const
Item_arena
::
Type
Prepared_statement
::
type
()
const
{
{
return
PREPARED_STATEMENT
;
return
PREPARED_STATEMENT
;
}
}
...
...
sql/sql_select.cc
View file @
75454b0a
...
@@ -4379,25 +4379,39 @@ COND *eliminate_not_funcs(THD *thd, COND *cond)
...
@@ -4379,25 +4379,39 @@ COND *eliminate_not_funcs(THD *thd, COND *cond)
static
COND
*
static
COND
*
optimize_cond
(
THD
*
thd
,
COND
*
conds
,
Item
::
cond_result
*
cond_value
)
optimize_cond
(
THD
*
thd
,
COND
*
conds
,
Item
::
cond_result
*
cond_value
)
{
{
SELECT_LEX
*
select
=
thd
->
lex
->
current_select
;
DBUG_ENTER
(
"optimize_cond"
);
DBUG_ENTER
(
"optimize_cond"
);
if
(
!
conds
)
if
(
conds
)
{
{
*
cond_value
=
Item
::
COND_TRUE
;
DBUG_EXECUTE
(
"where"
,
print_where
(
conds
,
"original"
););
DBUG_RETURN
(
conds
);
/* Eliminate NOT operators; in case of PS/SP do it once */
if
(
thd
->
current_arena
->
is_first_stmt_execute
())
{
Item_arena
*
arena
=
thd
->
current_arena
,
backup
;
thd
->
set_n_backup_item_arena
(
arena
,
&
backup
);
conds
=
eliminate_not_funcs
(
thd
,
conds
);
select
->
prep_where
=
conds
->
copy_andor_structure
(
thd
);
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
}
}
DBUG_EXECUTE
(
"where"
,
print_where
(
conds
,
"original"
););
else
/* eliminate NOT operators */
conds
=
eliminate_not_funcs
(
thd
,
conds
);
conds
=
eliminate_not_funcs
(
thd
,
conds
);
DBUG_EXECUTE
(
"where"
,
print_where
(
conds
,
"after negation elimination"
););
DBUG_EXECUTE
(
"where"
,
print_where
(
conds
,
"after negation elimination"
););
/* change field = field to field = const for each found field = const */
/* change field = field to field = const for each found field = const */
propagate_cond_constants
((
I_List
<
COND_CMP
>
*
)
0
,
conds
,
conds
);
propagate_cond_constants
((
I_List
<
COND_CMP
>
*
)
0
,
conds
,
conds
);
/*
/*
Remove all instances of item == item
Remove all instances of item == item
Remove all and-levels where CONST item != CONST item
Remove all and-levels where CONST item != CONST item
*/
*/
DBUG_EXECUTE
(
"where"
,
print_where
(
conds
,
"after const change"
););
DBUG_EXECUTE
(
"where"
,
print_where
(
conds
,
"after const change"
););
conds
=
remove_eq_conds
(
thd
,
conds
,
cond_value
)
;
conds
=
remove_eq_conds
(
thd
,
conds
,
cond_value
);
DBUG_EXECUTE
(
"info"
,
print_where
(
conds
,
"after remove"
););
DBUG_EXECUTE
(
"info"
,
print_where
(
conds
,
"after remove"
););
}
else
{
*
cond_value
=
Item
::
COND_TRUE
;
select
->
prep_where
=
0
;
}
DBUG_RETURN
(
conds
);
DBUG_RETURN
(
conds
);
}
}
...
...
sql/sql_union.cc
View file @
75454b0a
...
@@ -287,24 +287,23 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
...
@@ -287,24 +287,23 @@ 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
,
backup
;
Statement
backup
;
if
(
arena
->
is_stmt_prepare
())
if
(
stmt
)
thd
->
set_n_backup_item_arena
(
arena
,
&
backup
);
thd
->
set_n_backup_item_arena
(
stmt
,
&
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
->
is_stmt_prepare
()
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
}
}
}
}
if
(
stmt
)
if
(
arena
->
is_stmt_prepare
()
)
{
{
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
);
...
...
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