Loading mysql-test/r/ps.result +39 −0 Original line number Diff line number Diff line Loading @@ -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 +27 −1 Original line number Diff line number Diff line Loading @@ -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 +26 −8 Original line number Diff line number Diff line Loading @@ -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)))) /* 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. Loading @@ -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() Loading sql/item_func.h +3 −3 Original line number Diff line number Diff line Loading @@ -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 *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); }; Loading sql/mysql_priv.h +1 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading
mysql-test/r/ps.result +39 −0 Original line number Diff line number Diff line Loading @@ -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 +27 −1 Original line number Diff line number Diff line Loading @@ -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 +26 −8 Original line number Diff line number Diff line Loading @@ -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)))) /* 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. Loading @@ -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() Loading
sql/item_func.h +3 −3 Original line number Diff line number Diff line Loading @@ -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 *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); }; Loading
sql/mysql_priv.h +1 −0 Original line number Diff line number Diff line Loading @@ -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); Loading