# Result differences depending on FS case sensitivity. if (!$require_case_insensitive_file_system) { --source include/have_case_sensitive_file_system.inc } # --echo ######################################################### --echo # WL#6599: New data dictionary and I_S. --echo # --echo # The re-implemntation of I_S as views on top of DD tables, --echo # together with the modified way of retrieving statistics --echo # information, introduces some differences when comparing --echo # with the previous I_S implementation. The purpose of this --echo # test is to focus on these behavioral differences, both --echo # for the purpose of regression testing, and to document --echo # the changes. The issues below refer to the items listed --echo # in the WL#6599 text (HLS section 6). USE test; --echo ######################################################### --echo # Issue WL#6599/HLS/6a): Analyze table needed in FDS mode. --echo ######################################################### SET information_schema_stats_expiry=default; CREATE TABLE t1 (i INTEGER, KEY cached_key(i)) ENGINE=INNODB STATS_PERSISTENT=0; INSERT INTO t1 VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12), (13), (14), (15), (16), (17), (18), (19); SHOW KEYS FROM t1 WHERE key_name LIKE 'cached%'; ANALYZE TABLE t1; --echo # After ANALYZE, cardinality is correct. SHOW KEYS FROM t1 WHERE key_name LIKE 'cached%'; DROP TABLE t1; SET information_schema_stats_expiry=0; --echo # Getting latest statistics does not need ANALYZE. CREATE TABLE t1 (i INTEGER, KEY latest_key(i)); INSERT INTO t1 VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); --echo # Wait until InnoDB background thread updates the statistics. let $wait_condition = SELECT stat_value = 10 FROM mysql.innodb_index_stats WHERE table_name = 't1' AND index_name = 'latest_key' AND stat_name = 'n_diff_pfx01'; --source include/wait_condition.inc --echo # Cardinality is correct even without ANALYZE. --replace_column 7 # SHOW KEYS FROM t1 WHERE key_name LIKE 'latest%'; DROP TABLE t1; SET information_schema_stats_expiry=default; --echo ######################################################### --echo # Issue WL#6599/HLS/6b): DD tables listed in I_S query output. --echo ######################################################### --echo # The DD table 'mysql.tables' will not be visible. SHOW TABLES in mysql LIKE 'tables'; --echo # But the privilege table 'mysql.tables_priv' will. SHOW TABLES in mysql LIKE '%tables%'; --echo # The DD table 'mysql.tables' will not be visible. SELECT table_name FROM information_schema.tables WHERE TABLE_NAME LIKE 'tables' AND TABLE_SCHEMA LIKE 'mysql' ORDER BY table_name COLLATE utf8_general_ci; --echo # But the privilege table 'mysql.tables_priv' will. SELECT table_name FROM information_schema.tables WHERE TABLE_NAME LIKE '%tables%' AND TABLE_SCHEMA LIKE 'mysql' ORDER BY table_name COLLATE utf8_general_ci; --echo # The DD table 'mysql.tables' will be visible in the --echo # I_S view definitions. SHOW CREATE TABLE information_schema.tables; --echo ######################################################### --echo # Issue WL#6599/HLS/6c): Capital cased I_S table column names. --echo ######################################################### --echo # Default is that column names will be in upper case. SELECT table_name FROM information_schema.tables WHERE table_schema = 'no such schema'; --echo # We can use an alias to get the desired case. SELECT table_name as 'table_name' FROM information_schema.tables WHERE table_schema = 'no such schema'; --echo ######################################################### --echo # Issue WL#6599/HLS/6d): Row order of I_S queries. --echo ######################################################### --echo # Developing such a test would sporadically fail, --echo # Because the order depends on the Btree state at the time we --echo # fetch rows from mysql.tables DD table. --echo ######################################################### --echo # Issue WL#6599/HLS/6e): CREATE_TIME stored in DD table. --echo ######################################################### CREATE TABLE t1 (f1 int); INSERT INTO t1 VALUES (20); --echo # Read create_time without analyze table. SELECT TABLE_NAME, IF(CREATE_TIME IS NULL, 'no create time', 'have create time') FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1'; DROP TABLE t1; --echo ######################################################### --echo # Issue WL#6599/HLS/6g): CREATE TABLE LIKE and HANDLER statements. --echo ######################################################### --echo # HANDLER statemenst on I_S views now return ER_WRONG_OBJECT rather than --echo # ER_WRONG_USAGE. --replace_result columns COLUMNS --error ER_WRONG_OBJECT HANDLER information_schema.COLUMNS OPEN; USE test; --echo # Because the I_S table is a view and not a table, we get this error. --replace_result character_sets CHARACTER_SETS --error ER_WRONG_OBJECT CREATE TABLE t1 LIKE information_schema.CHARACTER_SETS; --echo # An alternative way to to the same is. CREATE TABLE t1 AS SELECT * FROM information_schema.CHARACTER_SETS; SHOW CREATE TABLE t1; DROP TABLE t1; --echo # CREATE TABLE LIKE works for I_S tables that are not system view. CREATE TABLE t1 LIKE information_schema.processlist; SHOW CREATE TABLE t1; DROP TABLE t1; --echo ######################################################### --echo # Issue WL#6599/HLS/6h): I_S schema/table name, --echo # case-sensitivity and l_c_t_n. --echo ######################################################### --echo # 1. The column headings are now in upper case. SELECT table_name FROM information_schema.tables WHERE table_name LIKE 'no_such_table'; SELECT table_name AS 'table_name' FROM information_schema.tables WHERE table_name LIKE 'no_such_table'; --echo # 2. The view names in I_S.tables are in upper case. CREATE VIEW v1 AS SELECT table_name FROM information_schema.tables WHERE table_schema LIKE 'information_schema' AND table_name NOT LIKE 'INNODB%' AND table_name NOT LIKE 'ndb%' ORDER BY table_name COLLATE UTF8_GENERAL_CI; SELECT * FROM v1; DROP VIEW v1; --echo # 3. I_S tables/views/columns are not case sensitive, but on trunk, the --echo # two statements below will have different case of the column heading. SELECT table_name FROM information_schema.tables WHERE table_name LIKE 'no_such_table'; SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE 'no_such_table'; --echo # 4. Names collate differently. On trunk, the queries below returns --echo # the same result set. SELECT count(*) = IF(@@lower_case_table_names = 0, 4, 9) FROM information_schema.tables WHERE table_name LIKE 'TAB%'; SELECT count(*) = IF(@@lower_case_table_names = 0, 5, 9) FROM information_schema.tables WHERE table_name LIKE 'tab%'; --echo # This is because the collation of the column is different. On trunk, --echo # it is utf8_general_ci. With the global DD, it is the collation of the --echo # underlying column, which depends on l_c_t_n. For l_c_t_n == 0, this --echo # is utf8_bin. --echo ######################################################### --echo # Issue WL#6599/HLS/6i): I_S schema/table name in WHERE clause should --echo # collate like mysql.tables.name. --echo ######################################################### --echo # lctn=0 will have table_name as utf8_bin, so we do not match --echo # capital information_schema name. SELECT COUNT(*)+IF(@@lower_case_table_names=0, 1, 0) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='INFORMATION_SCHEMA' AND TABLE_NAME='TABLES'; --echo ######################################################### --echo # WL#6599 HLS/6j --echo # Prepared statements of SHOW commands fail differently for e.g. --echo # ER_BAD_DB_ERROR unknown schema, instead of ER_TOO_BIG_SELECT for --echo # big SELECT's. This is consequence of we checking for existing --echo # database first and then JOIN::optimize(). In 5.7 this was done in --echo # the other way. For details we can see commit id --echo # fb7f9ff0a3b6cafa88f6123875415a660eda15a7 by Abhishek. on --echo # mysql-trunk-wl6599 --echo ######################################################### SET @old_join_size= @@session.max_join_size; SET @@session.max_join_size= 1; PREPARE ps1 FROM 'SHOW TABLES FROM no_such_schema'; PREPARE ps2 FROM 'SHOW TABLES FROM mysql LIKE \'%tables%\''; --error ER_BAD_DB_ERROR EXECUTE ps1; --error ER_TOO_BIG_SELECT EXECUTE ps2; DEALLOCATE PREPARE ps1; DEALLOCATE PREPARE ps2; SET @@session.max_join_size= @old_join_size; --echo ######################################################### --echo # WL#6599 HLS/6k --echo # ANALYZE TABLE under innodb read only mode fails with --echo # error/warning. This would be a restrictions with wl6599. It is --echo # recommended to use 'information_schema_stats_expiry=0' to get latest --echo # statistics from IS queries in read only mode. --echo ######################################################### use test; CREATE TABLE t1(a INT PRIMARY KEY) ENGINE=InnoDB; INSERT INTO t1 VALUES(1); call mtr.add_suppression('Skipped updating resource group metadata in InnoDB read only mode.'); #--source include/restart_innodb_read_only.inc ANALYZE TABLE t1; let $restart_parameters = restart; --source include/restart_mysqld.inc DROP TABLE t1; --echo ######################################################### --echo # WL#6599 HLS/6l --echo # Most of the INFORMATION_SCHEMA table are re-implemented as view as --echo # WL#6599. Current method of dumping INFORMATION_SCHEMA does not work --echo # for views. --echo # OTOH, INFORMATION_SCHEMA DB content dump is only used to reload the --echo # data into another tables for analysis purpose. This feature is not the --echo # core responsibility of mysqlpump tool. INFORMATION_SCHEMA DB --echo # content can be dumped using other methods like SELECT INTO OUTFILE ... --echo # for such purpose. Hence ignoring INFORMATION_SCHEMA DB dump from --echo # mysqldump and mysqlpump tool. --echo ######################################################### CREATE DATABASE test1; --error 1 --exec $MYSQL_DUMP --compact --opt -d INFORMATION_SCHEMA TABLES --error 1 --exec $MYSQL_DUMP --compact --opt -d INFORMATION_SCHEMA --error 1 --exec $MYSQL_DUMP --compact --opt -d --databases INFORMATION_SCHEMA test1 --error 1 --exec $MYSQL_DUMP --compact --opt -d --databases INFORMATION_SCHEMA --echo # Following statements should pass as INFORMATION_SCHEMA db is not used. --exec $MYSQL_DUMP --compact --opt -d --databases test1 >$MYSQLTEST_VARDIR/tmp/dump.sql --exec $MYSQL_DUMP --compact --opt -d test1 >$MYSQLTEST_VARDIR/tmp/dump.sql DROP DATABASE test1; --remove_file $MYSQLTEST_VARDIR/tmp/dump.sql --echo ######################################################################## --echo # In 5.7 code, MDL lock on the table being created in another session is --echo # acquired by operation on INFORMATION_SCHMEA tables. --echo # Since INFORMATION_SCHEMA views reads committed tables information from --echo # new data dictionary, table being created in another session(uncommitted) --echo # is not visible and no MDL is acquired on it. --echo ######################################################################## --enable_connect_log CREATE TABLE t1 (f1 INT); LOCK TABLE t1 write; connect (con1,localhost,root,,test,,); --send CREATE TABLE t2 AS SELECT * FROM t1; connect (con2,localhost,root,,test,,); --echo # Waiting until CREATE TABLE ... SELECT ... is blocked. let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "CREATE TABLE t2 AS SELECT * FROM t1"; --source include/wait_condition.inc --echo # In 5.7 code, following select is expected to wait for MDL lock on --echo # table t2. --echo # But no MDL lock is acquired on table being created by another --echo # session(uncommited) with the INFORMATION_SCHEMA views on the --echo # new data dictionary tables. SELECT table_name, table_type, auto_increment, table_comment FROM information_schema.tables WHERE table_schema='test' and table_name='t2'; connection default; UNLOCK TABLES; connection con1; --reap DROP TABLE t1, t2; # cleanup connection default; disconnect con1; disconnect con2; --disable_connect_log --echo # --echo # 6. Change in view IS_UDPATABLE value in I_S.views. --echo # CREATE TABLE t1 (c1 INT(11) DEFAULT NULL, c2 INT(11) DEFAULT NULL); INSERT INTO t1 VALUES(5, 5); CREATE VIEW v1 AS SELECT A.c1 AS c1 FROM t1 A WHERE EXISTS(SELECT B.c2 FROM t1 B WHERE (B.c2 = A.c1)); --echo # View "v1" is non-updatable but "IS_UPDATABLE" column of I_S.views used --echo # show view as "updatable". Now we get correct value for is_updatable --echo # column for view "v1". SELECT table_name, is_updatable FROM INFORMATION_SCHEMA.VIEWS WHERE table_name = 'v1'; INSERT INTO v1 VALUES (10); --error ER_NON_UPDATABLE_TABLE UPDATE v1 SET c1=25; --error ER_NON_UPDATABLE_TABLE DELETE FROM v1; --echo # Cleanup DROP TABLE t1; DROP VIEW v1; --echo ######################################################################## --echo # In the 5.7 code while filling schema table "VIEWS", is_updatable column --echo # of view is evaluated to YES/NO depending on view is mergable and view --echo # has at least one updatable field in the view. --echo # Even while creating view and storing values in new DD tables, is_updatable --echo # value is evaluated but there was no check to find view has at least --echo # one updatable field. Without this check v1 below was evaluated to --echo # updatable view instead of non-updatable. --echo # Added check to find minimum one updatable field in create view code to --echo # keep the behavior similar to 5.7. --echo ######################################################################## CREATE TABLE t1(f1 int); CREATE VIEW v1 AS SELECT f1+1 AS a FROM t1; --echo # With out check for minimum one updatable field, is_updatable --echo # field for view v1 was evaluated to YES instead of NO here. SELECT table_name, is_updatable FROM INFORMATION_SCHEMA.VIEWS WHERE table_schema != 'sys' ORDER BY table_name; DROP TABLE t1; DROP VIEW v1;