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
7c95fa70
Commit
7c95fa70
authored
Oct 14, 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:/media/sda1/mysql/mysql-4.1-5985
parents
5fa60111
5abc3de2
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
159 additions
and
54 deletions
+159
-54
mysql-test/r/ps.result
mysql-test/r/ps.result
+39
-0
mysql-test/t/ps.test
mysql-test/t/ps.test
+27
-1
sql/item_func.cc
sql/item_func.cc
+26
-8
sql/item_func.h
sql/item_func.h
+3
-3
sql/mysql_priv.h
sql/mysql_priv.h
+1
-0
sql/sql_class.cc
sql/sql_class.cc
+1
-1
sql/sql_class.h
sql/sql_class.h
+6
-6
sql/sql_lex.cc
sql/sql_lex.cc
+23
-0
sql/sql_lex.h
sql/sql_lex.h
+2
-2
sql/sql_parse.cc
sql/sql_parse.cc
+26
-31
sql/sql_prepare.cc
sql/sql_prepare.cc
+5
-2
No files found.
mysql-test/r/ps.result
View file @
7c95fa70
...
...
@@ -336,3 +336,42 @@ id select_type table type possible_keys key key_len ref rows Extra
- - - - - - - - NULL Impossible WHERE
drop table t1;
deallocate prepare stmt;
create table t1 (a int);
insert into t1 (a) values (1), (2), (3), (4);
set @precision=10000000000;
select rand(),
cast(rand(10)*@precision as unsigned integer),
cast(rand(a)*@precision as unsigned integer) from t1;
rand() cast(rand(10)*@precision as unsigned integer) cast(rand(a)*@precision as unsigned integer)
- 6570515219 -
- 1282061302 -
- 6698761160 -
- 9647622201 -
prepare stmt from
"select rand(),
cast(rand(10)*@precision as unsigned integer),
cast(rand(a)*@precision as unsigned integer),
cast(rand(?)*@precision as unsigned integer) from t1";
set @var=1;
execute stmt using @var;
rand() cast(rand(10)*@precision as unsigned integer) cast(rand(a)*@precision as unsigned integer) cast(rand(?)*@precision as unsigned integer)
- 6570515219 - 4054035371
- 1282061302 - 8716141803
- 6698761160 - 1418603212
- 9647622201 - 944590960
set @var=2;
execute stmt using @var;
rand() cast(rand(10)*@precision as unsigned integer) cast(rand(a)*@precision as unsigned integer) cast(rand(?)*@precision as unsigned integer)
- 6570515219 1559528654 6555866465
- 1282061302 6238114970 1223466192
- 6698761160 6511989195 6449731873
- 9647622201 3845601374 8578261098
set @var=3;
execute stmt using @var;
rand() cast(rand(10)*@precision as unsigned integer) cast(rand(a)*@precision as unsigned integer) cast(rand(?)*@precision as unsigned integer)
- 6570515219 1559528654 9057697559
- 1282061302 6238114970 3730790581
- 6698761160 6511989195 1480860534
- 9647622201 3845601374 6211931236
drop table t1;
deallocate prepare stmt;
mysql-test/t/ps.test
View file @
7c95fa70
...
...
@@ -363,4 +363,30 @@ execute stmt using @v;
drop
table
t1
;
deallocate
prepare
stmt
;
#
# A test case for Bug#5985 prepare stmt from "select rand(?)" crashes
# server. Check that Item_func_rand is prepared-statements friendly.
#
create
table
t1
(
a
int
);
insert
into
t1
(
a
)
values
(
1
),
(
2
),
(
3
),
(
4
);
set
@
precision
=
10000000000
;
--
replace_column
1
-
3
-
select
rand
(),
cast
(
rand
(
10
)
*@
precision
as
unsigned
integer
),
cast
(
rand
(
a
)
*@
precision
as
unsigned
integer
)
from
t1
;
prepare
stmt
from
"select rand(),
cast(rand(10)*@precision as unsigned integer),
cast(rand(a)*@precision as unsigned integer),
cast(rand(?)*@precision as unsigned integer) from t1"
;
set
@
var
=
1
;
--
replace_column
1
-
3
-
execute
stmt
using
@
var
;
set
@
var
=
2
;
--
replace_column
1
-
execute
stmt
using
@
var
;
set
@
var
=
3
;
--
replace_column
1
-
execute
stmt
using
@
var
;
drop
table
t1
;
deallocate
prepare
stmt
;
sql/item_func.cc
View file @
7c95fa70
...
...
@@ -1010,21 +1010,38 @@ double Item_func_round::val()
}
void
Item_func_rand
::
fix_length_and_dec
()
bool
Item_func_rand
::
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tables
,
Item
**
ref
)
{
decimals
=
NOT_FIXED_DEC
;
max_length
=
float_length
(
decimals
);
Item_real_func
::
fix_fields
(
thd
,
tables
,
ref
);
used_tables_cache
|=
RAND_TABLE_BIT
;
if
(
arg_count
)
{
// Only use argument once in query
uint32
tmp
=
(
uint32
)
(
args
[
0
]
->
val_int
());
if
((
rand
=
(
struct
rand_struct
*
)
sql_alloc
(
sizeof
(
*
rand
))))
randominit
(
rand
,(
uint32
)
(
tmp
*
0x10001L
+
55555555L
),
(
uint32
)
(
tmp
*
0x10000001L
));
/*
Allocate rand structure once: we must use thd->current_arena
to create rand in proper mem_root if it's a prepared statement or
stored procedure.
*/
if
(
!
rand
&&
!
(
rand
=
(
struct
rand_struct
*
)
thd
->
current_arena
->
alloc
(
sizeof
(
*
rand
))))
return
TRUE
;
/*
PARAM_ITEM is returned if we're in statement prepare and consequently
no placeholder value is set yet.
*/
if
(
args
[
0
]
->
type
()
!=
PARAM_ITEM
)
{
/*
TODO: do not do reinit 'rand' for every execute of PS/SP if
args[0] is a constant.
*/
uint32
tmp
=
(
uint32
)
args
[
0
]
->
val_int
();
randominit
(
rand
,
(
uint32
)
(
tmp
*
0x10001L
+
55555555L
),
(
uint32
)
(
tmp
*
0x10000001L
));
}
}
else
{
THD
*
thd
=
current_thd
;
/*
No need to send a Rand log event if seed was given eg: RAND(seed),
as it will be replicated in the query as such.
...
...
@@ -1038,6 +1055,7 @@ void Item_func_rand::fix_length_and_dec()
thd
->
rand_saved_seed2
=
thd
->
rand
.
seed2
;
rand
=
&
thd
->
rand
;
}
return
FALSE
;
}
void
Item_func_rand
::
update_used_tables
()
...
...
sql/item_func.h
View file @
7c95fa70
...
...
@@ -512,13 +512,13 @@ class Item_func_rand :public Item_real_func
{
struct
rand_struct
*
rand
;
public:
Item_func_rand
(
Item
*
a
)
:
Item_real_func
(
a
)
{}
Item_func_rand
()
:
Item_real_func
()
{}
Item_func_rand
(
Item
*
a
)
:
Item_real_func
(
a
)
,
rand
(
0
)
{}
Item_func_rand
()
:
Item_real_func
()
{}
double
val
();
const
char
*
func_name
()
const
{
return
"rand"
;
}
bool
const_item
()
const
{
return
0
;
}
void
update_used_tables
();
void
fix_length_and_dec
(
);
bool
fix_fields
(
THD
*
thd
,
struct
st_table_list
*
tables
,
Item
**
ref
);
};
...
...
sql/mysql_priv.h
View file @
7c95fa70
...
...
@@ -447,6 +447,7 @@ bool is_update_query(enum enum_sql_command command);
bool
alloc_query
(
THD
*
thd
,
char
*
packet
,
ulong
packet_length
);
void
mysql_init_select
(
LEX
*
lex
);
void
mysql_init_query
(
THD
*
thd
,
uchar
*
buf
,
uint
length
);
void
mysql_reset_thd_for_next_command
(
THD
*
thd
);
bool
mysql_new_select
(
LEX
*
lex
,
bool
move_down
);
void
create_select_for_variable
(
const
char
*
var_name
);
void
mysql_init_multi_delete
(
LEX
*
lex
);
...
...
sql/sql_class.cc
View file @
7c95fa70
...
...
@@ -1498,7 +1498,7 @@ void Statement::restore_backup_statement(Statement *stmt, Statement *backup)
}
void
Statement
::
end_statement
()
void
THD
::
end_statement
()
{
/* Cleanup SQL processing state to resuse this statement in next query. */
lex_end
(
lex
);
...
...
sql/sql_class.h
View file @
7c95fa70
...
...
@@ -582,12 +582,6 @@ public:
void
restore_backup_statement
(
Statement
*
stmt
,
Statement
*
backup
);
/* return class type */
virtual
Type
type
()
const
;
/*
Cleanup statement parse state (parse tree, lex) after execution of
a non-prepared SQL statement.
*/
void
end_statement
();
};
...
...
@@ -1063,6 +1057,12 @@ public:
void
nocheck_register_item_tree_change
(
Item
**
place
,
Item
*
old_value
,
MEM_ROOT
*
runtime_memroot
);
void
rollback_item_tree_changes
();
/*
Cleanup statement parse state (parse tree, lex) and execution
state after execution of a non-prepared SQL statement.
*/
void
end_statement
();
};
/* Flags for the THD::system_thread (bitmap) variable */
...
...
sql/sql_lex.cc
View file @
7c95fa70
...
...
@@ -117,7 +117,30 @@ void lex_free(void)
void
lex_start
(
THD
*
thd
,
uchar
*
buf
,
uint
length
)
{
LEX
*
lex
=
thd
->
lex
;
lex
->
unit
.
init_query
();
lex
->
unit
.
init_select
();
lex
->
thd
=
thd
;
lex
->
unit
.
thd
=
thd
;
lex
->
select_lex
.
init_query
();
lex
->
value_list
.
empty
();
lex
->
param_list
.
empty
();
lex
->
unit
.
next
=
lex
->
unit
.
master
=
lex
->
unit
.
link_next
=
lex
->
unit
.
return_to
=
0
;
lex
->
unit
.
prev
=
lex
->
unit
.
link_prev
=
0
;
lex
->
unit
.
slave
=
lex
->
unit
.
global_parameters
=
lex
->
current_select
=
lex
->
all_selects_list
=
&
lex
->
select_lex
;
lex
->
select_lex
.
master
=
&
lex
->
unit
;
lex
->
select_lex
.
prev
=
&
lex
->
unit
.
slave
;
lex
->
select_lex
.
link_next
=
lex
->
select_lex
.
slave
=
lex
->
select_lex
.
next
=
0
;
lex
->
select_lex
.
link_prev
=
(
st_select_lex_node
**
)
&
(
lex
->
all_selects_list
);
lex
->
select_lex
.
options
=
0
;
lex
->
describe
=
0
;
lex
->
derived_tables
=
FALSE
;
lex
->
lock_option
=
TL_READ
;
lex
->
found_colon
=
0
;
lex
->
safe_to_cache_query
=
1
;
lex
->
time_zone_tables_used
=
0
;
lex
->
select_lex
.
select_number
=
1
;
lex
->
next_state
=
MY_LEX_START
;
lex
->
end_of_query
=
(
lex
->
ptr
=
buf
)
+
length
;
lex
->
yylineno
=
1
;
...
...
sql/sql_lex.h
View file @
7c95fa70
...
...
@@ -369,7 +369,7 @@ public:
ulong
init_prepare_fake_select_lex
(
THD
*
thd
);
int
change_result
(
select_subselect
*
result
,
select_subselect
*
old_result
);
friend
void
mysql_init_query
(
THD
*
thd
,
uchar
*
buf
,
uint
length
);
friend
void
lex_start
(
THD
*
thd
,
uchar
*
buf
,
uint
length
);
friend
int
subselect_union_engine
::
exec
();
private:
bool
create_total_list_n_last_return
(
THD
*
thd
,
st_lex
*
lex
,
...
...
@@ -508,7 +508,7 @@ public:
bool
test_limit
();
friend
void
mysql_init_query
(
THD
*
thd
,
uchar
*
buf
,
uint
length
);
friend
void
lex_start
(
THD
*
thd
,
uchar
*
buf
,
uint
length
);
st_select_lex
()
{}
void
make_empty_select
()
{
...
...
sql/sql_parse.cc
View file @
7c95fa70
...
...
@@ -1001,16 +1001,15 @@ pthread_handler_decl(handle_one_connection,arg)
net
->
compress
=
1
;
// Use compression
thd
->
version
=
refresh_version
;
thd
->
proc_info
=
0
;
thd
->
set_time
();
thd
->
init_for_queries
();
if
(
sys_init_connect
.
value_length
&&
!
(
thd
->
master_access
&
SUPER_ACL
))
{
execute_init_command
(
thd
,
&
sys_init_connect
,
&
LOCK_sys_init_connect
);
if
(
thd
->
query_error
)
thd
->
killed
=
1
;
}
thd
->
proc_info
=
0
;
thd
->
set_time
();
thd
->
init_for_queries
();
while
(
!
net
->
error
&&
net
->
vio
!=
0
&&
!
thd
->
killed
)
{
if
(
do_command
(
thd
))
...
...
@@ -3854,7 +3853,6 @@ bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, ulong *yystacksize)
return
0
;
}
/****************************************************************************
Initialize global thd variables needed for query
****************************************************************************/
...
...
@@ -3863,33 +3861,30 @@ void
mysql_init_query
(
THD
*
thd
,
uchar
*
buf
,
uint
length
)
{
DBUG_ENTER
(
"mysql_init_query"
);
LEX
*
lex
=
thd
->
lex
;
lex
->
unit
.
init_query
();
lex
->
unit
.
init_select
();
lex
->
unit
.
thd
=
thd
;
lex
->
select_lex
.
init_query
();
lex
->
value_list
.
empty
();
lex
->
param_list
.
empty
();
lex
->
unit
.
next
=
lex
->
unit
.
master
=
lex
->
unit
.
link_next
=
lex
->
unit
.
return_to
=
0
;
lex
->
unit
.
prev
=
lex
->
unit
.
link_prev
=
0
;
lex
->
unit
.
slave
=
lex
->
unit
.
global_parameters
=
lex
->
current_select
=
lex
->
all_selects_list
=
&
lex
->
select_lex
;
lex
->
select_lex
.
master
=
&
lex
->
unit
;
lex
->
select_lex
.
prev
=
&
lex
->
unit
.
slave
;
lex
->
select_lex
.
link_next
=
lex
->
select_lex
.
slave
=
lex
->
select_lex
.
next
=
0
;
lex
->
select_lex
.
link_prev
=
(
st_select_lex_node
**
)
&
(
lex
->
all_selects_list
);
lex
->
select_lex
.
options
=
0
;
lex
->
describe
=
0
;
lex
->
derived_tables
=
FALSE
;
lex
->
lock_option
=
TL_READ
;
lex
->
found_colon
=
0
;
lex
->
safe_to_cache_query
=
1
;
lex
->
time_zone_tables_used
=
0
;
lex_start
(
thd
,
buf
,
length
);
thd
->
select_number
=
lex
->
select_lex
.
select_number
=
1
;
thd
->
free_list
=
0
;
thd
->
total_warn_count
=
0
;
// Warnings for this query
mysql_reset_thd_for_next_command
(
thd
);
DBUG_VOID_RETURN
;
}
/*
Reset THD part responsible for command processing state.
DESCRIPTION
This needs to be called before execution of every statement
(prepared or conventional).
TODO
Make it a method of THD and align its name with the rest of
reset/end/start/init methods.
Call it after we use THD for queries, not before.
*/
void
mysql_reset_thd_for_next_command
(
THD
*
thd
)
{
DBUG_ENTER
(
"mysql_reset_thd_for_next_command"
);
thd
->
select_number
=
1
;
thd
->
total_warn_count
=
0
;
// Warnings for this query
thd
->
last_insert_id_used
=
thd
->
query_start_used
=
thd
->
insert_id_used
=
0
;
thd
->
sent_row_count
=
thd
->
examined_row_count
=
0
;
thd
->
is_fatal_error
=
thd
->
rand_used
=
thd
->
time_zone_used
=
0
;
...
...
sql/sql_prepare.cc
View file @
7c95fa70
...
...
@@ -1760,6 +1760,8 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
DBUG_VOID_RETURN
;
}
DBUG_ASSERT
(
thd
->
free_list
==
NULL
);
mysql_reset_thd_for_next_command
(
thd
);
#ifndef EMBEDDED_LIBRARY
if
(
stmt
->
param_count
)
{
...
...
@@ -1778,7 +1780,6 @@ 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
...
...
@@ -1823,7 +1824,8 @@ void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name)
}
DBUG_ASSERT
(
thd
->
free_list
==
NULL
);
/* Must go before setting variables, as it clears thd->user_var_events */
mysql_reset_thd_for_next_command
(
thd
);
thd
->
set_n_backup_statement
(
stmt
,
&
thd
->
stmt_backup
);
if
(
stmt
->
set_params_from_vars
(
stmt
,
thd
->
stmt_backup
.
lex
->
prepared_stmt_params
,
...
...
@@ -1932,6 +1934,7 @@ void mysql_stmt_reset(THD *thd, char *packet)
*/
reset_stmt_params
(
stmt
);
mysql_reset_thd_for_next_command
(
thd
);
send_ok
(
thd
);
DBUG_VOID_RETURN
;
...
...
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