Commit 55c1b794 authored by unknown's avatar unknown
Browse files

Merge bk-internal.mysql.com:/home/bk/mysql-4.1

into mysql.com:/media/sda1/mysql/mysql-4.1-5985


sql/sql_class.h:
  Auto merged
parents 7b1f818d 54b00f54
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
@@ -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;
+27 −1
Original line number Diff line number Diff line
@@ -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;
+26 −8
Original line number Diff line number Diff line
@@ -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.
@@ -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()
+3 −3
Original line number Diff line number Diff line
@@ -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);
};


+1 −0
Original line number Diff line number Diff line
@@ -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