Commit 36f1e484 authored by unknown's avatar unknown

Fixed bug #29338.

Optimization of queries with DETERMINISTIC functions in the
WHERE clause was not effective: sequential scan was always
used.
Now a SF with the DETERMINISTIC flags is treated as constant
when it's arguments are constants (or a SF doesn't has arguments).


sql/item_func.h:
  Fixed bug #29338.
  The Item_func_sp::used_tables has been removed
  (virtual Item_func::used_tables function is enough).
  The virtual Item_func_sp::update_used_tables function
  has been added.
sql/item_func.cc:
  Fixed bug #29338.
  The Item_func_sp::update_used_tables and the
  Item_func_sp::fix_field functions have been modified
  to take into account the DETERMINISTIC flag of SF definition.
mysql-test/r/sp.result:
  Updated test case for bug #29338.
mysql-test/t/sp.test:
  Updated test case for bug #29338.
parent 85603b2e
use test; use test;
drop table if exists t1,t2,t3,t4; drop table if exists t1,t2,t3,t4;
drop function if exists f1;
drop function if exists f2;
create table t1 ( create table t1 (
id char(16) not null default '', id char(16) not null default '',
data int not null data int not null
...@@ -6144,7 +6146,7 @@ drop table t1,t2; ...@@ -6144,7 +6146,7 @@ drop table t1,t2;
CREATE TABLE t1 (a int auto_increment primary key) engine=MyISAM; CREATE TABLE t1 (a int auto_increment primary key) engine=MyISAM;
CREATE TABLE t2 (a int auto_increment primary key, b int) engine=innodb; CREATE TABLE t2 (a int auto_increment primary key, b int) engine=innodb;
set @a=0; set @a=0;
CREATE function bug27354() RETURNS int deterministic CREATE function bug27354() RETURNS int not deterministic
begin begin
insert into t1 values (null); insert into t1 values (null);
set @a=@a+1; set @a=@a+1;
...@@ -6176,4 +6178,33 @@ v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VI ...@@ -6176,4 +6178,33 @@ v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VI
DROP VIEW v1; DROP VIEW v1;
DROP FUNCTION metered; DROP FUNCTION metered;
DROP TABLE t1; DROP TABLE t1;
CREATE FUNCTION f1() RETURNS INT DETERMINISTIC RETURN 2;
CREATE FUNCTION f2(I INT) RETURNS INT DETERMINISTIC RETURN 3;
CREATE TABLE t1 (c1 INT, INDEX(c1));
INSERT INTO t1 VALUES (1), (2), (3), (4), (5);
CREATE VIEW v1 AS SELECT c1 FROM t1;
EXPLAIN SELECT * FROM t1 WHERE c1=1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref c1 c1 5 const 1 Using where; Using index
EXPLAIN SELECT * FROM t1 WHERE c1=f1();
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref c1 c1 5 const 1 Using where; Using index
EXPLAIN SELECT * FROM v1 WHERE c1=1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref c1 c1 5 const 1 Using where; Using index
EXPLAIN SELECT * FROM v1 WHERE c1=f1();
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref c1 c1 5 const 1 Using where; Using index
EXPLAIN SELECT * FROM t1 WHERE c1=f2(10);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref c1 c1 5 const 1 Using where; Using index
EXPLAIN SELECT * FROM t1 WHERE c1=f2(c1);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL c1 5 NULL 5 Using where; Using index
EXPLAIN SELECT * FROM t1 WHERE c1=f2(rand());
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL c1 5 NULL 5 Using where; Using index
DROP VIEW v1;
DROP FUNCTION f1;
DROP TABLE t1;
End of 5.0 tests End of 5.0 tests
...@@ -23,6 +23,8 @@ use test; ...@@ -23,6 +23,8 @@ use test;
# #
--disable_warnings --disable_warnings
drop table if exists t1,t2,t3,t4; drop table if exists t1,t2,t3,t4;
drop function if exists f1;
drop function if exists f2;
--enable_warnings --enable_warnings
create table t1 ( create table t1 (
id char(16) not null default '', id char(16) not null default '',
...@@ -7098,7 +7100,7 @@ CREATE TABLE t2 (a int auto_increment primary key, b int) engine=innodb; ...@@ -7098,7 +7100,7 @@ CREATE TABLE t2 (a int auto_increment primary key, b int) engine=innodb;
set @a=0; set @a=0;
delimiter |; delimiter |;
CREATE function bug27354() RETURNS int deterministic CREATE function bug27354() RETURNS int not deterministic
begin begin
insert into t1 values (null); insert into t1 values (null);
set @a=@a+1; set @a=@a+1;
...@@ -7134,5 +7136,33 @@ DROP VIEW v1; ...@@ -7134,5 +7136,33 @@ DROP VIEW v1;
DROP FUNCTION metered; DROP FUNCTION metered;
DROP TABLE t1; DROP TABLE t1;
#
# Bug #29338: no optimization for stored functions with a trivial body
# always returning constant.
#
CREATE FUNCTION f1() RETURNS INT DETERMINISTIC RETURN 2;
CREATE FUNCTION f2(I INT) RETURNS INT DETERMINISTIC RETURN 3;
CREATE TABLE t1 (c1 INT, INDEX(c1));
INSERT INTO t1 VALUES (1), (2), (3), (4), (5);
CREATE VIEW v1 AS SELECT c1 FROM t1;
EXPLAIN SELECT * FROM t1 WHERE c1=1;
EXPLAIN SELECT * FROM t1 WHERE c1=f1();
EXPLAIN SELECT * FROM v1 WHERE c1=1;
EXPLAIN SELECT * FROM v1 WHERE c1=f1();
EXPLAIN SELECT * FROM t1 WHERE c1=f2(10);
EXPLAIN SELECT * FROM t1 WHERE c1=f2(c1);
EXPLAIN SELECT * FROM t1 WHERE c1=f2(rand());
DROP VIEW v1;
DROP FUNCTION f1;
DROP TABLE t1;
--echo End of 5.0 tests --echo End of 5.0 tests
...@@ -5591,5 +5591,15 @@ Item_func_sp::fix_fields(THD *thd, Item **ref) ...@@ -5591,5 +5591,15 @@ Item_func_sp::fix_fields(THD *thd, Item **ref)
#endif /* ! NO_EMBEDDED_ACCESS_CHECKS */ #endif /* ! NO_EMBEDDED_ACCESS_CHECKS */
} }
if (!m_sp->m_chistics->detistic)
used_tables_cache |= RAND_TABLE_BIT;
DBUG_RETURN(res); DBUG_RETURN(res);
} }
void Item_func_sp::update_used_tables()
{
Item_func::update_used_tables();
if (!m_sp->m_chistics->detistic)
used_tables_cache |= RAND_TABLE_BIT;
}
...@@ -1467,7 +1467,7 @@ public: ...@@ -1467,7 +1467,7 @@ public:
virtual ~Item_func_sp() virtual ~Item_func_sp()
{} {}
table_map used_tables() const { return RAND_TABLE_BIT; } void update_used_tables();
void cleanup(); void cleanup();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment