Skip to content

Commit 361527a

Browse files
committed
WL#7167 - Change DDL to update rows for view columns in DD.COLUMNS and other dependent values.
With WL6599(Integration of IS with New Data Dictionary), INFORMATION_SCHEMA.COLUMNS is implemented as a view on the new data dictionary table mysql.columns. But only column information of tables is stored in the mysql.columns. Hence only columns of tables are listed by the INFORMATION_SCHEMA.COLUMNS table. Even SHOW COLUMNS lists columns of only tables. The main goal of this work log is to support INFORMATION_SCHEMA.COLUMNS and SHOW COLUMNS implementation to list even view columns information. Functional changes introduced: ------------------------------ 1. Now view columns information is stored in the data dictionary table mysql.columns and these rows are updated each time type of the column changes i.e each time when type of columns in the base table changes. With this change INFORMATION_SCHEMA.COLUMNS and SHOW COLUMNS lists columns from the view. 2. If view becomes invalid then correct error warning or error messages are reported. Section A.c of the WL page lists reason for becoming valid or invalid. 3. This work log even takes care of updating mysql.tables.is_updatable, each time when view becomes updatable or non-updatable. With this change, INFORMATION_SCHEMA.VIEWS shows the correct IS_UPDATABLE state of view always. Compatibility issues: ------------------------ The view can become valid or invalid on execution of account management statements too. The error/warning reporting in such case is not handled as part of this WL. It will be handled as part of WL9496. Source files: ---------------- Most of code changes is placed in sql/dd_sql_view.* and sql/dd/dd_view.*. Related worklogs: ------------------ * WL#6599 - New Data Dictionary and I_S integration. This WL defines INFORMATION_SCHEMA (I_S) system view over DD tables, representing a I_S table. WL7167 implemented over the WL6599 changes. So WL#6599 and WL#7167 would be pushed together. They are QA'ed together. Upcoming WLs: ------------------ WL#9496 - Extend view status(valid/invalid) handling to Account Management Statements.
1 parent 0a10fc8 commit 361527a

File tree

342 files changed

+24493
-7154
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

342 files changed

+24493
-7154
lines changed

client/dump/mysql_object_reader.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ void Mysql_object_reader::read_table_rows_task(
9090
"SELECT `COLUMN_NAME`, `EXTRA` FROM " +
9191
this->get_quoted_object_full_name("INFORMATION_SCHEMA", "COLUMNS") +
9292
"WHERE TABLE_SCHEMA ='" + runner->escape_string(table->get_schema()) +
93-
"' AND TABLE_NAME ='" + runner->escape_string(table->get_name()) + "'",
93+
"' AND TABLE_NAME ='" + runner->escape_string(table->get_name()) + "'" +
94+
" ORDER BY ORDINAL_POSITION ",
9495
&columns);
9596

9697
std::string column_names;

client/mysqldump.cc

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1709,6 +1709,40 @@ static int connect_to_db(char *host, char *user,char *passwd)
17091709
if (mysql_query_with_error_report(mysql, 0, buff))
17101710
DBUG_RETURN(1);
17111711
}
1712+
1713+
/*
1714+
With the introduction of new information schema views on top
1715+
of new data dictionary, the way the SHOW command works is
1716+
changed. We now have two ways of SHOW command picking table
1717+
statistics.
1718+
1719+
One is to read it from DD table mysql.table_stats and
1720+
mysql.index_stats. For this to happen, we need to execute
1721+
ANALYZE TABLE prior to execution of mysqldump tool. As the
1722+
tool can run on whole database, we would end-up running
1723+
ANALYZE TABLE for all tables in the database irrespective of
1724+
whether statistics are already present in the statistics
1725+
tables. This could be a time consuming additional step to
1726+
carry.
1727+
1728+
Second option is to read statistics from SE itself. This
1729+
options looks safe and execution of mysqldump tool need not
1730+
care if ANALYZE TABLE command was run on every table. We
1731+
always get the statistics, which match the behavior without
1732+
data dictionary.
1733+
1734+
The first option would be faster as we do not opening the
1735+
underlying tables during execution of SHOW command. However
1736+
the first option might read old statistics, so we feel second
1737+
option is preferred here to get statistics dynamically from
1738+
SE by setting information_schema_stats=latest for this
1739+
session.
1740+
*/
1741+
my_snprintf(buff, sizeof(buff),
1742+
"/*!80000 SET SESSION INFORMATION_SCHEMA_STATS=latest */");
1743+
if (mysql_query_with_error_report(mysql, 0, buff))
1744+
DBUG_RETURN(1);
1745+
17121746
DBUG_RETURN(0);
17131747
} /* connect_to_db */
17141748

@@ -2619,7 +2653,8 @@ static uint get_table_structure(char *table, char *db, char *table_type,
26192653
"`EXTRA` AS `Extra`, "
26202654
"`COLUMN_COMMENT` AS `Comment` "
26212655
"FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE "
2622-
"TABLE_SCHEMA = '%s' AND TABLE_NAME = '%s'";
2656+
"TABLE_SCHEMA = '%s' AND TABLE_NAME = '%s' "
2657+
"ORDER BY ORDINAL_POSITION";
26232658
FILE *sql_file= md_result_file;
26242659
size_t len;
26252660
my_bool is_log_table;

mysql-test/include/commit.inc

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,7 @@ begin
600600
end|
601601
delimiter ;|
602602
--disable_warnings
603-
call p_verify_status_increment(3, 0, 2, 0);
603+
call p_verify_status_increment(4, 0, 2, 0);
604604
--enable_warnings
605605

606606
--echo # 16. A function changes non-trans-table.
@@ -653,7 +653,7 @@ drop table t2;
653653
set sql_mode=no_engine_substitution;
654654
create temporary table t2 (a int);
655655
--disable_warnings
656-
call p_verify_status_increment(5, 0, 0, 0);
656+
call p_verify_status_increment(6, 0, 0, 0);
657657
--enable_warnings
658658
set sql_mode=default;
659659
--echo # 19. A function changes temp-trans-table.
@@ -791,13 +791,13 @@ create table t2 (a int);
791791
# COM_PREPARE.
792792
if (`SELECT $PS_PROTOCOL = 0`)
793793
{
794-
--replace_regex /(call p_verify_status_increment.*)6(.*6)/\1<commit_count>\2/
795-
call p_verify_status_increment(6, 0, 6, 0);
794+
--replace_regex /(call p_verify_status_increment.*)7(.*6)/\1<commit_count>\2/
795+
call p_verify_status_increment(7, 0, 6, 0);
796796
}
797797
if (`SELECT $PS_PROTOCOL > 0`)
798798
{
799-
--replace_regex /(call p_verify_status_increment.*)7(.*6)/\1<commit_count>\2/
800-
call p_verify_status_increment(7, 0, 6, 0);
799+
--replace_regex /(call p_verify_status_increment.*)8(.*6)/\1<commit_count>\2/
800+
call p_verify_status_increment(8, 0, 6, 0);
801801
}
802802
do (select f1() from t1 where a=2);
803803
call p_verify_status_increment(2, 2, 3, 2);
@@ -850,24 +850,24 @@ create table t3 select a from t2;
850850
# COM_PREPARE.
851851
if (`SELECT $PS_PROTOCOL = 0`)
852852
{
853-
--replace_regex /8/<commit_count>/
854-
call p_verify_status_increment(8, 0, 4, 4);
853+
--replace_regex /9/<commit_count>/
854+
call p_verify_status_increment(9, 0, 4, 4);
855855
}
856856
if (`SELECT $PS_PROTOCOL > 0`)
857857
{
858-
--replace_regex /9/<commit_count>/
859-
call p_verify_status_increment(9, 0, 4, 4);
858+
--replace_regex /10/<commit_count>/
859+
call p_verify_status_increment(10, 0, 4, 4);
860860
}
861861
alter table t3 add column (b int);
862862
call p_verify_status_increment(10, 0, 2, 0);
863863
alter table t3 rename t4;
864-
call p_verify_status_increment(5, 0, 3, 0);
864+
call p_verify_status_increment(7, 0, 3, 0);
865865
rename table t4 to t3;
866866
call p_verify_status_increment(7, 0, 5, 0);
867867
truncate table t3;
868868
call p_verify_status_increment(2, 0, 4, 0);
869869
create view v1 as select * from t2;
870-
call p_verify_status_increment(4, 0, 3, 0);
870+
call p_verify_status_increment(5, 0, 3, 0);
871871
check table t1;
872872
call p_verify_status_increment(2, 0, 2, 0);
873873
--echo # Sic: after this bug is fixed, CHECK leaves no pending transaction
@@ -878,7 +878,7 @@ call p_verify_status_increment(6, 0, 6, 0);
878878
commit;
879879
call p_verify_status_increment(0, 0, 0, 0);
880880
drop view v1;
881-
call p_verify_status_increment(5, 0, 3, 0);
881+
call p_verify_status_increment(6, 0, 3, 0);
882882
--enable_warnings
883883

884884
--echo #

mysql-test/include/view_alias.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# The variable $after_select must be set before calling this routine.
44

55
eval CREATE VIEW v1 AS SELECT $after_select;
6-
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'test' AND TABLE_NAME = 'v1';
6+
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'test' AND TABLE_NAME = 'v1' ORDER BY COLUMN_NAME;
77
#
88
# Extract the VIEW's SELECT from INFORMATION_SCHEMA.VIEWS
99
let $query1 = `SELECT VIEW_DEFINITION FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_SCHEMA = 'test' AND TABLE_NAME = 'v1'`;

mysql-test/r/commit_1innodb.result

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,7 @@ begin
570570
insert t2 set a=2;
571571
return 2;
572572
end|
573-
call p_verify_status_increment(3, 0, 2, 0);
573+
call p_verify_status_increment(4, 0, 2, 0);
574574
SUCCESS
575575

576576
# 16. A function changes non-trans-table.
@@ -633,7 +633,7 @@ set sql_mode=no_engine_substitution;
633633
Warnings:
634634
Warning 3090 Changing sql mode 'NO_AUTO_CREATE_USER' is deprecated. It will be removed in a future release.
635635
create temporary table t2 (a int);
636-
call p_verify_status_increment(5, 0, 0, 0);
636+
call p_verify_status_increment(6, 0, 0, 0);
637637
SUCCESS
638638

639639
set sql_mode=default;
@@ -844,22 +844,22 @@ SUCCESS
844844

845845
alter table t3 add column (b int);
846846
call p_verify_status_increment(10, 0, 2, 0);
847-
SUCCESS
848-
847+
ERROR
848+
Expected commit increment: 10 actual: 11
849849
alter table t3 rename t4;
850-
call p_verify_status_increment(5, 0, 3, 0);
850+
call p_verify_status_increment(7, 0, 3, 0);
851851
SUCCESS
852852

853853
rename table t4 to t3;
854854
call p_verify_status_increment(7, 0, 5, 0);
855-
SUCCESS
856-
855+
ERROR
856+
Expected commit increment: 7 actual: 9
857857
truncate table t3;
858858
call p_verify_status_increment(2, 0, 4, 0);
859859
SUCCESS
860860

861861
create view v1 as select * from t2;
862-
call p_verify_status_increment(4, 0, 3, 0);
862+
call p_verify_status_increment(5, 0, 3, 0);
863863
SUCCESS
864864

865865
check table t1;
@@ -886,7 +886,7 @@ call p_verify_status_increment(0, 0, 0, 0);
886886
SUCCESS
887887

888888
drop view v1;
889-
call p_verify_status_increment(5, 0, 3, 0);
889+
call p_verify_status_increment(6, 0, 3, 0);
890890
SUCCESS
891891

892892
#

mysql-test/r/create.result

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -936,7 +936,7 @@ create table t2 select sql_big_result f1,count(f2) from t1 group by f1;
936936
show status like 'handler_read%';
937937
Variable_name Value
938938
Handler_read_first 1
939-
Handler_read_key 10
939+
Handler_read_key 11
940940
Handler_read_last 0
941941
Handler_read_next 2
942942
Handler_read_prev 0
@@ -1056,6 +1056,7 @@ select COLUMN_NAME from information_schema.columns where
10561056
table_schema='test' order by COLUMN_NAME;
10571057
COLUMN_NAME
10581058
имя_поля_в_кодировке_утф8_длиной_больше_чем_45
1059+
имя_поля_в_кодировке_утф8_длиной_больше_чем_45
10591060
select INDEX_NAME from information_schema.statistics where
10601061
table_schema='test' order by INDEX_NAME;
10611062
INDEX_NAME

mysql-test/r/create_ps_protocol.result

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ CREATE TABLE t2 SELECT SQL_BIG_RESULT f1, COUNT(f2) FROM t1 GROUP BY f1;
55
SHOW STATUS LIKE 'handler_read%';
66
Variable_name Value
77
Handler_read_first 1
8-
Handler_read_key 11
8+
Handler_read_key 12
99
Handler_read_last 0
1010
Handler_read_next 2
1111
Handler_read_prev 0

mysql-test/r/ctype_uca.result

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
call mtr.add_suppression("Plugin \'InnoDB\'");
12
DROP TABLE IF EXISTS t1;
23
set names utf8;
34
set collation_connection=utf8_unicode_ci;

mysql-test/r/ctype_ucs.result

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1156,7 +1156,7 @@ set names latin1;
11561156
create table t1(a blob, b text charset utf8, c text charset ucs2);
11571157
select data_type, character_octet_length, character_maximum_length
11581158
from information_schema.columns where table_name='t1';
1159-
data_type character_octet_length character_maximum_length
1159+
DATA_TYPE CHARACTER_OCTET_LENGTH CHARACTER_MAXIMUM_LENGTH
11601160
blob 65535 65535
11611161
text 65535 65535
11621162
text 65535 32767

mysql-test/r/dd_is_compatibility.result

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ tables_priv
6767
# I_S view definitions.
6868
SHOW CREATE TABLE information_schema.tables;
6969
View Create View character_set_client collation_connection
70-
TABLES CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `information_schema`.`TABLES` AS select `cat`.`name` AS `TABLE_CATALOG`,`sch`.`name` AS `TABLE_SCHEMA`,`tbl`.`name` AS `TABLE_NAME`,`tbl`.`type` AS `TABLE_TYPE`,if((`tbl`.`type` = 'VIEW'),NULL,`tbl`.`engine`) AS `ENGINE`,if((`tbl`.`type` = 'VIEW'),NULL,10) AS `VERSION`,`tbl`.`row_format` AS `ROW_FORMAT`,`stat`.`table_rows` AS `TABLE_ROWS`,`stat`.`avg_row_length` AS `AVG_ROW_LENGTH`,`stat`.`data_length` AS `DATA_LENGTH`,`stat`.`max_data_length` AS `MAX_DATA_LENGTH`,`stat`.`index_length` AS `INDEX_LENGTH`,`stat`.`data_free` AS `DATA_FREE`,`stat`.`auto_increment` AS `AUTO_INCREMENT`,`tbl`.`created` AS `CREATE_TIME`,`stat`.`update_time` AS `UPDATE_TIME`,`stat`.`check_time` AS `CHECK_TIME`,`col`.`name` AS `TABLE_COLLATION`,`stat`.`checksum` AS `CHECKSUM`,if((`tbl`.`type` = 'VIEW'),NULL,get_dd_create_options(`tbl`.`options`,if((ifnull(`tbl`.`partition_expression`,'NOT_PART_TBL') = 'NOT_PART_TBL'),0,1))) AS `CREATE_OPTIONS`,if((`tbl`.`type` = 'VIEW'),'VIEW',`tbl`.`comment`) AS `TABLE_COMMENT` from ((((`mysql`.`tables` `tbl` join `mysql`.`schemata` `sch` on((`tbl`.`schema_id` = `sch`.`id`))) join `mysql`.`catalogs` `cat` on((`cat`.`id` = `sch`.`catalog_id`))) left join `mysql`.`collations` `col` on((`tbl`.`collation_id` = `col`.`id`))) left join `mysql`.`table_stats` `stat` on(((`tbl`.`name` = `stat`.`table_name`) and (`sch`.`name` = `stat`.`schema_name`)))) where (can_access_table(`sch`.`name`,`tbl`.`name`) and (not(`tbl`.`hidden`))) utf8 utf8_general_ci
70+
TABLES CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `information_schema`.`TABLES` AS select `cat`.`name` AS `TABLE_CATALOG`,`sch`.`name` AS `TABLE_SCHEMA`,`tbl`.`name` AS `TABLE_NAME`,`tbl`.`type` AS `TABLE_TYPE`,if((`tbl`.`type` = 'BASE TABLE'),`tbl`.`engine`,NULL) AS `ENGINE`,if((`tbl`.`type` = 'VIEW'),NULL,10) AS `VERSION`,`tbl`.`row_format` AS `ROW_FORMAT`,`stat`.`table_rows` AS `TABLE_ROWS`,`stat`.`avg_row_length` AS `AVG_ROW_LENGTH`,`stat`.`data_length` AS `DATA_LENGTH`,`stat`.`max_data_length` AS `MAX_DATA_LENGTH`,`stat`.`index_length` AS `INDEX_LENGTH`,`stat`.`data_free` AS `DATA_FREE`,`stat`.`auto_increment` AS `AUTO_INCREMENT`,`tbl`.`created` AS `CREATE_TIME`,`stat`.`update_time` AS `UPDATE_TIME`,`stat`.`check_time` AS `CHECK_TIME`,`col`.`name` AS `TABLE_COLLATION`,`stat`.`checksum` AS `CHECKSUM`,if((`tbl`.`type` = 'VIEW'),NULL,get_dd_create_options(`tbl`.`options`,if((ifnull(`tbl`.`partition_expression`,'NOT_PART_TBL') = 'NOT_PART_TBL'),0,1))) AS `CREATE_OPTIONS`,internal_get_comment_or_error(`sch`.`name`,`tbl`.`name`,`tbl`.`type`,`tbl`.`options`,`tbl`.`comment`) AS `TABLE_COMMENT` from ((((`mysql`.`tables` `tbl` join `mysql`.`schemata` `sch` on((`tbl`.`schema_id` = `sch`.`id`))) join `mysql`.`catalogs` `cat` on((`cat`.`id` = `sch`.`catalog_id`))) left join `mysql`.`collations` `col` on((`tbl`.`collation_id` = `col`.`id`))) left join `mysql`.`table_stats` `stat` on(((`tbl`.`name` = `stat`.`table_name`) and (`sch`.`name` = `stat`.`schema_name`)))) where (can_access_table(`sch`.`name`,`tbl`.`name`) and (not(`tbl`.`hidden`))) utf8 utf8_general_ci
7171
#########################################################
7272
# Issue WL#6599/HLS/6c): Capital cased I_S table column names.
7373
#########################################################
@@ -222,7 +222,8 @@ count(*) = IF(@@lower_case_table_names = 0, 5, 10)
222222
# lctn=0 will have table_name as utf8_bin, so we do not match
223223
# capital information_schema name.
224224
SELECT COUNT(*)+IF(@@lower_case_table_names=0, 1, 0) FROM
225-
INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='INFORMATION_SCHEMA';
225+
INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='INFORMATION_SCHEMA' AND
226+
TABLE_NAME='TABLES';
226227
COUNT(*)+IF(@@lower_case_table_names=0, 1, 0)
227228
1
228229
#########################################################
@@ -280,7 +281,6 @@ DROP TABLE t1;
280281
#########################################################
281282
CREATE DATABASE test1;
282283
# Following statements should pass as INFORMATION_SCHEMA db is not used.
283-
# Following statements should pass as INFORMATION_SCHEMA db is not used.
284284
DROP DATABASE test1;
285285
########################################################################
286286
# In 5.7 code, MDL lock on the table being created in another session is
@@ -348,3 +348,46 @@ DROP TABLE t1;
348348
DROP TABLE t2;
349349
DROP TABLE t3;
350350
DROP TABLE t4;
351+
#
352+
# 6. Change in view IS_UDPATABLE value in I_S.views.
353+
#
354+
CREATE TABLE t1 (c1 INT(11) DEFAULT NULL, c2 INT(11) DEFAULT NULL);
355+
INSERT INTO t1 VALUES(5, 5);
356+
CREATE VIEW v1 AS SELECT A.c1 AS c1 FROM t1 A
357+
WHERE EXISTS(SELECT B.c2 FROM t1 B WHERE (B.c2 = A.c1));
358+
# View "v1" is non-updatable but "IS_UPDATABLE" column of I_S.views used
359+
# show view as "updatable". Now we get correct value for is_updatable
360+
# column for view "v1".
361+
SELECT table_name, is_updatable FROM INFORMATION_SCHEMA.VIEWS
362+
WHERE table_name = 'v1';
363+
TABLE_NAME IS_UPDATABLE
364+
v1 NO
365+
INSERT INTO v1 VALUES (10);
366+
UPDATE v1 SET c1=25;
367+
ERROR HY000: The target table v1 of the UPDATE is not updatable
368+
DELETE FROM v1;
369+
ERROR HY000: The target table v1 of the DELETE is not updatable
370+
# Cleanup
371+
DROP TABLE t1;
372+
DROP VIEW v1;
373+
########################################################################
374+
# In the 5.7 code while filling schema table "VIEWS", is_updatable column
375+
# of view is evaluated to YES/NO depending on view is mergable and view
376+
# has at least one updatable field in the view.
377+
# Even while creating view and storing values in new DD tables, is_updatable
378+
# value is evaluated but there was no check to find view has at least
379+
# one updatable field. Without this check v1 below was evaluated to
380+
# updatable view instead of non-updatable.
381+
# Added check to find minimum one updatable field in create view code to
382+
# keep the behavior similar to 5.7.
383+
########################################################################
384+
CREATE TABLE t1(f1 int);
385+
CREATE VIEW v1 AS SELECT f1+1 AS a FROM t1;
386+
# With out check for minimum one updatable field, is_updatable
387+
# field for view v1 was evaluated to YES instead of NO here.
388+
SELECT table_name, is_updatable FROM INFORMATION_SCHEMA.VIEWS
389+
WHERE table_schema != 'sys' ORDER BY table_name;
390+
TABLE_NAME IS_UPDATABLE
391+
v1 NO
392+
DROP TABLE t1;
393+
DROP VIEW v1;

0 commit comments

Comments
 (0)