Loading mysql-test/r/func_math.result +40 −5 Original line number Diff line number Diff line Loading @@ -177,11 +177,46 @@ drop table t1; select abs(-2) * -2; abs(-2) * -2 -4 create table t1 (i int); insert into t1 values (1); select rand(i) from t1; ERROR HY000: Incorrect arguments to RAND drop table t1; CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1),(1),(1),(2); SELECT CAST(RAND(2) * 1000 AS UNSIGNED), CAST(RAND(a) * 1000 AS UNSIGNED) FROM t1; CAST(RAND(2) * 1000 AS UNSIGNED) CAST(RAND(a) * 1000 AS UNSIGNED) 656 405 122 405 645 405 858 656 SELECT CAST(RAND(2) * 1000 AS UNSIGNED), CAST(RAND(a) * 1000 AS UNSIGNED) FROM t1 WHERE a = 1; CAST(RAND(2) * 1000 AS UNSIGNED) CAST(RAND(a) * 1000 AS UNSIGNED) 656 405 122 405 645 405 INSERT INTO t1 VALUES (3); SELECT CAST(RAND(2) * 1000 AS UNSIGNED), CAST(RAND(a) * 1000 AS UNSIGNED) FROM t1; CAST(RAND(2) * 1000 AS UNSIGNED) CAST(RAND(a) * 1000 AS UNSIGNED) 656 405 122 405 645 405 858 656 354 906 SELECT CAST(RAND(2) * 1000 AS UNSIGNED), CAST(RAND(a) * 1000 AS UNSIGNED) FROM t1 WHERE a = 1; CAST(RAND(2) * 1000 AS UNSIGNED) CAST(RAND(a) * 1000 AS UNSIGNED) 656 405 122 405 645 405 PREPARE stmt FROM "SELECT CAST(RAND(2) * 1000 AS UNSIGNED), CAST(RAND(?) * 1000 AS UNSIGNED) FROM t1 WHERE a = 1"; set @var=2; EXECUTE stmt USING @var; CAST(RAND(2) * 1000 AS UNSIGNED) CAST(RAND(?) * 1000 AS UNSIGNED) 656 656 122 122 645 645 DROP TABLE t1; create table t1 (a varchar(90), ts datetime not null, index (a)) engine=innodb default charset=utf8; insert into t1 values ('http://www.foo.com/', now()); select a from t1 where a='http://www.foo.com/' order by abs(timediff(ts, 0)); Loading mysql-test/t/func_math.test +19 −5 Original line number Diff line number Diff line Loading @@ -115,11 +115,25 @@ select abs(-2) * -2; # # Bug #6172 RAND(a) should only accept constant values as arguments # create table t1 (i int); insert into t1 values (1); --error 1210 select rand(i) from t1; drop table t1; CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1),(1),(1),(2); SELECT CAST(RAND(2) * 1000 AS UNSIGNED), CAST(RAND(a) * 1000 AS UNSIGNED) FROM t1; SELECT CAST(RAND(2) * 1000 AS UNSIGNED), CAST(RAND(a) * 1000 AS UNSIGNED) FROM t1 WHERE a = 1; INSERT INTO t1 VALUES (3); SELECT CAST(RAND(2) * 1000 AS UNSIGNED), CAST(RAND(a) * 1000 AS UNSIGNED) FROM t1; SELECT CAST(RAND(2) * 1000 AS UNSIGNED), CAST(RAND(a) * 1000 AS UNSIGNED) FROM t1 WHERE a = 1; PREPARE stmt FROM "SELECT CAST(RAND(2) * 1000 AS UNSIGNED), CAST(RAND(?) * 1000 AS UNSIGNED) FROM t1 WHERE a = 1"; set @var=2; EXECUTE stmt USING @var; DROP TABLE t1; # # Bug #14009: use of abs() on null value causes problems with filesort Loading sql/item_func.cc +17 −19 Original line number Diff line number Diff line Loading @@ -2042,6 +2042,18 @@ my_decimal *Item_func_round::decimal_op(my_decimal *decimal_value) } void Item_func_rand::seed_random(Item *arg) { /* TODO: do not do reinit 'rand' for every execute of PS/SP if args[0] is a constant. */ uint32 tmp= (uint32) arg->val_int(); randominit(rand, (uint32) (tmp*0x10001L+55555555L), (uint32) (tmp*0x10000001L)); } bool Item_func_rand::fix_fields(THD *thd,Item **ref) { if (Item_real_func::fix_fields(thd, ref)) Loading @@ -2049,11 +2061,6 @@ bool Item_func_rand::fix_fields(THD *thd,Item **ref) used_tables_cache|= RAND_TABLE_BIT; if (arg_count) { // Only use argument once in query if (!args[0]->const_during_execution()) { my_error(ER_WRONG_ARGUMENTS, MYF(0), "RAND"); return TRUE; } /* Allocate rand structure once: we must use thd->stmt_arena to create rand in proper mem_root if it's a prepared statement or Loading @@ -2065,20 +2072,9 @@ bool Item_func_rand::fix_fields(THD *thd,Item **ref) if (!rand && !(rand= (struct rand_struct*) thd->stmt_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)); } if (args[0]->const_item()) seed_random (args[0]); } else { Loading Loading @@ -2108,6 +2104,8 @@ void Item_func_rand::update_used_tables() double Item_func_rand::val_real() { DBUG_ASSERT(fixed == 1); if (arg_count && !args[0]->const_item()) seed_random (args[0]); return my_rnd(rand); } Loading sql/item_func.h +2 −0 Original line number Diff line number Diff line Loading @@ -679,6 +679,8 @@ class Item_func_rand :public Item_real_func bool const_item() const { return 0; } void update_used_tables(); bool fix_fields(THD *thd, Item **ref); private: void seed_random (Item * val); }; Loading Loading
mysql-test/r/func_math.result +40 −5 Original line number Diff line number Diff line Loading @@ -177,11 +177,46 @@ drop table t1; select abs(-2) * -2; abs(-2) * -2 -4 create table t1 (i int); insert into t1 values (1); select rand(i) from t1; ERROR HY000: Incorrect arguments to RAND drop table t1; CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1),(1),(1),(2); SELECT CAST(RAND(2) * 1000 AS UNSIGNED), CAST(RAND(a) * 1000 AS UNSIGNED) FROM t1; CAST(RAND(2) * 1000 AS UNSIGNED) CAST(RAND(a) * 1000 AS UNSIGNED) 656 405 122 405 645 405 858 656 SELECT CAST(RAND(2) * 1000 AS UNSIGNED), CAST(RAND(a) * 1000 AS UNSIGNED) FROM t1 WHERE a = 1; CAST(RAND(2) * 1000 AS UNSIGNED) CAST(RAND(a) * 1000 AS UNSIGNED) 656 405 122 405 645 405 INSERT INTO t1 VALUES (3); SELECT CAST(RAND(2) * 1000 AS UNSIGNED), CAST(RAND(a) * 1000 AS UNSIGNED) FROM t1; CAST(RAND(2) * 1000 AS UNSIGNED) CAST(RAND(a) * 1000 AS UNSIGNED) 656 405 122 405 645 405 858 656 354 906 SELECT CAST(RAND(2) * 1000 AS UNSIGNED), CAST(RAND(a) * 1000 AS UNSIGNED) FROM t1 WHERE a = 1; CAST(RAND(2) * 1000 AS UNSIGNED) CAST(RAND(a) * 1000 AS UNSIGNED) 656 405 122 405 645 405 PREPARE stmt FROM "SELECT CAST(RAND(2) * 1000 AS UNSIGNED), CAST(RAND(?) * 1000 AS UNSIGNED) FROM t1 WHERE a = 1"; set @var=2; EXECUTE stmt USING @var; CAST(RAND(2) * 1000 AS UNSIGNED) CAST(RAND(?) * 1000 AS UNSIGNED) 656 656 122 122 645 645 DROP TABLE t1; create table t1 (a varchar(90), ts datetime not null, index (a)) engine=innodb default charset=utf8; insert into t1 values ('http://www.foo.com/', now()); select a from t1 where a='http://www.foo.com/' order by abs(timediff(ts, 0)); Loading
mysql-test/t/func_math.test +19 −5 Original line number Diff line number Diff line Loading @@ -115,11 +115,25 @@ select abs(-2) * -2; # # Bug #6172 RAND(a) should only accept constant values as arguments # create table t1 (i int); insert into t1 values (1); --error 1210 select rand(i) from t1; drop table t1; CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1),(1),(1),(2); SELECT CAST(RAND(2) * 1000 AS UNSIGNED), CAST(RAND(a) * 1000 AS UNSIGNED) FROM t1; SELECT CAST(RAND(2) * 1000 AS UNSIGNED), CAST(RAND(a) * 1000 AS UNSIGNED) FROM t1 WHERE a = 1; INSERT INTO t1 VALUES (3); SELECT CAST(RAND(2) * 1000 AS UNSIGNED), CAST(RAND(a) * 1000 AS UNSIGNED) FROM t1; SELECT CAST(RAND(2) * 1000 AS UNSIGNED), CAST(RAND(a) * 1000 AS UNSIGNED) FROM t1 WHERE a = 1; PREPARE stmt FROM "SELECT CAST(RAND(2) * 1000 AS UNSIGNED), CAST(RAND(?) * 1000 AS UNSIGNED) FROM t1 WHERE a = 1"; set @var=2; EXECUTE stmt USING @var; DROP TABLE t1; # # Bug #14009: use of abs() on null value causes problems with filesort Loading
sql/item_func.cc +17 −19 Original line number Diff line number Diff line Loading @@ -2042,6 +2042,18 @@ my_decimal *Item_func_round::decimal_op(my_decimal *decimal_value) } void Item_func_rand::seed_random(Item *arg) { /* TODO: do not do reinit 'rand' for every execute of PS/SP if args[0] is a constant. */ uint32 tmp= (uint32) arg->val_int(); randominit(rand, (uint32) (tmp*0x10001L+55555555L), (uint32) (tmp*0x10000001L)); } bool Item_func_rand::fix_fields(THD *thd,Item **ref) { if (Item_real_func::fix_fields(thd, ref)) Loading @@ -2049,11 +2061,6 @@ bool Item_func_rand::fix_fields(THD *thd,Item **ref) used_tables_cache|= RAND_TABLE_BIT; if (arg_count) { // Only use argument once in query if (!args[0]->const_during_execution()) { my_error(ER_WRONG_ARGUMENTS, MYF(0), "RAND"); return TRUE; } /* Allocate rand structure once: we must use thd->stmt_arena to create rand in proper mem_root if it's a prepared statement or Loading @@ -2065,20 +2072,9 @@ bool Item_func_rand::fix_fields(THD *thd,Item **ref) if (!rand && !(rand= (struct rand_struct*) thd->stmt_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)); } if (args[0]->const_item()) seed_random (args[0]); } else { Loading Loading @@ -2108,6 +2104,8 @@ void Item_func_rand::update_used_tables() double Item_func_rand::val_real() { DBUG_ASSERT(fixed == 1); if (arg_count && !args[0]->const_item()) seed_random (args[0]); return my_rnd(rand); } Loading
sql/item_func.h +2 −0 Original line number Diff line number Diff line Loading @@ -679,6 +679,8 @@ class Item_func_rand :public Item_real_func bool const_item() const { return 0; } void update_used_tables(); bool fix_fields(THD *thd, Item **ref); private: void seed_random (Item * val); }; Loading