2005-03-30 01:50:16 +02:00
|
|
|
# Grant tests not performed with embedded server
|
|
|
|
-- source include/not_embedded.inc
|
2002-03-22 21:55:08 +01:00
|
|
|
-- source include/have_query_cache.inc
|
Fix for BUG#735 "Prepared Statements: there is no support for Query
Cache".
WL#1569 "Prepared Statements: implement support of Query Cache".
Prepared SELECTs did not look up in the query cache, and their results
were not stored in the query cache. This made them slower than
non-prepared SELECTs in some cases.
The fix is to re-use the expanded query (the prepared query where
"?" placeholders are replaced by their values, at execution time)
for searching/storing in the query cache.
It works fine for statements prepared via mysql_stmt_prepare(), which
are the most commonly used and were the scope of this bugfix and WL.
It works less fine for statements prepared via the SQL command
PREPARE...FROM, which are still not using the query cache if they
have at least one parameter (because then the expanded query contains
names of user variables, and user variables don't work with the
query cache, even in non-prepared queries).
Note that results from prepared SELECTs, which are in the binary
protocol, and results from normal SELECTs, which are in the text
protocol, ignore each other in the query cache, because a result in the
binary protocol should never be served to a SELECT expecting the text
protocol and vice-versa.
Note, after this patch, bug 25843 starts applying to query cache
("changing default database between PREPARE and EXECUTE of statement
breaks binlog"), we need to fix it.
2007-03-09 18:09:57 +01:00
|
|
|
# See at the end of the test why we disable the ps protocol (*)
|
|
|
|
-- disable_ps_protocol
|
2002-03-22 21:55:08 +01:00
|
|
|
|
2007-02-26 11:49:24 +01:00
|
|
|
--source include/add_anonymous_users.inc
|
|
|
|
|
2001-12-22 14:13:31 +01:00
|
|
|
#
|
|
|
|
# Test grants with query cache
|
|
|
|
#
|
2003-01-06 00:48:59 +01:00
|
|
|
--disable_warnings
|
2001-12-22 14:13:31 +01:00
|
|
|
drop table if exists test.t1,mysqltest.t1,mysqltest.t2;
|
2003-08-11 21:44:43 +02:00
|
|
|
drop database if exists mysqltest;
|
2003-01-06 00:48:59 +01:00
|
|
|
--enable_warnings
|
|
|
|
|
2005-05-18 15:41:32 +02:00
|
|
|
set GLOBAL query_cache_size=1355776;
|
|
|
|
|
2001-12-22 14:13:31 +01:00
|
|
|
reset query cache;
|
|
|
|
flush status;
|
2004-07-15 03:19:07 +02:00
|
|
|
connect (root,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK);
|
2001-12-22 14:13:31 +01:00
|
|
|
connection root;
|
2004-04-05 14:55:26 +02:00
|
|
|
show grants for current_user;
|
|
|
|
show grants;
|
2003-01-06 00:48:59 +01:00
|
|
|
--disable_warnings
|
2001-12-22 14:13:31 +01:00
|
|
|
create database if not exists mysqltest;
|
2003-01-06 00:48:59 +01:00
|
|
|
--enable_warnings
|
2001-12-22 14:13:31 +01:00
|
|
|
|
|
|
|
create table mysqltest.t1 (a int,b int,c int);
|
|
|
|
create table mysqltest.t2 (a int,b int,c int);
|
|
|
|
insert into mysqltest.t1 values (1,1,1),(2,2,2);
|
|
|
|
insert into mysqltest.t2 values (3,3,3);
|
|
|
|
create table test.t1 (a char (10));
|
|
|
|
insert into test.t1 values ("test.t1");
|
|
|
|
select * from t1;
|
2004-07-15 03:19:07 +02:00
|
|
|
connect (root2,localhost,root,,mysqltest,$MASTER_MYPORT,$MASTER_MYSOCK);
|
2001-12-22 14:13:31 +01:00
|
|
|
connection root2;
|
|
|
|
# put queries in cache
|
|
|
|
select * from t1;
|
|
|
|
select a from t1;
|
|
|
|
select c from t1;
|
|
|
|
select * from t2;
|
|
|
|
select * from mysqltest.t1,test.t1;
|
|
|
|
show status like "Qcache_queries_in_cache";
|
|
|
|
show status like "Qcache_hits%";
|
|
|
|
|
|
|
|
# Create the test users
|
|
|
|
grant SELECT on mysqltest.* to mysqltest_1@localhost;
|
|
|
|
grant SELECT on mysqltest.t1 to mysqltest_2@localhost;
|
|
|
|
grant SELECT on test.t1 to mysqltest_2@localhost;
|
|
|
|
grant SELECT(a) on mysqltest.t1 to mysqltest_3@localhost;
|
|
|
|
|
|
|
|
# The following queries should be fetched from cache
|
2004-07-15 03:19:07 +02:00
|
|
|
connect (user1,localhost,mysqltest_1,,mysqltest,$MASTER_MYPORT,$MASTER_MYSOCK);
|
2001-12-22 14:13:31 +01:00
|
|
|
connection user1;
|
2004-04-05 14:55:26 +02:00
|
|
|
show grants for current_user();
|
2004-03-21 10:48:51 +01:00
|
|
|
show status like "Qcache_queries_in_cache";
|
|
|
|
show status like "Qcache_hits";
|
|
|
|
show status like "Qcache_not_cached";
|
2001-12-22 14:13:31 +01:00
|
|
|
select "user1";
|
2004-03-21 10:48:51 +01:00
|
|
|
show status like "Qcache_queries_in_cache";
|
|
|
|
show status like "Qcache_hits";
|
|
|
|
show status like "Qcache_not_cached";
|
2001-12-22 14:13:31 +01:00
|
|
|
select * from t1;
|
2004-03-21 10:48:51 +01:00
|
|
|
show status like "Qcache_queries_in_cache";
|
|
|
|
show status like "Qcache_hits";
|
|
|
|
show status like "Qcache_not_cached";
|
2001-12-22 14:13:31 +01:00
|
|
|
# The pre and end space are intentional
|
|
|
|
select a from t1 ;
|
2004-03-21 10:48:51 +01:00
|
|
|
show status like "Qcache_queries_in_cache";
|
|
|
|
show status like "Qcache_hits";
|
|
|
|
show status like "Qcache_not_cached";
|
2001-12-22 14:13:31 +01:00
|
|
|
select c from t1;
|
|
|
|
show status like "Qcache_queries_in_cache";
|
|
|
|
show status like "Qcache_hits";
|
|
|
|
show status like "Qcache_not_cached";
|
|
|
|
|
2007-02-26 11:49:24 +01:00
|
|
|
|
2004-08-12 13:12:09 +02:00
|
|
|
# Don't use '' as user because it will pick Unix login
|
2004-09-06 14:14:10 +02:00
|
|
|
connect (unkuser,localhost,unkuser,,,$MASTER_MYPORT,$MASTER_MYSOCK);
|
2004-04-05 14:55:26 +02:00
|
|
|
connection unkuser;
|
|
|
|
show grants for current_user();
|
|
|
|
|
2001-12-22 14:13:31 +01:00
|
|
|
# The following queries should be fetched from cache
|
2004-07-15 03:19:07 +02:00
|
|
|
connect (user2,localhost,mysqltest_2,,mysqltest,$MASTER_MYPORT,$MASTER_MYSOCK);
|
2001-12-22 14:13:31 +01:00
|
|
|
connection user2;
|
|
|
|
select "user2";
|
|
|
|
select * from t1;
|
|
|
|
select a from t1;
|
|
|
|
select c from t1;
|
|
|
|
select * from mysqltest.t1,test.t1;
|
2003-01-28 07:38:28 +01:00
|
|
|
--replace_result 127.0.0.1 localhost
|
2001-12-22 14:13:31 +01:00
|
|
|
--error 1142
|
|
|
|
select * from t2;
|
|
|
|
show status like "Qcache_queries_in_cache";
|
|
|
|
show status like "Qcache_hits";
|
|
|
|
show status like "Qcache_not_cached";
|
|
|
|
|
|
|
|
# The following queries should not be fetched from cache
|
2004-07-15 03:19:07 +02:00
|
|
|
connect (user3,localhost,mysqltest_3,,mysqltest,$MASTER_MYPORT,$MASTER_MYSOCK);
|
2001-12-22 14:13:31 +01:00
|
|
|
connection user3;
|
|
|
|
select "user3";
|
2003-01-28 07:38:28 +01:00
|
|
|
--replace_result 127.0.0.1 localhost
|
2001-12-22 14:13:31 +01:00
|
|
|
--error 1143
|
|
|
|
select * from t1;
|
|
|
|
select a from t1;
|
2003-01-28 07:38:28 +01:00
|
|
|
--replace_result 127.0.0.1 localhost
|
2001-12-22 14:13:31 +01:00
|
|
|
--error 1143
|
|
|
|
select c from t1;
|
2003-01-28 07:38:28 +01:00
|
|
|
--replace_result 127.0.0.1 localhost
|
2001-12-22 14:13:31 +01:00
|
|
|
--error 1142
|
|
|
|
select * from t2;
|
2003-01-28 07:38:28 +01:00
|
|
|
--replace_result 127.0.0.1 localhost
|
2001-12-22 14:13:31 +01:00
|
|
|
--error 1143
|
|
|
|
select mysqltest.t1.c from test.t1,mysqltest.t1;
|
|
|
|
show status like "Qcache_queries_in_cache";
|
|
|
|
show status like "Qcache_hits";
|
|
|
|
show status like "Qcache_not_cached";
|
|
|
|
|
|
|
|
# Connect without a database
|
2004-07-15 03:19:07 +02:00
|
|
|
connect (user4,localhost,mysqltest_1,,*NO-ONE*,$MASTER_MYPORT,$MASTER_MYSOCK);
|
2001-12-22 14:13:31 +01:00
|
|
|
connection user4;
|
|
|
|
select "user4";
|
2004-04-05 14:55:26 +02:00
|
|
|
show grants;
|
2001-12-22 14:13:31 +01:00
|
|
|
--error 1046
|
|
|
|
select a from t1;
|
|
|
|
# The following query is not cached before (different database)
|
|
|
|
select * from mysqltest.t1,test.t1;
|
|
|
|
# Cache a query with 'no database'
|
|
|
|
select a from mysqltest.t1;
|
|
|
|
select a from mysqltest.t1;
|
|
|
|
show status like "Qcache_queries_in_cache";
|
|
|
|
show status like "Qcache_hits";
|
|
|
|
show status like "Qcache_not_cached";
|
|
|
|
|
|
|
|
# Cleanup
|
|
|
|
|
|
|
|
connection root;
|
2004-07-08 15:54:07 +02:00
|
|
|
#
|
|
|
|
# A temporary 4.1 workaround to make this test pass if
|
|
|
|
# mysql was compiled with other than latin1 --with-charset=XXX.
|
|
|
|
# Without "set names binary" the below queries fail with
|
|
|
|
# "Illegal mix of collations" error.
|
|
|
|
# In 5.0 we will change grant tables to use NCHAR(N) instead
|
|
|
|
# of "CHAR(N) BINARY", and use cast-to-nchar: N'mysqltest_1'.
|
|
|
|
#
|
|
|
|
set names binary;
|
2001-12-22 14:13:31 +01:00
|
|
|
delete from mysql.user where user in ("mysqltest_1","mysqltest_2","mysqltest_3");
|
|
|
|
delete from mysql.db where user in ("mysqltest_1","mysqltest_2","mysqltest_3");
|
|
|
|
delete from mysql.tables_priv where user in ("mysqltest_1","mysqltest_2","mysqltest_3");
|
|
|
|
delete from mysql.columns_priv where user in ("mysqltest_1","mysqltest_2","mysqltest_3");
|
|
|
|
flush privileges;
|
|
|
|
drop table test.t1,mysqltest.t1,mysqltest.t2;
|
|
|
|
drop database mysqltest;
|
2005-05-18 15:41:32 +02:00
|
|
|
|
|
|
|
set GLOBAL query_cache_size=default;
|
2005-07-28 02:22:47 +02:00
|
|
|
|
2007-02-26 11:49:24 +01:00
|
|
|
--source include/delete_anonymous_users.inc
|
|
|
|
|
|
|
|
|
2005-07-28 02:22:47 +02:00
|
|
|
# End of 4.1 tests
|
Fix for BUG#735 "Prepared Statements: there is no support for Query
Cache".
WL#1569 "Prepared Statements: implement support of Query Cache".
Prepared SELECTs did not look up in the query cache, and their results
were not stored in the query cache. This made them slower than
non-prepared SELECTs in some cases.
The fix is to re-use the expanded query (the prepared query where
"?" placeholders are replaced by their values, at execution time)
for searching/storing in the query cache.
It works fine for statements prepared via mysql_stmt_prepare(), which
are the most commonly used and were the scope of this bugfix and WL.
It works less fine for statements prepared via the SQL command
PREPARE...FROM, which are still not using the query cache if they
have at least one parameter (because then the expanded query contains
names of user variables, and user variables don't work with the
query cache, even in non-prepared queries).
Note that results from prepared SELECTs, which are in the binary
protocol, and results from normal SELECTs, which are in the text
protocol, ignore each other in the query cache, because a result in the
binary protocol should never be served to a SELECT expecting the text
protocol and vice-versa.
Note, after this patch, bug 25843 starts applying to query cache
("changing default database between PREPARE and EXECUTE of statement
breaks binlog"), we need to fix it.
2007-03-09 18:09:57 +01:00
|
|
|
|
|
|
|
# (*) Why we disable the ps protocol: because in normal protocol,
|
|
|
|
# a SELECT failing due to insufficient privileges increments
|
|
|
|
# Qcache_not_cached, while in ps-protocol, no.
|
|
|
|
# In detail: in normal protocol,
|
|
|
|
# the "access denied" errors on SELECT are issued at (stack trace):
|
|
|
|
# mysql_parse/mysql_execute_command/execute_sqlcom_select/handle_select/
|
|
|
|
# mysql_select/JOIN::prepare/setup_wild/insert_fields/
|
|
|
|
# check_grant_all_columns/my_error/my_message_sql, which then calls
|
|
|
|
# push_warning/query_cache_abort: at this moment,
|
|
|
|
# query_cache_store_query() has been called, so query exists in cache,
|
|
|
|
# so thd->net.query_cache_query!=NULL, so query_cache_abort() removes
|
|
|
|
# the query from cache, which causes a query_cache.refused++ (thus,
|
|
|
|
# a Qcache_not_cached++).
|
|
|
|
# While in ps-protocol, the error is issued at prepare time;
|
|
|
|
# for this mysql_test_select() is called, not execute_sqlcom_select()
|
|
|
|
# (and that also leads to JOIN::prepare/etc). Thus, as
|
|
|
|
# query_cache_store_query() has not been called,
|
|
|
|
# thd->net.query_cache_query==NULL, so query_cache_abort() does nothing:
|
|
|
|
# Qcache_not_cached is not incremented.
|
|
|
|
# As this test prints Qcache_not_cached after SELECT failures,
|
|
|
|
# we cannot enable this test in ps-protocol.
|
|
|
|
|
|
|
|
--enable_ps_protocol
|