diff options
author | Sergei Golubchik <serg@mariadb.org> | 2019-03-10 23:59:50 +0100 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2019-03-12 13:10:49 +0100 |
commit | a62e9a83c04738009918ae63da41c9bea7ab941e (patch) | |
tree | 16b9b101d29ae755e159bf024e53a8a1d73d250f | |
parent | 22f1cf9292f859f2f59208f267917481b29d4739 (diff) | |
download | mariadb-git-a62e9a83c04738009918ae63da41c9bea7ab941e.tar.gz |
MDEV-15945 --ps-protocol does not test some queries
Make mysqltest to use --ps-protocol more
use prepared statements for everything that server supports
with the exception of CALL (for now).
Fix discovered test failures and bugs.
tests:
* PROCESSLIST shows Execute state, not Query
* SHOW STATUS increments status variables more than in text protocol
* multi-statements should be avoided (see tests with a wrong delimiter)
* performance_schema events have different names in --ps-protocol
* --enable_prepare_warnings
mysqltest.cc:
* make sure run_query_stmt() doesn't crash if there's
no active connection (in wait_until_connected_again.inc)
* prepare all statements that server supports
protocol.h
* Protocol_discard::send_result_set_metadata() should not send
anything to the client.
sql_acl.cc:
* extract the functionality of getting the user for SHOW GRANTS
from check_show_access(), so that mysql_test_show_grants() could
generate the correct column names in the prepare step
sql_class.cc:
* result->prepare() can fail, don't ignore its return value
* use correct number of decimals for EXPLAIN columns
sql_parse.cc:
* discard profiling for SHOW PROFILE. In text protocol it's done in
prepare_schema_table(), but in --ps it is called on prepare only,
so nothing was discarding profiling during execute.
* move the permission checking code for SHOW CREATE VIEW to
mysqld_show_create_get_fields(), so that it would be called during
prepare step too.
* only set sel_result when it was created here and needs to be
destroyed in the same block. Avoid destroying lex->result.
* use the correct number of tables in check_show_access(). Saying
"as many as possible" doesn't work when first_not_own_table isn't
set yet.
sql_prepare.cc:
* use correct user name for SHOW GRANTS columns
* don't ignore verbose flag for SHOW SLAVE STATUS
* support preparing REVOKE ALL and ROLLBACK TO SAVEPOINT
* don't ignore errors from thd->prepare_explain_fields()
* use select_send result for sending ANALYZE and EXPLAIN, but don't
overwrite lex->result, because it might be needed to issue execute-time
errors (select_dumpvar - too many rows)
sql_show.cc:
* check grants for SHOW CREATE VIEW here, not in mysql_execute_command
sql_view.cc:
* use the correct function to check privileges. Old code was doing
check_access() for thd->security_ctx, which is invoker's sctx,
not definer's sctx. Hide various view related errors from the invoker.
sql_yacc.yy:
* initialize lex->select_lex for LOAD, otherwise it'll contain garbage
data that happen to fail tests with views in --ps (but not otherwise).
38 files changed, 305 insertions, 177 deletions
diff --git a/client/mysqltest.cc b/client/mysqltest.cc index b2a63287709..cc1d61e5d79 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -8219,6 +8219,12 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, DBUG_ENTER("run_query_stmt"); DBUG_PRINT("query", ("'%-.60s'", query)); + if (!mysql) + { + handle_no_active_connection(command, cn, ds); + DBUG_VOID_RETURN; + } + /* Init a new stmt if it's not already one created for this connection */ @@ -8744,18 +8750,56 @@ void init_re(void) */ const char *ps_re_str = "^(" - "[[:space:]]*REPLACE[[:space:]]|" - "[[:space:]]*INSERT[[:space:]]|" - "[[:space:]]*UPDATE[[:space:]]|" - "[[:space:]]*DELETE[[:space:]]|" - "[[:space:]]*SELECT[[:space:]]|" + "[[:space:]]*ALTER[[:space:]]+SEQUENCE[[:space:]]|" + "[[:space:]]*ALTER[[:space:]]+TABLE[[:space:]]|" + "[[:space:]]*ALTER[[:space:]]+USER[[:space:]]|" + "[[:space:]]*ANALYZE[[:space:]]|" + "[[:space:]]*ASSIGN[[:space:]]|" + //"[[:space:]]*CALL[[:space:]]|" // XXX run_query_stmt doesn't read multiple result sets + "[[:space:]]*CHANGE[[:space:]]|" + "[[:space:]]*CHECKSUM[[:space:]]|" + "[[:space:]]*COMMIT[[:space:]]|" + "[[:space:]]*COMPOUND[[:space:]]|" + "[[:space:]]*CREATE[[:space:]]+DATABASE[[:space:]]|" + "[[:space:]]*CREATE[[:space:]]+INDEX[[:space:]]|" + "[[:space:]]*CREATE[[:space:]]+ROLE[[:space:]]|" + "[[:space:]]*CREATE[[:space:]]+SEQUENCE[[:space:]]|" "[[:space:]]*CREATE[[:space:]]+TABLE[[:space:]]|" + "[[:space:]]*CREATE[[:space:]]+USER[[:space:]]|" + "[[:space:]]*CREATE[[:space:]]+VIEW[[:space:]]|" + "[[:space:]]*DELETE[[:space:]]|" "[[:space:]]*DO[[:space:]]|" + "[[:space:]]*DROP[[:space:]]+DATABASE[[:space:]]|" + "[[:space:]]*DROP[[:space:]]+INDEX[[:space:]]|" + "[[:space:]]*DROP[[:space:]]+ROLE[[:space:]]|" + "[[:space:]]*DROP[[:space:]]+SEQUENCE[[:space:]]|" + "[[:space:]]*DROP[[:space:]]+TABLE[[:space:]]|" + "[[:space:]]*DROP[[:space:]]+USER[[:space:]]|" + "[[:space:]]*DROP[[:space:]]+VIEW[[:space:]]|" + "[[:space:]]*FLUSH[[:space:]]|" + "[[:space:]]*GRANT[[:space:]]|" "[[:space:]]*HANDLER[[:space:]]+.*[[:space:]]+READ[[:space:]]|" + "[[:space:]]*INSERT[[:space:]]|" + "[[:space:]]*INSTALL[[:space:]]+|" + "[[:space:]]*KILL[[:space:]]|" + "[[:space:]]*OPTIMIZE[[:space:]]|" + "[[:space:]]*PRELOAD[[:space:]]|" + "[[:space:]]*RENAME[[:space:]]+TABLE[[:space:]]|" + "[[:space:]]*RENAME[[:space:]]+USER[[:space:]]|" + "[[:space:]]*REPAIR[[:space:]]|" + "[[:space:]]*REPLACE[[:space:]]|" + "[[:space:]]*RESET[[:space:]]|" + "[[:space:]]*REVOKE[[:space:]]|" + "[[:space:]]*ROLLBACK[[:space:]]|" + "[[:space:]]*SELECT[[:space:]]|" "[[:space:]]*SET[[:space:]]+OPTION[[:space:]]|" - "[[:space:]]*DELETE[[:space:]]+MULTI[[:space:]]|" - "[[:space:]]*UPDATE[[:space:]]+MULTI[[:space:]]|" - "[[:space:]]*INSERT[[:space:]]+SELECT[[:space:]])"; + "[[:space:]]*SHOW[[:space:]]|" + "[[:space:]]*SHUTDOWN[[:space:]]|" + "[[:space:]]*SLAVE[[:space:]]|" + "[[:space:]]*TRUNCATE[[:space:]]|" + "[[:space:]]*UNINSTALL[[:space:]]+|" + "[[:space:]]*UPDATE[[:space:]]" + ")"; /* Filter for queries that can be run using the diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index d2b3d06b2f2..6cea712e482 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -1318,7 +1318,7 @@ partition p2 values in (1)); end// call p()// drop procedure p// -drop table t1; +drop table t1// create procedure p () begin create table t1 (a int not null,b int not null,c int not null,primary key (a,b)) diff --git a/mysql-test/r/sp-ucs2.result b/mysql-test/r/sp-ucs2.result index 3c444ad97de..48381819313 100644 --- a/mysql-test/r/sp-ucs2.result +++ b/mysql-test/r/sp-ucs2.result @@ -32,61 +32,55 @@ RETURNS VARCHAR(64) UNICODE BINARY BEGIN RETURN ''; END| -SHOW CREATE FUNCTION f; -DROP FUNCTION f; +SHOW CREATE FUNCTION f| +Function sql_mode Create Function character_set_client collation_connection Database Collation +f NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` FUNCTION `f`() RETURNS varchar(64) CHARSET ucs2 COLLATE ucs2_bin +BEGIN +RETURN ''; +END latin1 latin1_swedish_ci latin1_swedish_ci +DROP FUNCTION f| CREATE FUNCTION f() RETURNS VARCHAR(64) BINARY UNICODE BEGIN RETURN ''; END| +SHOW CREATE FUNCTION f| Function sql_mode Create Function character_set_client collation_connection Database Collation f NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` FUNCTION `f`() RETURNS varchar(64) CHARSET ucs2 COLLATE ucs2_bin BEGIN RETURN ''; END latin1 latin1_swedish_ci latin1_swedish_ci -SHOW CREATE FUNCTION f; -DROP FUNCTION f; -# -# Testing keywords ASCII + BINARY -# +DROP FUNCTION f| CREATE FUNCTION f() RETURNS VARCHAR(64) ASCII BINARY BEGIN RETURN ''; END| +SHOW CREATE FUNCTION f| Function sql_mode Create Function character_set_client collation_connection Database Collation -f NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` FUNCTION `f`() RETURNS varchar(64) CHARSET ucs2 COLLATE ucs2_bin +f NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` FUNCTION `f`() RETURNS varchar(64) CHARSET latin1 COLLATE latin1_bin BEGIN RETURN ''; END latin1 latin1_swedish_ci latin1_swedish_ci -SHOW CREATE FUNCTION f; -DROP FUNCTION f; +DROP FUNCTION f| CREATE FUNCTION f() RETURNS VARCHAR(64) BINARY ASCII BEGIN RETURN ''; END| +SHOW CREATE FUNCTION f| Function sql_mode Create Function character_set_client collation_connection Database Collation f NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` FUNCTION `f`() RETURNS varchar(64) CHARSET latin1 COLLATE latin1_bin BEGIN RETURN ''; END latin1 latin1_swedish_ci latin1_swedish_ci -SHOW CREATE FUNCTION f; -DROP FUNCTION f; -# -# Testing COLLATE in OUT parameter -# +DROP FUNCTION f| CREATE PROCEDURE p1(IN f1 VARCHAR(64) CHARACTER SET ucs2 COLLATE ucs2_czech_ci, OUT f2 VARCHAR(64) CHARACTER SET ucs2 COLLATE ucs2_polish_ci) BEGIN SET f2= f1; SET f2= concat(collation(f1), ' ', collation(f2)); END| -Function sql_mode Create Function character_set_client collation_connection Database Collation -f NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` FUNCTION `f`() RETURNS varchar(64) CHARSET latin1 COLLATE latin1_bin -BEGIN -RETURN ''; -END latin1 latin1_swedish_ci latin1_swedish_ci CREATE FUNCTION f1() RETURNS VARCHAR(64) CHARACTER SET ucs2 BEGIN diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 1cd01711ce8..cd818ed22b8 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -6790,7 +6790,7 @@ ERROR 42S02: Table 'test.t1' doesn't exist create table t1 (a integer)$ call p1$ a -alter table t1 add b integer; +alter table t1 add b integer$ call p1$ a drop table t1; diff --git a/mysql-test/r/sp_notembedded.result b/mysql-test/r/sp_notembedded.result index 712f299014c..02ae3731d94 100644 --- a/mysql-test/r/sp_notembedded.result +++ b/mysql-test/r/sp_notembedded.result @@ -72,7 +72,7 @@ select res; end| create table t3 (a int)| insert into t3 values (0)| -create view v1 as select a from t3; +create view v1 as select a from t3| create procedure bug10100pt(level int, lim int) begin if level < lim then diff --git a/mysql-test/r/sp_trans.result b/mysql-test/r/sp_trans.result index c76615d644f..87339816bc2 100644 --- a/mysql-test/r/sp_trans.result +++ b/mysql-test/r/sp_trans.result @@ -640,7 +640,7 @@ TRUNCATE TABLE t1; END| LOCK TABLES t1 WRITE| CALL p1()| -FLUSH TABLES; +FLUSH TABLES| UNLOCK TABLES| CALL p1()| DROP PROCEDURE p1| diff --git a/mysql-test/r/userstat.result b/mysql-test/r/userstat.result index 66bb4516c85..f6f7e0fdcf8 100644 --- a/mysql-test/r/userstat.result +++ b/mysql-test/r/userstat.result @@ -142,7 +142,7 @@ show table_statistics; Table_schema Table_name Rows_read Rows_changed Rows_changed_x_#indexes show index_statistics; Table_schema Table_name Index_name Rows_read -select TOTAL_CONNECTIONS, TOTAL_SSL_CONNECTIONS, CONCURRENT_CONNECTIONS, ROWS_READ, ROWS_SENT, ROWS_DELETED, ROWS_INSERTED, ROWS_UPDATED, SELECT_COMMANDS, UPDATE_COMMANDS, OTHER_COMMANDS, COMMIT_TRANSACTIONS, ROLLBACK_TRANSACTIONS, DENIED_CONNECTIONS, LOST_CONNECTIONS, ACCESS_DENIED, EMPTY_QUERIES from information_schema.client_statistics;; +select TOTAL_CONNECTIONS, TOTAL_SSL_CONNECTIONS, CONCURRENT_CONNECTIONS, ROWS_READ, ROWS_SENT, ROWS_DELETED, ROWS_INSERTED, ROWS_UPDATED, SELECT_COMMANDS, UPDATE_COMMANDS, COMMIT_TRANSACTIONS, ROLLBACK_TRANSACTIONS, DENIED_CONNECTIONS, LOST_CONNECTIONS, ACCESS_DENIED, EMPTY_QUERIES from information_schema.client_statistics;; TOTAL_CONNECTIONS 2 TOTAL_SSL_CONNECTIONS 1 CONCURRENT_CONNECTIONS 0 @@ -153,14 +153,13 @@ ROWS_INSERTED 7 ROWS_UPDATED 5 SELECT_COMMANDS 4 UPDATE_COMMANDS 11 -OTHER_COMMANDS 7 COMMIT_TRANSACTIONS 19 ROLLBACK_TRANSACTIONS 2 DENIED_CONNECTIONS 0 LOST_CONNECTIONS 0 ACCESS_DENIED 0 EMPTY_QUERIES 1 -select TOTAL_CONNECTIONS, TOTAL_SSL_CONNECTIONS, CONCURRENT_CONNECTIONS, ROWS_READ, ROWS_SENT, ROWS_DELETED, ROWS_INSERTED, ROWS_UPDATED, SELECT_COMMANDS, UPDATE_COMMANDS, OTHER_COMMANDS, COMMIT_TRANSACTIONS, ROLLBACK_TRANSACTIONS, DENIED_CONNECTIONS, LOST_CONNECTIONS, ACCESS_DENIED, EMPTY_QUERIES from information_schema.user_statistics;; +select TOTAL_CONNECTIONS, TOTAL_SSL_CONNECTIONS, CONCURRENT_CONNECTIONS, ROWS_READ, ROWS_SENT, ROWS_DELETED, ROWS_INSERTED, ROWS_UPDATED, SELECT_COMMANDS, UPDATE_COMMANDS, COMMIT_TRANSACTIONS, ROLLBACK_TRANSACTIONS, DENIED_CONNECTIONS, LOST_CONNECTIONS, ACCESS_DENIED, EMPTY_QUERIES from information_schema.user_statistics;; TOTAL_CONNECTIONS 2 TOTAL_SSL_CONNECTIONS 1 CONCURRENT_CONNECTIONS 0 @@ -171,13 +170,18 @@ ROWS_INSERTED 7 ROWS_UPDATED 5 SELECT_COMMANDS 4 UPDATE_COMMANDS 11 -OTHER_COMMANDS 7 COMMIT_TRANSACTIONS 19 ROLLBACK_TRANSACTIONS 2 DENIED_CONNECTIONS 0 LOST_CONNECTIONS 0 ACCESS_DENIED 0 EMPTY_QUERIES 1 +select OTHER_COMMANDS IN (7,8) from information_schema.client_statistics; +OTHER_COMMANDS IN (7,8) +1 +select OTHER_COMMANDS IN (7,8) from information_schema.user_statistics; +OTHER_COMMANDS IN (7,8) +1 flush table_statistics; flush index_statistics; select * from information_schema.index_statistics; diff --git a/mysql-test/suite/funcs_1/datadict/processlist_priv.inc b/mysql-test/suite/funcs_1/datadict/processlist_priv.inc index cd060e7a370..a2e701cc5fa 100644 --- a/mysql-test/suite/funcs_1/datadict/processlist_priv.inc +++ b/mysql-test/suite/funcs_1/datadict/processlist_priv.inc @@ -156,6 +156,7 @@ WHERE DB = 'information_schema' AND COMMAND = 'Sleep' AND USER = 'ddicttestuser1 --source include/wait_condition.inc --replace_result ENGINE=MyISAM "" ENGINE=Aria "" " PAGE_CHECKSUM=1" "" " PAGE_CHECKSUM=0" "" eval SHOW CREATE TABLE $table; +--replace_result Execute Query --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS eval SHOW $table; --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS 15 QUERY_ID 17 TID @@ -176,6 +177,7 @@ connection con100; # but "ddicttestuser1" must not see anything of the root session. --replace_result ENGINE=MyISAM "" ENGINE=Aria "" " PAGE_CHECKSUM=1" "" " PAGE_CHECKSUM=0" "" eval SHOW CREATE TABLE $table; +--replace_result Execute Query --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS eval SHOW $table; --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS 15 QUERY_ID 17 TID @@ -202,6 +204,7 @@ GRANT PROCESS ON *.* TO ddicttestuser1@'localhost' IDENTIFIED BY 'ddictpass'; --echo #################################################################################### connection con100; SHOW GRANTS; +--replace_result Execute Query --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS SHOW processlist; --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS 15 QUERY_ID 17 TID @@ -214,6 +217,7 @@ SELECT * FROM information_schema.processlist; --echo #################################################################################### connect (con101,localhost,ddicttestuser1,ddictpass,information_schema); SHOW GRANTS; +--replace_result Execute Query --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS SHOW processlist; --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS 15 QUERY_ID 17 TID @@ -237,6 +241,7 @@ GRANT PROCESS ON *.* TO ''@'localhost'; --echo #################################################################################### connect (anonymous1,localhost,"''",,information_schema); SHOW GRANTS; +--replace_result Execute Query --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS SHOW processlist; --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS 15 QUERY_ID 17 TID @@ -259,6 +264,7 @@ connect (con102,localhost,ddicttestuser1,ddictpass,information_schema); --echo ddicttestuser1 are visible. --echo #################################################################################### SHOW GRANTS; +--replace_result Execute Query --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS SHOW processlist; --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS 15 QUERY_ID 17 TID @@ -284,6 +290,7 @@ SHOW GRANTS FOR ''@'localhost'; if ($fixed_bug_30395) { # Bug#30395 strange results after REVOKE PROCESS ON *.* FROM ... +--replace_result Execute Query --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS SHOW processlist; } @@ -306,6 +313,7 @@ connect (con103,localhost,ddicttestuser1,ddictpass,information_schema); --echo Only the processes of ddicttestuser1 user are visible. --echo #################################################################################### SHOW GRANTS FOR 'ddicttestuser1'@'localhost'; +--replace_result Execute Query --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS SHOW processlist; --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS 15 QUERY_ID 17 TID @@ -328,6 +336,7 @@ connect (con104,localhost,ddicttestuser1,ddictpass,information_schema); --echo Only the processes of ddicttestuser1 are visible. --echo #################################################################################### SHOW GRANTS FOR 'ddicttestuser1'@'localhost'; +--replace_result Execute Query --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS SHOW processlist; --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS 15 QUERY_ID 17 TID @@ -375,6 +384,7 @@ connect (con200,localhost,ddicttestuser2,ddictpass,information_schema); --echo ddicttestuser2 has now the PROCESS privilege and sees all connections --echo #################################################################################### SHOW GRANTS FOR 'ddicttestuser2'@'localhost'; +--replace_result Execute Query --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS SHOW processlist; --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS 15 QUERY_ID 17 TID @@ -396,6 +406,7 @@ connect (con201,localhost,ddicttestuser2,ddictpass,information_schema); --echo ddicttestuser2 has no more the PROCESS privilege and can only see own connects --echo #################################################################################### SHOW GRANTS; +--replace_result Execute Query --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS SHOW processlist; --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS 15 QUERY_ID 17 TID @@ -419,6 +430,7 @@ connect (con107,localhost,ddicttestuser1,ddictpass,information_schema); SHOW GRANTS FOR 'ddicttestuser1'@'localhost'; --error ER_ACCESS_DENIED_ERROR GRANT PROCESS ON *.* TO 'ddicttestuser2'@'localhost'; +--replace_result Execute Query --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS SHOW processlist; --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS 15 QUERY_ID 17 TID @@ -443,6 +455,7 @@ connect (con108,localhost,ddicttestuser1,ddictpass,information_schema); --echo Therefore the missing SELECT privilege does not affect SELECTs on PROCESSLIST. --echo #################################################################################### SHOW GRANTS FOR 'ddicttestuser1'@'localhost'; +--replace_result Execute Query --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS SHOW processlist; --replace_column 1 ID 3 HOST_NAME 6 TIME 9 TIME_MS 13 MEMORY 14 ROWS 15 QUERY_ID 17 TID diff --git a/mysql-test/suite/funcs_1/datadict/processlist_val.inc b/mysql-test/suite/funcs_1/datadict/processlist_val.inc index 6e76cedde2e..cdc070aff74 100644 --- a/mysql-test/suite/funcs_1/datadict/processlist_val.inc +++ b/mysql-test/suite/funcs_1/datadict/processlist_val.inc @@ -94,6 +94,7 @@ echo # 1. Just dump what we get --replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 9 <TIME_MS> 13 <MEMORY> 14 <ROWS> 15 <QUERY_ID> 17 <TID> SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST; +--replace_result Execute Query --replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 9 <TIME_MS> 13 <MEMORY> 14 <ROWS> SHOW FULL PROCESSLIST; # @@ -167,6 +168,7 @@ let $wait_condition= SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST # 1. Just dump what we get --replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 7 <STATE> 9 <TIME_MS> 13 <MEMORY> 14 <ROWS> 15 <QUERY_ID> 17 <TID> SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST; +--replace_result Execute Query --replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> SHOW FULL PROCESSLIST; # @@ -212,6 +214,7 @@ echo connection con1; --replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 9 <TIME_MS> 13 <MEMORY> 14 <ROWS> 15 <QUERY_ID> 17 <TID> SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST; +--replace_result Execute Query --replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> SHOW FULL PROCESSLIST; @@ -246,6 +249,7 @@ connection con2; # Just dump what we get --replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 9 <TIME_MS> 13 <MEMORY> 14 <ROWS> 15 <QUERY_ID> 17 <TID> SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST; +--replace_result Execute Query --replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> SHOW FULL PROCESSLIST; # @@ -306,6 +310,7 @@ WHERE ID = @test_user_con2_id AND Command IN('Query','Execute') # 1. Just dump what we get --replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> 9 <TIME_MS> 13 <MEMORY> 14 <ROWS> 15 <QUERY_ID> 17 <TID> SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST; +--replace_result Execute Query --replace_column 1 <ID> 3 <HOST_NAME> 6 <TIME> SHOW FULL PROCESSLIST; # @@ -436,8 +441,10 @@ echo ; --replace_column 1 <ID> 3 <HOST_NAME> 5 <COMMAND> 6 <TIME> 7 <STATE> 9 <TIME_MS> 13 <MEMORY> 14 <ROWS> 15 <QUERY_ID> 17 <TID> SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST; +--replace_result Execute Query --replace_column 1 <ID> 3 <HOST_NAME> 5 <COMMAND> 6 <TIME> 7 <STATE> SHOW FULL PROCESSLIST; +--replace_result Execute Query --replace_column 1 <ID> 3 <HOST_NAME> 5 <COMMAND> 6 <TIME> 7 <STATE> SHOW PROCESSLIST; UNLOCK TABLES; diff --git a/mysql-test/suite/handler/ps.test b/mysql-test/suite/handler/ps.test index 68091190c85..783d862435e 100644 --- a/mysql-test/suite/handler/ps.test +++ b/mysql-test/suite/handler/ps.test @@ -7,5 +7,7 @@ flush status; handler handler_a read first; # handler...read must be prepared in --ps-protocol mode --replace_result $PS_PROTOCOL OK +--disable_ps_protocol show status like 'Com_stmt_prepare%'; +--enable_ps_protocol drop table t1; diff --git a/mysql-test/suite/innodb/t/innodb-corrupted-table.test b/mysql-test/suite/innodb/t/innodb-corrupted-table.test index 94c5454429f..c8e17e5b7aa 100644 --- a/mysql-test/suite/innodb/t/innodb-corrupted-table.test +++ b/mysql-test/suite/innodb/t/innodb-corrupted-table.test @@ -34,6 +34,7 @@ alter table t1 add primary key (pk); --enable_reconnect --source include/wait_until_connected_again.inc +--enable_prepare_warnings show create table t1; select * from t1; alter table t1 add j int; diff --git a/mysql-test/suite/sys_vars/t/max_prepared_stmt_count_func.test b/mysql-test/suite/sys_vars/t/max_prepared_stmt_count_func.test index 6617c4ad2ea..c37fc7ab114 100644 --- a/mysql-test/suite/sys_vars/t/max_prepared_stmt_count_func.test +++ b/mysql-test/suite/sys_vars/t/max_prepared_stmt_count_func.test @@ -19,7 +19,7 @@ # option_mysqld_max_prepared_stmt_count # # # ################################################################################ - +--source include/no_protocol.inc --echo ** Setup ** --echo diff --git a/mysql-test/suite/sys_vars/t/sql_buffer_result_func.test b/mysql-test/suite/sys_vars/t/sql_buffer_result_func.test index 4530545b8f0..2a2d7572d91 100644 --- a/mysql-test/suite/sys_vars/t/sql_buffer_result_func.test +++ b/mysql-test/suite/sys_vars/t/sql_buffer_result_func.test @@ -46,17 +46,23 @@ INSERT INTO t1 VALUES('aa','bb'); SET SESSION sql_buffer_result = 1; +--disable_ps_protocol SHOW STATUS LIKE 'Created_tmp_tables'; +--enable_ps_protocol --echo Expected value : 0. SELECT * FROM t1; +--disable_ps_protocol SHOW STATUS LIKE 'Created_tmp_tables'; +--enable_ps_protocol --echo Expected value : 1. SELECT * FROM t1; +--disable_ps_protocol SHOW STATUS LIKE 'Created_tmp_tables'; +--enable_ps_protocol --echo Expected value : 2. --echo '#--------------------FN_DYNVARS_156_02-------------------------#' @@ -66,12 +72,16 @@ SHOW STATUS LIKE 'Created_tmp_tables'; SET SESSION sql_buffer_result = 0; +--disable_ps_protocol SHOW STATUS LIKE 'Created_tmp_tables'; +--enable_ps_protocol --echo Expected value : 2. SELECT * FROM t1; +--disable_ps_protocol SHOW STATUS LIKE 'Created_tmp_tables'; +--enable_ps_protocol --echo Expected value : 2. --echo '#--------------------FN_DYNVARS_156_03-------------------------#' diff --git a/mysql-test/suite/vcol/t/wrong_arena.test b/mysql-test/suite/vcol/t/wrong_arena.test index 484f1fe685d..f3030902784 100644 --- a/mysql-test/suite/vcol/t/wrong_arena.test +++ b/mysql-test/suite/vcol/t/wrong_arena.test @@ -14,7 +14,9 @@ create table t1 (a datetime, # other issues e int as ((a,1) in ((1,1),(2,1),(NULL,1))) # cmp_item_row::alloc_comparators() ); +enable_prepare_warnings; show create table t1; +disable_prepare_warnings; connect con1, localhost, root; insert t1 (a) values ('2010-10-10 10:10:10'); select * from t1; diff --git a/mysql-test/t/kill_processlist-6619.test b/mysql-test/t/kill_processlist-6619.test index 551d36e03fd..533297032e6 100644 --- a/mysql-test/t/kill_processlist-6619.test +++ b/mysql-test/t/kill_processlist-6619.test @@ -7,6 +7,7 @@ --enable_connect_log --connect (con1,localhost,root,,) --let $con_id = `SELECT CONNECTION_ID()` +--replace_result Execute Query --replace_column 1 # 3 # 6 # 7 # SHOW PROCESSLIST; SET DEBUG_SYNC='before_execute_sql_command SIGNAL ready WAIT_FOR go'; @@ -30,5 +31,6 @@ let $wait_condition= WHERE info is NULL; --source include/wait_condition.inc +--replace_result Execute Query --replace_column 1 # 3 # 6 # 7 # SHOW PROCESSLIST; diff --git a/mysql-test/t/log_tables.test b/mysql-test/t/log_tables.test index a4158ba6a24..f822ec8d758 100644 --- a/mysql-test/t/log_tables.test +++ b/mysql-test/t/log_tables.test @@ -855,7 +855,9 @@ SET GLOBAL slow_query_log = @old_slow_query_log; # select CONNECTION_ID() into @thread_id; +--disable_ps_protocol truncate table mysql.general_log; +--enable_ps_protocol set global general_log = on; --disable_result_log set @lparam = "000 001 002 003 004 005 006 007 008 009" diff --git a/mysql-test/t/old-mode.test b/mysql-test/t/old-mode.test index ed33da523c7..d2f628de660 100644 --- a/mysql-test/t/old-mode.test +++ b/mysql-test/t/old-mode.test @@ -22,7 +22,8 @@ drop table t1,t2; --replace_column 1 <Id> 3 <Host> 6 <Time> 7 <State> # Embedded server is hardcoded to show "Writing to net" as STATE. ---replace_result "Writing to net" "NULL" +# ps-protocol will have Execute not Query +--replace_result "Writing to net" "NULL" "Execute" "Query" --replace_regex /localhost[:0-9]*/localhost/ SHOW PROCESSLIST; diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index 3b2445ad83d..0f965cc810a 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -1197,7 +1197,7 @@ end// call p()// drop procedure p// -drop table t1; +drop table t1// create procedure p () begin diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test index d9aed952fce..81ccfd2a05e 100644 --- a/mysql-test/t/show_check.test +++ b/mysql-test/t/show_check.test @@ -47,7 +47,9 @@ insert into t1 values (5,5,5); check table t1 changed; check table t1 medium; check table t1 extended; +--disable_ps_protocol show index from t1; +--enable_ps_protocol --disable_metadata --error ER_DUP_ENTRY insert into t1 values (5,5,5); @@ -72,7 +74,9 @@ drop table t1; show variables like "wait_timeout%"; show variables like "WAIT_timeout%"; show variables like "this_doesn't_exists%"; +--disable_ps_protocol show table status from test like "this_doesn't_exists%"; +--enable_ps_protocol show databases; show databases like "test%"; --disable_metadata @@ -409,7 +413,9 @@ CREATE TABLE t1( PRIMARY KEY(field1(1000)) ); --enable_metadata +--disable_ps_protocol show index from t1; +--enable_ps_protocol --disable_metadata drop table t1; @@ -707,11 +713,15 @@ set names utf8; --echo ---------------------------------------------------------------- +--disable_ps_protocol SHOW CHARACTER SET LIKE 'utf8'; +--enable_ps_protocol --echo ---------------------------------------------------------------- +--disable_ps_protocol SHOW COLLATION LIKE 'latin1_bin'; +--enable_ps_protocol --echo ---------------------------------------------------------------- @@ -727,7 +737,9 @@ SHOW CREATE TABLE t1; --echo ---------------------------------------------------------------- +--disable_ps_protocol SHOW INDEX FROM t1; +--enable_ps_protocol --echo ---------------------------------------------------------------- @@ -774,7 +786,9 @@ SHOW COLUMNS FROM t1; --echo ---------------------------------------------------------------- +--disable_ps_protocol SHOW TRIGGERS LIKE 't1'; +--enable_ps_protocol --echo ---------------------------------------------------------------- @@ -1343,9 +1357,11 @@ let $wait_timeout= 10; let $wait_condition= SELECT COUNT(*) FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO LIKE '%GET_LOCK%' AND ID != CONNECTION_ID(); --source include/wait_condition.inc --replace_column 1 ### 3 ### 6 ### 7 ### +--replace_result "Execute" "Query" SHOW PROCESSLIST; SET NAMES utf8; --replace_column 1 ### 3 ### 6 ### 7 ### +--replace_result "Execute" "Query" SHOW PROCESSLIST; SELECT RELEASE_LOCK('t'); --connection con1 diff --git a/mysql-test/t/sp-ucs2.test b/mysql-test/t/sp-ucs2.test index 3532169e5a1..a1aec8071b4 100644 --- a/mysql-test/t/sp-ucs2.test +++ b/mysql-test/t/sp-ucs2.test @@ -52,16 +52,16 @@ CREATE FUNCTION f() BEGIN RETURN ''; END| -SHOW CREATE FUNCTION f; -DROP FUNCTION f; +SHOW CREATE FUNCTION f| +DROP FUNCTION f| CREATE FUNCTION f() RETURNS VARCHAR(64) BINARY UNICODE BEGIN RETURN ''; END| -SHOW CREATE FUNCTION f; -DROP FUNCTION f; +SHOW CREATE FUNCTION f| +DROP FUNCTION f| # @@ -72,16 +72,16 @@ CREATE FUNCTION f() BEGIN RETURN ''; END| -SHOW CREATE FUNCTION f; -DROP FUNCTION f; +SHOW CREATE FUNCTION f| +DROP FUNCTION f| CREATE FUNCTION f() RETURNS VARCHAR(64) BINARY ASCII BEGIN RETURN ''; END| -SHOW CREATE FUNCTION f; -DROP FUNCTION f; +SHOW CREATE FUNCTION f| +DROP FUNCTION f| # # Testing COLLATE in OUT parameter diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 568c33595c2..a24da76602d 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -8057,7 +8057,7 @@ create procedure p1() begin select * from t1; end$ call p1$ create table t1 (a integer)$ call p1$ -alter table t1 add b integer; +alter table t1 add b integer$ call p1$ delimiter ;$ diff --git a/mysql-test/t/sp_notembedded.test b/mysql-test/t/sp_notembedded.test index d7aaaa4340f..6dd2dbf7e82 100644 --- a/mysql-test/t/sp_notembedded.test +++ b/mysql-test/t/sp_notembedded.test @@ -116,7 +116,7 @@ end| # a procedure which use tables and recursion create table t3 (a int)| insert into t3 values (0)| -create view v1 as select a from t3; +create view v1 as select a from t3| create procedure bug10100pt(level int, lim int) begin if level < lim then diff --git a/mysql-test/t/sp_trans.test b/mysql-test/t/sp_trans.test index a9759b99269..7d6faba9789 100644 --- a/mysql-test/t/sp_trans.test +++ b/mysql-test/t/sp_trans.test @@ -689,7 +689,7 @@ END| LOCK TABLES t1 WRITE| CALL p1()| -FLUSH TABLES; +FLUSH TABLES| UNLOCK TABLES| CALL p1()| diff --git a/mysql-test/t/subselect_sj_mat.test b/mysql-test/t/subselect_sj_mat.test index fd40bee6705..1f514be23d2 100644 --- a/mysql-test/t/subselect_sj_mat.test +++ b/mysql-test/t/subselect_sj_mat.test @@ -1570,7 +1570,9 @@ INSERT INTO t2 values(1),(2); EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT * FROM t2 GROUP BY a HAVING a > 1); flush status; CREATE TABLE t3 SELECT * FROM t1 WHERE a IN (SELECT * FROM t2 GROUP BY a HAVING a > 1); +--disable_ps_protocol SHOW STATUS LIKE 'Created_tmp_tables'; +--enable_ps_protocol DROP TABLE t1,t2,t3; --echo # diff --git a/mysql-test/t/temp_table.test b/mysql-test/t/temp_table.test index 43621cf6ba1..9613a16e6ff 100644 --- a/mysql-test/t/temp_table.test +++ b/mysql-test/t/temp_table.test @@ -114,8 +114,10 @@ CREATE TABLE t1 ( INSERT INTO t1 VALUES ('2002-10-24 14:50:32'),('2002-10-24 14:50:33'),('2002-10-24 14:50:34'),('2002-10-24 14:50:34'),('2002-10-24 14:50:34'),('2002-10-24 14:50:35'),('2002-10-24 14:50:35'),('2002-10-24 14:50:35'),('2002-10-24 14:50:35'),('2002-10-24 14:50:36'),('2002-10-24 14:50:36'),('2002-10-24 14:50:36'),('2002-10-24 14:50:36'),('2002-10-24 14:50:37'),('2002-10-24 14:50:37'),('2002-10-24 14:50:37'),('2002-10-24 14:50:37'),('2002-10-24 14:50:38'),('2002-10-24 14:50:38'),('2002-10-24 14:50:38'),('2002-10-24 14:50:39'),('2002-10-24 14:50:39'),('2002-10-24 14:50:39'),('2002-10-24 14:50:39'),('2002-10-24 14:50:40'),('2002-10-24 14:50:40'),('2002-10-24 14:50:40'); flush status; +--disable_ps_protocol select * from t1 group by d; show status like "created_tmp%tables"; +--enable_ps_protocol drop table t1; # Fix for BUG#8921: Check that temporary table is ingored by view commands. diff --git a/mysql-test/t/tmp_table_count-7586.test b/mysql-test/t/tmp_table_count-7586.test index e7bac127815..8bfb0e7c5cf 100644 --- a/mysql-test/t/tmp_table_count-7586.test +++ b/mysql-test/t/tmp_table_count-7586.test @@ -9,12 +9,16 @@ create view v2 as select a from t2; flush status; select * from v2; +--disable_ps_protocol show status like '%Created_tmp%'; +--enable_ps_protocol explain select * from v2; select * from (select * from t2) T1; +--disable_ps_protocol show status like '%Created_tmp%'; +--enable_ps_protocol explain select * from (select * from t2) T1; diff --git a/mysql-test/t/userstat.test b/mysql-test/t/userstat.test index 9ce3a32c442..547138cfeaa 100644 --- a/mysql-test/t/userstat.test +++ b/mysql-test/t/userstat.test @@ -73,8 +73,11 @@ select * from information_schema.index_statistics; select * from information_schema.table_statistics; show table_statistics; show index_statistics; ---query_vertical select TOTAL_CONNECTIONS, TOTAL_SSL_CONNECTIONS, CONCURRENT_CONNECTIONS, ROWS_READ, ROWS_SENT, ROWS_DELETED, ROWS_INSERTED, ROWS_UPDATED, SELECT_COMMANDS, UPDATE_COMMANDS, OTHER_COMMANDS, COMMIT_TRANSACTIONS, ROLLBACK_TRANSACTIONS, DENIED_CONNECTIONS, LOST_CONNECTIONS, ACCESS_DENIED, EMPTY_QUERIES from information_schema.client_statistics; ---query_vertical select TOTAL_CONNECTIONS, TOTAL_SSL_CONNECTIONS, CONCURRENT_CONNECTIONS, ROWS_READ, ROWS_SENT, ROWS_DELETED, ROWS_INSERTED, ROWS_UPDATED, SELECT_COMMANDS, UPDATE_COMMANDS, OTHER_COMMANDS, COMMIT_TRANSACTIONS, ROLLBACK_TRANSACTIONS, DENIED_CONNECTIONS, LOST_CONNECTIONS, ACCESS_DENIED, EMPTY_QUERIES from information_schema.user_statistics; +--query_vertical select TOTAL_CONNECTIONS, TOTAL_SSL_CONNECTIONS, CONCURRENT_CONNECTIONS, ROWS_READ, ROWS_SENT, ROWS_DELETED, ROWS_INSERTED, ROWS_UPDATED, SELECT_COMMANDS, UPDATE_COMMANDS, COMMIT_TRANSACTIONS, ROLLBACK_TRANSACTIONS, DENIED_CONNECTIONS, LOST_CONNECTIONS, ACCESS_DENIED, EMPTY_QUERIES from information_schema.client_statistics; +--query_vertical select TOTAL_CONNECTIONS, TOTAL_SSL_CONNECTIONS, CONCURRENT_CONNECTIONS, ROWS_READ, ROWS_SENT, ROWS_DELETED, ROWS_INSERTED, ROWS_UPDATED, SELECT_COMMANDS, UPDATE_COMMANDS, COMMIT_TRANSACTIONS, ROLLBACK_TRANSACTIONS, DENIED_CONNECTIONS, LOST_CONNECTIONS, ACCESS_DENIED, EMPTY_QUERIES from information_schema.user_statistics; +# different values in --ps-protocol +select OTHER_COMMANDS IN (7,8) from information_schema.client_statistics; +select OTHER_COMMANDS IN (7,8) from information_schema.user_statistics; flush table_statistics; flush index_statistics; select * from information_schema.index_statistics; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 6ff226d738f..2d1266dd17a 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -2437,6 +2437,7 @@ DROP TABLE t1; # Bug#15943 mysql_next_result hangs on invalid SHOW CREATE VIEW # +--disable_ps_protocol delimiter //; drop table if exists t1; drop view if exists v1; @@ -2447,6 +2448,7 @@ show create view v1; drop view v1; // delimiter ;// +--enable_ps_protocol # @@ -3957,7 +3959,9 @@ CREATE VIEW v1 AS SELECT f1() FROM t1; let $MYSQLD_DATADIR= `SELECT @@datadir`; copy_file std_data/bug48449.frm $MYSQLD_DATADIR/test/v2.frm; +enable_prepare_warnings; SHOW CREATE VIEW v1; +disable_prepare_warnings; DROP VIEW v1,v2; DROP TABLE t1,t2; diff --git a/sql/protocol.h b/sql/protocol.h index 93b8fcbe8ef..2edad5663e8 100644 --- a/sql/protocol.h +++ b/sql/protocol.h @@ -230,13 +230,8 @@ class Protocol_discard : public Protocol_text { public: Protocol_discard(THD *thd_arg) : Protocol_text(thd_arg) {} - virtual bool send_result_set_metadata(List<Item> *list, uint flags) - { - // Don't pas Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF flags - return Protocol_text::send_result_set_metadata(list, 0); - } - bool write() { return 0; } + bool send_result_set_metadata(List<Item> *, uint) { return 0; } bool send_eof(uint, uint) { return 0; } void prepare_for_resend() { IF_DBUG(field_pos= 0,); } diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 6052284428e..9110834b449 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -7776,6 +7776,51 @@ void mysql_show_grants_get_fields(THD *thd, List<Item> *fields, fields->push_back(field, thd->mem_root); } +bool get_show_user(THD *thd, LEX_USER *lex_user, const char **username, + const char **hostname, const char **rolename) +{ + if (lex_user->user.str == current_user.str) + { + *username= thd->security_ctx->priv_user; + *hostname= thd->security_ctx->priv_host; + return 0; + } + if (lex_user->user.str == current_role.str) + { + *rolename= thd->security_ctx->priv_role; + return 0; + } + if (lex_user->user.str == current_user_and_current_role.str) + { + *username= thd->security_ctx->priv_user; + *hostname= thd->security_ctx->priv_host; + *rolename= thd->security_ctx->priv_role; + return 0; + } + + Security_context *sctx= thd->security_ctx; + bool do_check_access; + + if (!(lex_user= get_current_user(thd, lex_user))) + return 1; + + if (lex_user->is_role()) + { + *rolename= lex_user->user.str; + do_check_access= strcmp(*rolename, sctx->priv_role); + } + else + { + *username= lex_user->user.str; + *hostname= lex_user->host.str; + do_check_access= strcmp(*username, sctx->priv_user) || + strcmp(*hostname, sctx->priv_host); + } + + if (do_check_access && check_access(thd, SELECT_ACL, "mysql", 0, 0, 1, 0)) + return 1; + return 0; +} /* SHOW GRANTS; Send grants for a user to the client @@ -7791,9 +7836,9 @@ bool mysql_show_grants(THD *thd, LEX_USER *lex_user) ACL_ROLE *acl_role= NULL; char buff[1024]; Protocol *protocol= thd->protocol; - char *username= NULL; - char *hostname= NULL; - char *rolename= NULL; + const char *username= NULL; + const char *hostname= NULL; + const char *rolename= NULL; DBUG_ENTER("mysql_show_grants"); if (!initialized) @@ -7802,46 +7847,9 @@ bool mysql_show_grants(THD *thd, LEX_USER *lex_user) DBUG_RETURN(TRUE); } - if (lex_user->user.str == current_user.str) - { - username= thd->security_ctx->priv_user; - hostname= thd->security_ctx->priv_host; - } - else if (lex_user->user.str == current_role.str) - { - rolename= thd->security_ctx->priv_role; - } - else if (lex_user->user.str == current_user_and_current_role.str) - { - username= thd->security_ctx->priv_user; - hostname= thd->security_ctx->priv_host; - rolename= thd->security_ctx->priv_role; - } - else - { - Security_context *sctx= thd->security_ctx; - bool do_check_access; - - lex_user= get_current_user(thd, lex_user); - if (!lex_user) - DBUG_RETURN(TRUE); - - if (lex_user->is_role()) - { - rolename= lex_user->user.str; - do_check_access= strcmp(rolename, sctx->priv_role); - } - else - { - username= lex_user->user.str; - hostname= lex_user->host.str; - do_check_access= strcmp(username, sctx->priv_user) || - strcmp(hostname, sctx->priv_host); - } + if (get_show_user(thd, lex_user, &username, &hostname, &rolename)) + DBUG_RETURN(TRUE); - if (do_check_access && check_access(thd, SELECT_ACL, "mysql", 0, 0, 1, 0)) - DBUG_RETURN(TRUE); - } DBUG_ASSERT(rolename || username); List<Item> field_list; diff --git a/sql/sql_acl.h b/sql/sql_acl.h index c2ad9a649e5..fc3fcdc534a 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -241,6 +241,8 @@ ulong get_table_grant(THD *thd, TABLE_LIST *table); ulong get_column_grant(THD *thd, GRANT_INFO *grant, const char *db_name, const char *table_name, const char *field_name); +bool get_show_user(THD *thd, LEX_USER *lex_user, const char **username, + const char **hostname, const char **rolename); void mysql_show_grants_get_fields(THD *thd, List<Item> *fields, const char *name); bool mysql_show_grants(THD *thd, LEX_USER *user); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 628dcee0570..02e76520cb4 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -2405,17 +2405,15 @@ CHANGED_TABLE_LIST* THD::changed_table_dup(const char *key, long key_length) } -void THD::prepare_explain_fields(select_result *result, - List<Item> *field_list, - uint8 explain_flags, - bool is_analyze) +int THD::prepare_explain_fields(select_result *result, List<Item> *field_list, + uint8 explain_flags, bool is_analyze) { if (lex->explain_json) make_explain_json_field_list(*field_list, is_analyze); else make_explain_field_list(*field_list, explain_flags, is_analyze); - result->prepare(*field_list, NULL); + return result->prepare(*field_list, NULL); } @@ -2425,11 +2423,10 @@ int THD::send_explain_fields(select_result *result, { List<Item> field_list; int rc; - prepare_explain_fields(result, &field_list, explain_flags, is_analyze); - rc= result->send_result_set_metadata(field_list, - Protocol::SEND_NUM_ROWS | - Protocol::SEND_EOF); - return(rc); + rc= prepare_explain_fields(result, &field_list, explain_flags, is_analyze) || + result->send_result_set_metadata(field_list, Protocol::SEND_NUM_ROWS | + Protocol::SEND_EOF); + return rc; } @@ -2504,7 +2501,7 @@ void THD::make_explain_field_list(List<Item> &field_list, uint8 explain_flags, if (is_analyze) { field_list.push_back(item= new (mem_root) - Item_float(this, "r_rows", 0.1234, 10, 4), + Item_float(this, "r_rows", 0.1234, 2, 4), mem_root); item->maybe_null=1; } diff --git a/sql/sql_class.h b/sql/sql_class.h index a52367be108..de52cec0f38 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -3331,8 +3331,8 @@ public: void add_changed_table(TABLE *table); void add_changed_table(const char *key, long key_length); CHANGED_TABLE_LIST * changed_table_dup(const char *key, long key_length); - void prepare_explain_fields(select_result *result, List<Item> *field_list, - uint8 explain_flags, bool is_analyze); + int prepare_explain_fields(select_result *result, List<Item> *field_list, + uint8 explain_flags, bool is_analyze); int send_explain_fields(select_result *result, uint8 explain_flags, bool is_analyze); void make_explain_field_list(List<Item> &field_list, uint8 explain_flags, diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 150d13f1360..04ea7dad8bb 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3007,7 +3007,11 @@ mysql_execute_command(THD *thd) if (lex->sql_command == SQLCOM_SELECT) WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_READ); else + { WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW); + if (lex->sql_command == SQLCOM_SHOW_PROFILE) + thd->profiling.discard_current_query(); + } thd->status_var.last_query_cost= 0.0; @@ -3723,49 +3727,6 @@ end_with_restore_list: DBUG_PRINT("debug", ("lex->only_view: %d, table: %s.%s", lex->only_view, first_table->db, first_table->table_name)); - if (lex->only_view) - { - if (check_table_access(thd, SELECT_ACL, first_table, FALSE, 1, FALSE)) - { - DBUG_PRINT("debug", ("check_table_access failed")); - my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0), - "SHOW", thd->security_ctx->priv_user, - thd->security_ctx->host_or_ip, first_table->alias); - goto error; - } - DBUG_PRINT("debug", ("check_table_access succeeded")); - - /* Ignore temporary tables if this is "SHOW CREATE VIEW" */ - first_table->open_type= OT_BASE_ONLY; - - } - else - { - /* - Temporary tables should be opened for SHOW CREATE TABLE, but not - for SHOW CREATE VIEW. - */ - if (open_temporary_tables(thd, all_tables)) - goto error; - - /* - The fact that check_some_access() returned FALSE does not mean that - access is granted. We need to check if first_table->grant.privilege - contains any table-specific privilege. - */ - DBUG_PRINT("debug", ("first_table->grant.privilege: %lx", - first_table->grant.privilege)); - if (check_some_access(thd, SHOW_CREATE_TABLE_ACLS, first_table) || - (first_table->grant.privilege & SHOW_CREATE_TABLE_ACLS) == 0) - { - my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0), - "SHOW", thd->security_ctx->priv_user, - thd->security_ctx->host_or_ip, first_table->alias); - goto error; - } - } - - /* Access is granted. Execute the command. */ res= mysqld_show_create(thd, first_table); break; #endif @@ -4116,7 +4077,7 @@ end_with_restore_list: case SQLCOM_DELETE: { WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_UPDATE_DELETE); - select_result *sel_result=lex->result; + select_result *sel_result= NULL; DBUG_ASSERT(first_table == all_tables && first_table != 0); if (WSREP_CLIENT(thd) && wsrep_sync_wait(thd, WSREP_SYNC_WAIT_BEFORE_UPDATE_DELETE)) @@ -4147,16 +4108,15 @@ end_with_restore_list: } else { - if (!(sel_result= lex->result) && - !(sel_result= new (thd->mem_root) select_send(thd))) - return 1; + if (!lex->result && !(sel_result= new (thd->mem_root) select_send(thd))) + goto error; } } res = mysql_delete(thd, all_tables, select_lex->where, &select_lex->order_list, unit->select_limit_cnt, select_lex->options, - sel_result); + lex->result ? lex->result : sel_result); if (replaced_protocol) { @@ -6517,7 +6477,7 @@ static bool check_show_access(THD *thd, TABLE_LIST *table) Check_grant will grant access if there is any column privileges on all of the tables thanks to the fourth parameter (bool show_table). */ - if (check_grant(thd, SELECT_ACL, dst_table, TRUE, UINT_MAX, FALSE)) + if (check_grant(thd, SELECT_ACL, dst_table, TRUE, 1, FALSE)) return TRUE; /* Access denied */ close_thread_tables(thd); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 89b7e490cb9..9de2f7f34a5 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1883,9 +1883,20 @@ static int mysql_test_show_grants(Prepared_statement *stmt) DBUG_ENTER("mysql_test_show_grants"); THD *thd= stmt->thd; List<Item> fields; + char buff[1024]; + const char *username= NULL, *hostname= NULL, *rolename= NULL; - mysql_show_grants_get_fields(thd, &fields, "Grants for"); - + if (get_show_user(thd, thd->lex->grant_user, &username, &hostname, &rolename)) + DBUG_RETURN(1); + + if (username) + strxmov(buff,"Grants for ",username,"@",hostname, NullS); + else if (rolename) + strxmov(buff,"Grants for ",rolename, NullS); + else + DBUG_RETURN(1); + + mysql_show_grants_get_fields(thd, &fields, buff); DBUG_RETURN(send_stmt_metadata(thd, stmt, &fields)); } #endif /*NO_EMBEDDED_ACCESS_CHECKS*/ @@ -1909,7 +1920,7 @@ static int mysql_test_show_slave_status(Prepared_statement *stmt) THD *thd= stmt->thd; List<Item> fields; - show_master_info_get_fields(thd, &fields, 0, 0); + show_master_info_get_fields(thd, &fields, thd->lex->verbose, 0); DBUG_RETURN(send_stmt_metadata(thd, stmt, &fields)); } @@ -2424,6 +2435,7 @@ static bool check_prepared_statement(Prepared_statement *stmt) case SQLCOM_CREATE_INDEX: case SQLCOM_DROP_INDEX: case SQLCOM_ROLLBACK: + case SQLCOM_ROLLBACK_TO_SAVEPOINT: case SQLCOM_TRUNCATE: case SQLCOM_DROP_VIEW: case SQLCOM_REPAIR: @@ -2452,6 +2464,7 @@ static bool check_prepared_statement(Prepared_statement *stmt) case SQLCOM_GRANT: case SQLCOM_GRANT_ROLE: case SQLCOM_REVOKE: + case SQLCOM_REVOKE_ALL: case SQLCOM_REVOKE_ROLE: case SQLCOM_KILL: case SQLCOM_COMPOUND: @@ -2480,14 +2493,12 @@ static bool check_prepared_statement(Prepared_statement *stmt) { if (lex->describe || lex->analyze_stmt) { - if (!lex->result && - !(lex->result= new (stmt->mem_root) select_send(thd))) - DBUG_RETURN(TRUE); + select_send result(thd); List<Item> field_list; - thd->prepare_explain_fields(lex->result, &field_list, - lex->describe, lex->analyze_stmt); - res= send_prep_stmt(stmt, lex->result->field_count(field_list)) || - lex->result->send_result_set_metadata(field_list, + res= thd->prepare_explain_fields(&result, &field_list, + lex->describe, lex->analyze_stmt) || + send_prep_stmt(stmt, result.field_count(field_list)) || + result.send_result_set_metadata(field_list, Protocol::SEND_EOF); } else diff --git a/sql/sql_show.cc b/sql/sql_show.cc index e0a4fb4ea95..e1c599102c6 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1148,6 +1148,48 @@ mysqld_show_create_get_fields(THD *thd, TABLE_LIST *table_list, DBUG_PRINT("enter",("db: %s table: %s",table_list->db, table_list->table_name)); + if (lex->only_view) + { + if (check_table_access(thd, SELECT_ACL, table_list, FALSE, 1, FALSE)) + { + DBUG_PRINT("debug", ("check_table_access failed")); + my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0), + "SHOW", thd->security_ctx->priv_user, + thd->security_ctx->host_or_ip, table_list->alias); + goto exit; + } + DBUG_PRINT("debug", ("check_table_access succeeded")); + + /* Ignore temporary tables if this is "SHOW CREATE VIEW" */ + table_list->open_type= OT_BASE_ONLY; + } + else + { + /* + Temporary tables should be opened for SHOW CREATE TABLE, but not + for SHOW CREATE VIEW. + */ + if (open_temporary_tables(thd, table_list)) + goto exit; + + /* + The fact that check_some_access() returned FALSE does not mean that + access is granted. We need to check if table_list->grant.privilege + contains any table-specific privilege. + */ + DBUG_PRINT("debug", ("table_list->grant.privilege: %lx", + table_list->grant.privilege)); + if (check_some_access(thd, SHOW_CREATE_TABLE_ACLS, table_list) || + (table_list->grant.privilege & SHOW_CREATE_TABLE_ACLS) == 0) + { + my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0), + "SHOW", thd->security_ctx->priv_user, + thd->security_ctx->host_or_ip, table_list->alias); + goto exit; + } + } + /* Access is granted. Execute the command. */ + /* We want to preserve the tree for views. */ lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW; diff --git a/sql/sql_view.cc b/sql/sql_view.cc index df9fdab6635..8fa03f23ca1 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -330,12 +330,11 @@ bool create_view_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *view, { if (!tbl->table_in_first_from_clause) { - if (check_access(thd, SELECT_ACL, tbl->db, - &tbl->grant.privilege, - &tbl->grant.m_internal, - 0, 0) || - check_grant(thd, SELECT_ACL, tbl, FALSE, 1, FALSE)) + if (check_single_table_access(thd, SELECT_ACL, tbl, FALSE)) + { + tbl->hide_view_error(thd); goto err; + } } } } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index f98a7b7e474..c3a34f23ac9 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -12994,6 +12994,7 @@ load: LOAD data_or_xml { LEX *lex= thd->lex; + mysql_init_select(lex); if (lex->sphead) { |