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
8f43d0c4
Commit
8f43d0c4
authored
Aug 21, 2004
by
paul@ice.snake.net
Browse files
Options
Browse Files
Download
Plain Diff
Merge paul@bk-internal.mysql.com:/home/bk/mysql-4.1
into ice.snake.net:/Volumes/ice2/MySQL/bk/mysql-4.1
parents
db40cfb4
df1d90d1
Changes
20
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
396 additions
and
262 deletions
+396
-262
mysql-test/r/olap.result
mysql-test/r/olap.result
+36
-0
mysql-test/r/ps.result
mysql-test/r/ps.result
+7
-0
mysql-test/t/flush_block_commit-master.opt
mysql-test/t/flush_block_commit-master.opt
+1
-1
mysql-test/t/olap.test
mysql-test/t/olap.test
+37
-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
+13
-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
+32
-16
sql/sql_union.cc
sql/sql_union.cc
+7
-8
No files found.
mysql-test/r/olap.result
View file @
8f43d0c4
...
...
@@ -271,3 +271,39 @@ i i COUNT(*)
100 NULL 2
NULL NULL 2
drop table t1,t2;
CREATE TABLE user_day(
user_id INT NOT NULL,
date DATE NOT NULL,
UNIQUE INDEX user_date (user_id, date)
);
INSERT INTO user_day VALUES
(1, '2004-06-06' ),
(1, '2004-06-07' ),
(2, '2004-06-06' );
SELECT
d.date AS day,
COUNT(d.user_id) as sample,
COUNT(next_day.user_id) AS not_cancelled
FROM user_day d
LEFT JOIN user_day next_day
ON next_day.user_id=d.user_id AND
next_day.date= DATE_ADD( d.date, interval 1 day )
GROUP BY day;
day sample not_cancelled
2004-06-06 2 1
2004-06-07 1 0
SELECT
d.date AS day,
COUNT(d.user_id) as sample,
COUNT(next_day.user_id) AS not_cancelled
FROM user_day d
LEFT JOIN user_day next_day
ON next_day.user_id=d.user_id AND
next_day.date= DATE_ADD( d.date, interval 1 day )
GROUP BY day
WITH ROLLUP;
day sample not_cancelled
2004-06-06 2 1
2004-06-07 1 0
NULL 3 1
DROP TABLE user_day;
mysql-test/r/ps.result
View file @
8f43d0c4
...
...
@@ -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/flush_block_commit-master.opt
View file @
8f43d0c4
--innodb_lock_wait_timeout=5
--
loose-
innodb_lock_wait_timeout=5
mysql-test/t/olap.test
View file @
8f43d0c4
...
...
@@ -88,3 +88,40 @@ INSERT INTO t2 VALUES (100),(200);
SELECT
i
,
COUNT
(
*
)
FROM
t1
GROUP
BY
i
WITH
ROLLUP
;
SELECT
t1
.
i
,
t2
.
i
,
COUNT
(
*
)
FROM
t1
,
t2
GROUP
BY
t1
.
i
,
t2
.
i
WITH
ROLLUP
;
drop
table
t1
,
t2
;
#bug #4767: ROLLUP with LEFT JOIN
CREATE
TABLE
user_day
(
user_id
INT
NOT
NULL
,
date
DATE
NOT
NULL
,
UNIQUE
INDEX
user_date
(
user_id
,
date
)
);
INSERT
INTO
user_day
VALUES
(
1
,
'2004-06-06'
),
(
1
,
'2004-06-07'
),
(
2
,
'2004-06-06'
);
SELECT
d
.
date
AS
day
,
COUNT
(
d
.
user_id
)
as
sample
,
COUNT
(
next_day
.
user_id
)
AS
not_cancelled
FROM
user_day
d
LEFT
JOIN
user_day
next_day
ON
next_day
.
user_id
=
d
.
user_id
AND
next_day
.
date
=
DATE_ADD
(
d
.
date
,
interval
1
day
)
GROUP
BY
day
;
SELECT
d
.
date
AS
day
,
COUNT
(
d
.
user_id
)
as
sample
,
COUNT
(
next_day
.
user_id
)
AS
not_cancelled
FROM
user_day
d
LEFT
JOIN
user_day
next_day
ON
next_day
.
user_id
=
d
.
user_id
AND
next_day
.
date
=
DATE_ADD
(
d
.
date
,
interval
1
day
)
GROUP
BY
day
WITH
ROLLUP
;
DROP
TABLE
user_day
;
mysql-test/t/ps.test
View file @
8f43d0c4
...
...
@@ -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 @
8f43d0c4
...
...
@@ -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 @
8f43d0c4
...
...
@@ -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 @
8f43d0c4
...
...
@@ -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 @
8f43d0c4
...
...
@@ -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
;
...
...
@@ -159,7 +159,10 @@ Item *Item_sum::get_tmp_table_item(THD *thd)
if
(
!
arg
->
const_item
())
{
if
(
arg
->
type
()
==
Item
::
FIELD_ITEM
)
{
arg
->
maybe_null
=
result_field_tmp
->
maybe_null
();
((
Item_field
*
)
arg
)
->
field
=
result_field_tmp
++
;
}
else
sum_item
->
args
[
i
]
=
new
Item_field
(
result_field_tmp
++
);
}
...
...
@@ -214,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
)
...
...
@@ -248,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
];
...
...
@@ -1947,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 @
8f43d0c4
...
...
@@ -92,8 +92,8 @@ public:
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 @
8f43d0c4
...
...
@@ -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 @
8f43d0c4
...
...
@@ -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 @
8f43d0c4
...
...
@@ -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 @
8f43d0c4
...
...
@@ -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 @@ public:
*/
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 @@ public:
/* 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 @@ public:
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 @@ public:
}
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 @
8f43d0c4
...
...
@@ -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 @
8f43d0c4
...
...
@@ -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 @
8f43d0c4
...
...
@@ -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 @
8f43d0c4
...
...
@@ -88,7 +88,6 @@ public:
uint
param_count
;
uint
last_errno
;
char
last_error
[
MYSQL_ERRMSG_SIZE
];
bool
get_longdata_error
;
#ifndef EMBEDDED_LIBRARY
bool
(
*
set_params
)(
Prepared_statement
*
st
,
uchar
*
data
,
uchar
*
data_end
,
uchar
*
read_pos
,
String
*
expanded_query
);
...
...
@@ -102,7 +101,7 @@ public:
Prepared_statement
(
THD
*
thd_arg
);
virtual
~
Prepared_statement
();
void
setup_set_params
();
virtual
Statement
::
Type
type
()
const
;
virtual
Item_arena
::
Type
type
()
const
;
};
static
void
execute_stmt
(
THD
*
thd
,
Prepared_statement
*
stmt
,
...
...
@@ -133,7 +132,7 @@ find_prepared_statement(THD *thd, ulong id, const char *where,
{
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
];
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,
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
))
{
thd
->
free_temporary_memory_pool_for_ps_preparing
();
DBUG_RETURN
(
-
1
);
}
...
...
@@ -934,7 +931,6 @@ static int mysql_test_insert(Prepared_statement *stmt,
res
=
0
;
error:
lex
->
unit
.
cleanup
();
thd
->
free_temporary_memory_pool_for_ps_preparing
();
DBUG_RETURN
(
res
);
}
...
...
@@ -963,12 +959,6 @@ static int mysql_test_update(Prepared_statement *stmt,
if
((
res
=
update_precheck
(
thd
,
table_list
)))
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
))
res
=
-
1
;
else
...
...
@@ -988,7 +978,6 @@ static int mysql_test_update(Prepared_statement *stmt,
}
stmt
->
lex
->
unit
.
cleanup
();
}
thd
->
free_temporary_memory_pool_for_ps_preparing
();
/* TODO: here we should send types of placeholders to the client. */
DBUG_RETURN
(
res
);
}
...
...
@@ -1018,12 +1007,6 @@ static int mysql_test_delete(Prepared_statement *stmt,
if
((
res
=
delete_precheck
(
thd
,
table_list
)))
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
))
res
=
-
1
;
else
...
...
@@ -1031,7 +1014,6 @@ static int mysql_test_delete(Prepared_statement *stmt,
res
=
mysql_prepare_delete
(
thd
,
table_list
,
&
lex
->
select_lex
.
where
);
lex
->
unit
.
cleanup
();
}
thd
->
free_temporary_memory_pool_for_ps_preparing
();
/* TODO: here we should send types of placeholders to the client. */
DBUG_RETURN
(
res
);
}
...
...
@@ -1073,11 +1055,6 @@ static int mysql_test_select(Prepared_statement *stmt,
DBUG_RETURN
(
1
);
#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
))
{
send_error
(
thd
);
...
...
@@ -1092,15 +1069,14 @@ static int mysql_test_select(Prepared_statement *stmt,
send_error
(
thd
);
goto
err_prep
;
}
if
(
!
text_protocol
)
{
if
(
lex
->
describe
)
{
if
(
!
text_protocol
&&
send_prep_stmt
(
stmt
,
0
))
if
(
send_prep_stmt
(
stmt
,
0
))
goto
err_prep
;
unit
->
cleanup
();
}
else
{
if
(
!
text_protocol
)
{
if
(
send_prep_stmt
(
stmt
,
lex
->
select_lex
.
item_list
.
elements
)
||
thd
->
protocol_simple
.
send_fields
(
&
lex
->
select_lex
.
item_list
,
0
)
...
...
@@ -1110,15 +1086,13 @@ static int mysql_test_select(Prepared_statement *stmt,
)
goto
err_prep
;
}
unit
->
cleanup
();
}
thd
->
free_temporary_memory_pool_for_ps_preparing
();
unit
->
cleanup
();
DBUG_RETURN
(
0
);
err_prep:
unit
->
cleanup
();
err:
thd
->
free_temporary_memory_pool_for_ps_preparing
();
DBUG_RETURN
(
1
);
}
...
...
@@ -1147,19 +1121,13 @@ static int mysql_test_do_fields(Prepared_statement *stmt,
int
res
=
0
;
if
(
tables
&&
(
res
=
check_table_access
(
thd
,
SELECT_ACL
,
tables
,
0
)))
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
)))
{
thd
->
free_temporary_memory_pool_for_ps_preparing
();
DBUG_RETURN
(
res
);
}
res
=
setup_fields
(
thd
,
0
,
0
,
*
values
,
0
,
0
,
0
);
stmt
->
lex
->
unit
.
cleanup
();
thd
->
free_temporary_memory_pool_for_ps_preparing
();
if
(
res
)
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
0
);
...
...
@@ -1192,11 +1160,7 @@ static int mysql_test_set_fields(Prepared_statement *stmt,
if
(
tables
&&
(
res
=
check_table_access
(
thd
,
SELECT_ACL
,
tables
,
0
)))
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
)))
goto
error
;
while
((
var
=
it
++
))
...
...
@@ -1210,7 +1174,6 @@ static int mysql_test_set_fields(Prepared_statement *stmt,
}
error:
stmt
->
lex
->
unit
.
cleanup
();
thd
->
free_temporary_memory_pool_for_ps_preparing
();
DBUG_RETURN
(
res
);
}
...
...
@@ -1235,11 +1198,7 @@ static int select_like_statement_test(Prepared_statement *stmt,
THD
*
thd
=
stmt
->
thd
;
LEX
*
lex
=
stmt
->
lex
;
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
)))
goto
end
;
...
...
@@ -1252,7 +1211,6 @@ static int select_like_statement_test(Prepared_statement *stmt,
}
end:
lex
->
unit
.
cleanup
();
thd
->
free_temporary_memory_pool_for_ps_preparing
();
DBUG_RETURN
(
res
);
}
...
...
@@ -1596,17 +1554,13 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
DBUG_RETURN
(
1
);
}
thd
->
stmt_backup
.
set_statement
(
thd
);
thd
->
stmt_backup
.
set_item_arena
(
thd
);
thd
->
set_statement
(
stmt
);
thd
->
set_item_arena
(
stmt
);
thd
->
set_n_backup_statement
(
stmt
,
&
thd
->
stmt_backup
);
thd
->
set_n_backup_item_arena
(
stmt
,
&
thd
->
stmt_backup
);
if
(
alloc_query
(
thd
,
packet
,
packet_length
))
{
stmt
->
set_statement
(
thd
);
stmt
->
set_item_arena
(
thd
);
thd
->
set_statement
(
&
thd
->
stmt_backup
);
thd
->
set_item_arena
(
&
thd
->
stmt_backup
);
thd
->
restore_backup_statement
(
stmt
,
&
thd
->
stmt_backup
);
thd
->
restore_backup_item_arena
(
stmt
,
&
thd
->
stmt_backup
);
/* Statement map deletes statement on erase */
thd
->
stmt_map
.
erase
(
stmt
);
send_error
(
thd
,
ER_OUT_OF_RESOURCES
);
...
...
@@ -1615,24 +1569,36 @@ int 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
;
mysql_init_query
(
thd
,
(
uchar
*
)
thd
->
query
,
thd
->
query_length
);
lex
=
thd
->
lex
;
lex
->
safe_to_cache_query
=
0
;
error
=
yyparse
((
void
*
)
thd
)
||
thd
->
is_fatal_error
||
init_param_array
(
stmt
)
||
send_prepare_results
(
stmt
,
test
(
name
));
init_param_array
(
stmt
);
/*
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 */
if
(
!
(
specialflag
&
SPECIAL_NO_PRIOR
))
my_pthread_setprio
(
pthread_self
(),
WAIT_PRIOR
);
lex_end
(
lex
);
stmt
->
set_statement
(
thd
);
stmt
->
set_item_arena
(
thd
);
thd
->
set_statement
(
&
thd
->
stmt_backup
);
thd
->
set_item_arena
(
&
thd
->
stmt_backup
);
thd
->
current_statement
=
0
;
thd
->
restore_backup_statement
(
stmt
,
&
thd
->
stmt_backup
);
cleanup_items
(
stmt
->
free_list
);
close_thread_tables
(
thd
);
free_items
(
thd
->
free_list
);
thd
->
free_list
=
0
;
thd
->
current_arena
=
thd
;
if
(
error
)
{
...
...
@@ -1653,7 +1619,7 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
{
sl
->
prep_where
=
sl
->
where
;
}
stmt
->
state
=
Prepared_statement
::
PREPARED
;
}
DBUG_RETURN
(
!
stmt
);
...
...
@@ -1767,7 +1733,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
DBUG_PRINT
(
"exec_query:"
,
(
"%s"
,
stmt
->
query
));
/* 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
);
DBUG_VOID_RETURN
;
...
...
@@ -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
))
goto
set_params_data_err
;
#endif
DBUG_ASSERT
(
thd
->
free_list
==
NULL
);
thd
->
protocol
=
&
thd
->
protocol_prep
;
// Switch to binary protocol
execute_stmt
(
thd
,
stmt
,
&
expanded_query
,
true
);
thd
->
protocol
=
&
thd
->
protocol_simple
;
// Use normal protocol
...
...
@@ -1834,9 +1801,9 @@ void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name)
DBUG_VOID_RETURN
;
}
thd
->
free_list
=
NULL
;
thd
->
stmt_backup
.
set_statement
(
thd
);
thd
->
set_
statement
(
stmt
);
DBUG_ASSERT
(
thd
->
free_list
==
NULL
)
;
thd
->
set_
n_backup_statement
(
stmt
,
&
thd
->
stmt_backup
);
if
(
stmt
->
set_params_from_vars
(
stmt
,
thd
->
stmt_backup
.
lex
->
prepared_stmt_params
,
&
expanded_query
))
...
...
@@ -1868,11 +1835,7 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt,
{
DBUG_ENTER
(
"execute_stmt"
);
if
(
set_context
)
{
thd
->
free_list
=
NULL
;
thd
->
stmt_backup
.
set_statement
(
thd
);
thd
->
set_statement
(
stmt
);
}
thd
->
set_n_backup_statement
(
stmt
,
&
thd
->
stmt_backup
);
reset_stmt_for_execute
(
stmt
);
if
(
expanded_query
->
length
()
&&
...
...
@@ -1882,6 +1845,13 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt,
my_error
(
ER_OUTOFMEMORY
,
0
,
expanded_query
->
length
());
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
))
my_pthread_setprio
(
pthread_self
(),
QUERY_PRIOR
);
...
...
@@ -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
(
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
);
reset_stmt_params
(
stmt
);
close_thread_tables
(
thd
);
// to close derived tables
...
...
@@ -1929,7 +1905,7 @@ void mysql_stmt_reset(THD *thd, char *packet)
SEND_ERROR
)))
DBUG_VOID_RETURN
;
stmt
->
get_longdata_error
=
0
;
stmt
->
state
=
Item_arena
::
PREPARED
;
/*
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)
if
(
param_number
>=
stmt
->
param_count
)
{
/* Error will be sent in execute call */
stmt
->
get_longdata_error
=
1
;
stmt
->
state
=
Item_arena
::
ERROR
;
stmt
->
last_errno
=
ER_WRONG_ARGUMENTS
;
sprintf
(
stmt
->
last_error
,
ER
(
ER_WRONG_ARGUMENTS
),
"mysql_stmt_send_long_data"
);
...
...
@@ -2028,10 +2004,15 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length)
param
=
stmt
->
param_array
[
param_number
];
#ifndef EMBEDDED_LIBRARY
param
->
set_longdata
(
packet
,
(
ulong
)
(
packet_end
-
packet
));
if
(
param
->
set_longdata
(
packet
,
(
ulong
)
(
packet_end
-
packet
)))
#else
param
->
set_longdata
(
thd
->
extra_data
,
thd
->
extra_length
);
if
(
param
->
set_longdata
(
thd
->
extra_data
,
thd
->
extra_length
))
#endif
{
stmt
->
state
=
Item_arena
::
ERROR
;
stmt
->
last_errno
=
ER_OUTOFMEMORY
;
sprintf
(
stmt
->
last_error
,
ER
(
ER_OUTOFMEMORY
),
0
);
}
DBUG_VOID_RETURN
;
}
...
...
@@ -2041,8 +2022,7 @@ Prepared_statement::Prepared_statement(THD *thd_arg)
thd
(
thd_arg
),
param_array
(
0
),
param_count
(
0
),
last_errno
(
0
),
get_longdata_error
(
0
)
last_errno
(
0
)
{
*
last_error
=
'\0'
;
}
...
...
@@ -2076,7 +2056,7 @@ Prepared_statement::~Prepared_statement()
}
Statement
::
Type
Prepared_statement
::
type
()
const
Item_arena
::
Type
Prepared_statement
::
type
()
const
{
return
PREPARED_STATEMENT
;
}
...
...
sql/sql_select.cc
View file @
8f43d0c4
...
...
@@ -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
)
{
*
cond_value
=
Item
::
COND_TRUE
;
DBUG_RETURN
(
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
);
}
DBUG_EXECUTE
(
"where"
,
print_where
(
conds
,
"original"
););
/* eliminate NOT operators */
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
);
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"
););
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
;
select
->
prep_where
=
0
;
}
DBUG_RETURN
(
conds
);
}
...
...
@@ -4997,6 +5011,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
blob_count
++
;
}
((
Item_sum
*
)
item
)
->
args
[
i
]
=
new
Item_field
(
new_field
);
if
(((
Item_sum
*
)
item
)
->
arg_count
==
1
)
((
Item_sum
*
)
item
)
->
result_field
=
new_field
;
}
}
}
...
...
sql/sql_union.cc
View file @
8f43d0c4
...
...
@@ -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