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
02f9e068
Commit
02f9e068
authored
Aug 20, 2004
by
igor@rurik.mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge ibabaev@bk-internal.mysql.com:/home/bk/mysql-4.1
into rurik.mysql.com:/home/igor/mysql-4.1
parents
b817b007
75454b0a
Changes
17
Expand all
Hide 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 @
02f9e068
...
...
@@ -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
deallocate prepare stmt1 ;
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 @
02f9e068
...
...
@@ -206,3 +206,15 @@ execute stmt1;
show
table
status
from
test
like
't1%'
;
deallocate
prepare
stmt1
;
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 @
02f9e068
...
...
@@ -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 =>
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
]);
if
(
cache
->
cols
()
==
1
)
{
...
...
sql/item_subselect.cc
View file @
02f9e068
...
...
@@ -125,7 +125,6 @@ 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
;
char
const
*
save_where
=
thd
->
where
;
int
res
;
...
...
@@ -306,7 +305,10 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
return
RES_OK
;
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
()
&&
!
select_lex
->
table_list
.
elements
&&
...
...
@@ -341,8 +343,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
->
is_stmt_prepare
()
)
thd
->
set_n_backup_item_arena
(
arena
,
&
backup
);
if
(
!
join
->
having
)
cond
=
join
->
conds
;
...
...
@@ -355,15 +357,15 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
new
Item_null
())))
goto
err
;
}
if
(
stmt
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
if
(
arena
->
is_stmt_prepare
()
)
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
->
is_stmt_prepare
()
)
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
return
RES_ERROR
;
}
...
...
@@ -640,11 +642,11 @@ Item_in_subselect::single_value_transformer(JOIN *join,
}
SELECT_LEX
*
select_lex
=
join
->
select_lex
;
Statement
backup
;
Item_arena
*
arena
=
join
->
thd
->
current_arena
,
backup
;
thd
->
where
=
"scalar IN/ALL/ANY subquery"
;
if
(
stmt
)
thd
->
set_n_backup_item_arena
(
stmt
,
&
backup
);
if
(
arena
->
is_stmt_prepare
()
)
thd
->
set_n_backup_item_arena
(
arena
,
&
backup
);
if
(
select_lex
->
item_list
.
elements
>
1
)
{
...
...
@@ -857,21 +859,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
->
is_stmt_prepare
()
)
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
DBUG_RETURN
(
RES_REDUCE
);
}
}
}
ok:
if
(
stmt
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
if
(
arena
->
is_stmt_prepare
()
)
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
DBUG_RETURN
(
RES_OK
);
err:
if
(
stmt
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
if
(
arena
->
is_stmt_prepare
()
)
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
DBUG_RETURN
(
RES_ERROR
);
}
...
...
@@ -885,12 +887,12 @@ Item_in_subselect::row_value_transformer(JOIN *join)
{
DBUG_RETURN
(
RES_OK
);
}
Statement
backup
;
Item_arena
*
arena
=
join
->
thd
->
current_arena
,
backup
;
Item
*
item
=
0
;
thd
->
where
=
"row IN/ALL/ANY subquery"
;
if
(
stmt
)
thd
->
set_n_backup_item_arena
(
stmt
,
&
backup
);
if
(
arena
->
is_stmt_prepare
()
)
thd
->
set_n_backup_item_arena
(
arena
,
&
backup
);
SELECT_LEX
*
select_lex
=
join
->
select_lex
;
...
...
@@ -974,13 +976,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
->
is_stmt_prepare
()
)
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
DBUG_RETURN
(
RES_OK
);
err:
if
(
stmt
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
if
(
arena
->
is_stmt_prepare
()
)
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
DBUG_RETURN
(
RES_ERROR
);
}
...
...
sql/item_subselect.h
View file @
02f9e068
...
...
@@ -36,8 +36,6 @@ 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
;
/* substitution instead of subselect in case of optimization */
Item
*
substitution
;
/* unit of subquery */
...
...
sql/item_sum.cc
View file @
02f9e068
...
...
@@ -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())
SYNOPSIS
Item_sum::save_args_for_prepared_statement
s
()
Item_sum::save_args_for_prepared_statement()
thd - thread handler
RETURN
0 - OK
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
)
return
save_args
(
thd
->
current_
statement
);
if
(
thd
->
current_
arena
->
is_stmt_prepare
()
)
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
;
...
...
@@ -217,7 +217,7 @@ Item_sum_num::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{
DBUG_ASSERT
(
fixed
==
0
);
if
(
save_args_for_prepared_statement
s
(
thd
))
if
(
save_args_for_prepared_statement
(
thd
))
return
1
;
if
(
!
thd
->
allow_sum_func
)
...
...
@@ -251,7 +251,7 @@ Item_sum_hybrid::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{
DBUG_ASSERT
(
fixed
==
0
);
if
(
save_args_for_prepared_statement
s
(
thd
))
if
(
save_args_for_prepared_statement
(
thd
))
return
1
;
Item
*
item
=
args
[
0
];
...
...
@@ -1950,7 +1950,7 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{
DBUG_ASSERT
(
fixed
==
0
);
if
(
save_args_for_prepared_statement
s
(
thd
))
if
(
save_args_for_prepared_statement
(
thd
))
return
1
;
uint
i
;
/* for loop variable */
...
...
sql/item_sum.h
View file @
02f9e068
...
...
@@ -92,8 +92,8 @@ class Item_sum :public Item_result_field
virtual
bool
setup
(
THD
*
thd
)
{
return
0
;}
virtual
void
make_unique
()
{}
Item
*
get_tmp_table_item
(
THD
*
thd
);
bool
save_args_for_prepared_statement
s
(
THD
*
);
bool
save_args
(
Statement
*
stmt
);
bool
save_args_for_prepared_statement
(
THD
*
);
bool
save_args
(
Item_arena
*
arena
);
bool
walk
(
Item_processor
processor
,
byte
*
argument
);
};
...
...
sql/mysql_priv.h
View file @
02f9e068
...
...
@@ -295,7 +295,7 @@ void debug_sync_point(const char* lock_name, uint lock_timeout);
struct
st_table
;
class
THD
;
class
Statement
;
class
Item_arena
;
/* Struct to handle simple linked lists */
...
...
sql/sql_base.cc
View file @
02f9e068
...
...
@@ -2251,14 +2251,15 @@ 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
->
is_stmt_prepare
())
thd
->
set_n_backup_item_arena
(
arena
,
&
backup
);
reg2
Item
*
item
;
List_iterator
<
Item
>
it
(
fields
);
while
(
wild_num
&&
(
item
=
it
++
))
...
...
@@ -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
,
((
Item_field
*
)
item
)
->
table_name
,
&
it
))
{
if
(
stmt
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
if
(
arena
->
is_stmt_prepare
()
)
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
return
(
-
1
);
}
if
(
sum_func_list
)
...
...
@@ -2298,8 +2299,8 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
wild_num
--
;
}
}
if
(
stmt
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
if
(
arena
->
is_stmt_prepare
()
)
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
return
0
;
}
...
...
@@ -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
)
{
table_map
not_null_tables
=
0
;
Statement
*
stmt
=
thd
->
current_statement
,
backup
;
Item_arena
*
arena
=
thd
->
current_arena
,
backup
;
DBUG_ENTER
(
"setup_conds"
);
thd
->
set_query_id
=
1
;
...
...
@@ -2551,12 +2552,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
->
is_stmt_prepare
()
)
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
->
is_stmt_prepare
()
)
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
if
((
*
conds
)
&&
!
(
*
conds
)
->
fixed
&&
(
*
conds
)
->
fix_fields
(
thd
,
tables
,
conds
))
DBUG_RETURN
(
1
);
...
...
@@ -2564,8 +2565,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
->
is_stmt_prepare
()
)
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
;
...
...
@@ -2606,8 +2607,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
->
is_stmt_prepare
()
)
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
if
(
*
conds
&&
!
(
*
conds
)
->
fixed
)
{
if
((
*
conds
)
->
fix_fields
(
thd
,
tables
,
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
);
// fix_fields() should be made with temporary memory pool
if
(
stmt
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
if
(
arena
->
is_stmt_prepare
()
)
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
))
...
...
@@ -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
...
...
@@ -2643,8 +2644,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
DBUG_RETURN
(
test
(
thd
->
net
.
report_error
));
err:
if
(
stmt
)
thd
->
restore_backup_item_arena
(
stmt
,
&
backup
);
if
(
arena
->
is_stmt_prepare
()
)
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
DBUG_RETURN
(
1
);
}
...
...
sql/sql_class.cc
View file @
02f9e068
...
...
@@ -155,7 +155,7 @@ bool foreign_key_prefix(Key *a, Key *b)
** 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
),
insert_id_used
(
0
),
rand_used
(
0
),
time_zone_used
(
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)
}
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
::
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
)
query_length
(
0
)
{
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()
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
));
}
Statement
::
Type
Statement
::
type
()
const
Item_arena
::
Type
Statement
::
type
()
const
{
return
STATEMENT
;
}
...
...
@@ -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
);
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
);
...
...
@@ -1371,10 +1420,11 @@ 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
;
state
=
set
->
state
;
}
Statement
::~
Statement
()
...
...
sql/sql_class.h
View file @
02f9e068
...
...
@@ -418,6 +418,61 @@ 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
;
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.
One connection can contain a lot of simultaneously running statements,
...
...
@@ -432,7 +487,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 */
...
...
@@ -474,20 +529,8 @@ 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. */
enum
Type
{
STATEMENT
,
PREPARED_STATEMENT
};
/*
This constructor is called when statement is a subobject of THD:
...
...
@@ -500,34 +543,10 @@ class Statement
/* Assign execution context (note: not all members) of given stmt to self */
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 */
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 @@ 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
...
...
@@ -983,33 +1002,6 @@ class THD :public ilink,
}
inline
CHARSET_INFO
*
charset
()
{
return
variables
.
character_set_client
;
}
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 */
...
...
sql/sql_derived.cc
View file @
02f9e068
...
...
@@ -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
can skip execution (and parameters is not defined, too)
*/
if
(
!
thd
->
current_statement
)
if
(
!
thd
->
current_arena
->
is_stmt_prepare
()
)
{
if
(
is_union
)
{
...
...
sql/sql_lex.cc
View file @
02f9e068
...
...
@@ -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
prepared statement
*/
Statement
*
stmt
=
thd
->
current_statement
?
thd
->
current_statement
:
thd
;
Item_arena
*
arena
=
thd
->
current_arena
;
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_parse.cc
View file @
02f9e068
...
...
@@ -1543,6 +1543,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
break
;
mysqld_list_fields
(
thd
,
&
table_list
,
fields
);
free_items
(
thd
->
free_list
);
thd
->
free_list
=
0
;
break
;
}
#endif
...
...
@@ -4047,6 +4048,7 @@ void mysql_parse(THD *thd, char *inBuf, uint length)
}
thd
->
proc_info
=
"freeing items"
;
free_items
(
thd
->
free_list
);
/* Free strings used by items */
thd
->
free_list
=
0
;
lex_end
(
lex
);
}
DBUG_VOID_RETURN
;
...
...
@@ -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
))
error
=
1
;
/* Ignore question */
free_items
(
thd
->
free_list
);
/* Free strings used by items */
thd
->
free_list
=
0
;
lex_end
(
lex
);
return
error
;
...
...
sql/sql_prepare.cc
View file @
02f9e068
This diff is collapsed.
Click to expand it.
sql/sql_select.cc
View file @
02f9e068
...
...
@@ -4379,25 +4379,39 @@ COND *eliminate_not_funcs(THD *thd, COND *cond)
static
COND
*
optimize_cond
(
THD
*
thd
,
COND
*
conds
,
Item
::
cond_result
*
cond_value
)
{
SELECT_LEX
*
select
=
thd
->
lex
->
current_select
;
DBUG_ENTER
(
"optimize_cond"
);
if
(
!
conds
)
if
(
conds
)
{
DBUG_EXECUTE
(
"where"
,
print_where
(
conds
,
"original"
););
/* 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
);
}
else
conds
=
eliminate_not_funcs
(
thd
,
conds
);
DBUG_EXECUTE
(
"where"
,
print_where
(
conds
,
"after negation elimination"
););
/* change field = field to field = const for each found field = const */
propagate_cond_constants
((
I_List
<
COND_CMP
>
*
)
0
,
conds
,
conds
);
/*
Remove all instances of item == item
Remove all and-levels where CONST item != CONST item
*/
DBUG_EXECUTE
(
"where"
,
print_where
(
conds
,
"after const change"
););
conds
=
remove_eq_conds
(
thd
,
conds
,
cond_value
);
DBUG_EXECUTE
(
"info"
,
print_where
(
conds
,
"after remove"
););
}
else
{
*
cond_value
=
Item
::
COND_TRUE
;
DBUG_RETURN
(
conds
);
}
DBUG_EXECUTE
(
"where"
,
print_where
(
conds
,
"original"
););
/* eliminate NOT operators */
conds
=
eliminate_not_funcs
(
thd
,
conds
);
DBUG_EXECUTE
(
"where"
,
print_where
(
conds
,
"after negation elimination"
););
/* change field = field to field = const for each found field = const */
propagate_cond_constants
((
I_List
<
COND_CMP
>
*
)
0
,
conds
,
conds
);
/*
Remove all instances of item == item
Remove all and-levels where CONST item != CONST item
*/
DBUG_EXECUTE
(
"where"
,
print_where
(
conds
,
"after const change"
););
conds
=
remove_eq_conds
(
thd
,
conds
,
cond_value
)
;
DBUG_EXECUTE
(
"info"
,
print_where
(
conds
,
"after remove"
););
select
->
prep_where
=
0
;
}
DBUG_RETURN
(
conds
);
}
...
...
sql/sql_union.cc
View file @
02f9e068
...
...
@@ -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
;
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
,
backup
;
if
(
arena
->
is_stmt_prepare
())
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
->
is_stmt_prepare
()
)
thd
->
restore_backup_item_arena
(
arena
,
&
backup
);
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 */
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