Commit 3a5a0ea3 authored by unknown's avatar unknown

Bug#30269 Query cache eats memory

Although the query cache doesn't support retrieval of statements containing
column level access control, it was still possible to cache such statements
thus wasting memory.
  
This patch extends the access control check on the target tables to avoid
caching a statement with column level restrictions. 

Views are excepted and can be cached but only retrieved by super user account.


mysql-test/t/query_cache_with_views.test:
  Rename: mysql-test/t/view_query_cache.test -> mysql-test/t/query_cache_with_views.test
mysql-test/r/query_cache_with_views.result:
  Rename: mysql-test/r/view_query_cache.result -> mysql-test/r/query_cache_with_views.result
mysql-test/r/query_cache.result:
  Modified test case to allow caching of views
mysql-test/t/query_cache.test:
  Modified test case to allow caching of views
sql/sql_cache.cc:
  Allow caching of views
parent bd80048f
...@@ -1503,10 +1503,11 @@ a (select count(*) from t2) ...@@ -1503,10 +1503,11 @@ a (select count(*) from t2)
4 0 4 0
drop table t1,t2; drop table t1,t2;
DROP DATABASE IF EXISTS bug30269; DROP DATABASE IF EXISTS bug30269;
FLUSH STATUS;
CREATE DATABASE bug30269; CREATE DATABASE bug30269;
USE bug30269; USE bug30269;
CREATE TABLE test1 (id int, name varchar(23)); CREATE TABLE test1 (id int, name varchar(23));
CREATE VIEW view1 AS SELECT id FROM test1; CREATE VIEW view1 AS SELECT * FROM test1;
INSERT INTO test1 VALUES (5, 'testit'); INSERT INTO test1 VALUES (5, 'testit');
GRANT SELECT (id) ON TABLE bug30269.test1 TO 'bug30269'@'localhost'; GRANT SELECT (id) ON TABLE bug30269.test1 TO 'bug30269'@'localhost';
GRANT SELECT ON TABLE bug30269.view1 TO 'bug30269'@'localhost'; GRANT SELECT ON TABLE bug30269.view1 TO 'bug30269'@'localhost';
...@@ -1515,15 +1516,19 @@ USE bug30269; ...@@ -1515,15 +1516,19 @@ USE bug30269;
show status like 'Qcache_queries_in_cache'; show status like 'Qcache_queries_in_cache';
Variable_name Value Variable_name Value
Qcache_queries_in_cache 0 Qcache_queries_in_cache 0
# Select statement not stored in query cache because of column privileges.
SELECT id FROM test1 WHERE id>2; SELECT id FROM test1 WHERE id>2;
id id
5 5
show status like 'Qcache_queries_in_cache';
Variable_name Value
Qcache_queries_in_cache 0
SELECT id FROM view1 WHERE id>2; SELECT id FROM view1 WHERE id>2;
id id
5 5
show status like 'Qcache_queries_in_cache'; show status like 'Qcache_queries_in_cache';
Variable_name Value Variable_name Value
Qcache_queries_in_cache 0 Qcache_queries_in_cache 1
DROP DATABASE bug30269; DROP DATABASE bug30269;
DROP USER 'bug30269'@'localhost'; DROP USER 'bug30269'@'localhost';
set GLOBAL query_cache_type=default; set GLOBAL query_cache_type=default;
......
...@@ -1103,10 +1103,11 @@ disconnect user3; ...@@ -1103,10 +1103,11 @@ disconnect user3;
--disable_warnings --disable_warnings
DROP DATABASE IF EXISTS bug30269; DROP DATABASE IF EXISTS bug30269;
--enable_warnings --enable_warnings
FLUSH STATUS;
CREATE DATABASE bug30269; CREATE DATABASE bug30269;
USE bug30269; USE bug30269;
CREATE TABLE test1 (id int, name varchar(23)); CREATE TABLE test1 (id int, name varchar(23));
CREATE VIEW view1 AS SELECT id FROM test1; CREATE VIEW view1 AS SELECT * FROM test1;
INSERT INTO test1 VALUES (5, 'testit'); INSERT INTO test1 VALUES (5, 'testit');
GRANT SELECT (id) ON TABLE bug30269.test1 TO 'bug30269'@'localhost'; GRANT SELECT (id) ON TABLE bug30269.test1 TO 'bug30269'@'localhost';
GRANT SELECT ON TABLE bug30269.view1 TO 'bug30269'@'localhost'; GRANT SELECT ON TABLE bug30269.view1 TO 'bug30269'@'localhost';
...@@ -1115,7 +1116,9 @@ connect (bug30269, localhost, bug30269,,); ...@@ -1115,7 +1116,9 @@ connect (bug30269, localhost, bug30269,,);
connection bug30269; connection bug30269;
USE bug30269; USE bug30269;
show status like 'Qcache_queries_in_cache'; show status like 'Qcache_queries_in_cache';
--echo # Select statement not stored in query cache because of column privileges.
SELECT id FROM test1 WHERE id>2; SELECT id FROM test1 WHERE id>2;
show status like 'Qcache_queries_in_cache';
SELECT id FROM view1 WHERE id>2; SELECT id FROM view1 WHERE id>2;
show status like 'Qcache_queries_in_cache'; show status like 'Qcache_queries_in_cache';
......
...@@ -3007,8 +3007,19 @@ Query_cache::process_and_count_tables(THD *thd, TABLE_LIST *tables_used, ...@@ -3007,8 +3007,19 @@ Query_cache::process_and_count_tables(THD *thd, TABLE_LIST *tables_used,
The grant.want_privileges flag was set to 1 in the The grant.want_privileges flag was set to 1 in the
check_grant() function earlier if the TABLE_LIST object check_grant() function earlier if the TABLE_LIST object
had any associated column privileges. had any associated column privileges.
We need to check that the TABLE_LIST object isn't part
of a VIEW definition because we want to be able to cache
views.
TODO: Although it is possible to cache views, the privilege
check on view tables always fall back on column privileges
even if there are more generic table privileges. Thus it isn't
currently possible to retrieve cached view-tables unless the
client has the super user privileges.
*/ */
if (tables_used->grant.want_privilege) if (tables_used->grant.want_privilege &&
tables_used->belong_to_view == NULL)
{ {
DBUG_PRINT("qcache", ("Don't cache statement as it refers to " DBUG_PRINT("qcache", ("Don't cache statement as it refers to "
"tables with column privileges.")); "tables with column privileges."));
......
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