From 79cc1546b23f757266dc2f4ed67317865c9d0f2f Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 2 May 2006 16:31:39 +0500 Subject: [PATCH] WL#2257 REFERENTIAL_CONSTRAINTS view added I_S.REFARENTIAL_CONSTRAINTS table mysql-test/r/information_schema.result: WL#2257 REFERENTIAL_CONSTRAINTS view result fix mysql-test/r/information_schema_db.result: WL#2257 REFERENTIAL_CONSTRAINTS view result fix mysql-test/r/information_schema_inno.result: WL#2257 REFERENTIAL_CONSTRAINTS view test case mysql-test/t/information_schema_inno.test: WL#2257 REFERENTIAL_CONSTRAINTS view test case sql/ha_innodb.cc: WL#2257 REFERENTIAL_CONSTRAINTS view --- mysql-test/r/information_schema.result | 6 +- mysql-test/r/information_schema_db.result | 1 + mysql-test/r/information_schema_inno.result | 31 ++++++++ mysql-test/t/information_schema_inno.test | 32 ++++++++ sql/ha_innodb.cc | 77 +++++++++++------- sql/sql_show.cc | 88 +++++++++++++++++++++ sql/table.h | 4 +- 7 files changed, 208 insertions(+), 31 deletions(-) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index 5e915b5742c..002e444acca 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -50,6 +50,7 @@ KEY_COLUMN_USAGE PARTITIONS PLUGINS PROCESSLIST +REFERENTIAL_CONSTRAINTS ROUTINES SCHEMATA SCHEMA_PRIVILEGES @@ -745,7 +746,7 @@ CREATE TABLE t_crashme ( f1 BIGINT); CREATE VIEW a1 (t_CRASHME) AS SELECT f1 FROM t_crashme GROUP BY f1; CREATE VIEW a2 AS SELECT t_CRASHME FROM a1; count(*) -112 +113 drop view a2, a1; drop table t_crashme; select table_schema,table_name, column_name from @@ -832,6 +833,7 @@ COLUMN_PRIVILEGES TABLE_NAME select FILES TABLE_NAME select KEY_COLUMN_USAGE TABLE_NAME select PARTITIONS TABLE_NAME select +REFERENTIAL_CONSTRAINTS TABLE_NAME select STATISTICS TABLE_NAME select TABLES TABLE_NAME select TABLE_CONSTRAINTS TABLE_NAME select @@ -843,7 +845,7 @@ flush privileges; SELECT table_schema, count(*) FROM information_schema.TABLES GROUP BY TABLE_SCHEMA; table_schema count(*) cluster 1 -information_schema 22 +information_schema 23 mysql 21 create table t1 (i int, j int); create trigger trg1 before insert on t1 for each row diff --git a/mysql-test/r/information_schema_db.result b/mysql-test/r/information_schema_db.result index 584e1701a14..37537e257da 100644 --- a/mysql-test/r/information_schema_db.result +++ b/mysql-test/r/information_schema_db.result @@ -13,6 +13,7 @@ KEY_COLUMN_USAGE PARTITIONS PLUGINS PROCESSLIST +REFERENTIAL_CONSTRAINTS ROUTINES SCHEMATA SCHEMA_PRIVILEGES diff --git a/mysql-test/r/information_schema_inno.result b/mysql-test/r/information_schema_inno.result index fb6584673f6..9bb3185c6fb 100644 --- a/mysql-test/r/information_schema_inno.result +++ b/mysql-test/r/information_schema_inno.result @@ -25,3 +25,34 @@ NULL test PRIMARY NULL test t3 id 1 NULL NULL NULL NULL NULL test t3_ibfk_1 NULL test t3 id 1 1 test t2 t1_id NULL test t3_ibfk_1 NULL test t3 t2_id 2 2 test t2 id drop table t3, t2, t1; +CREATE TABLE t1(a1 INT NOT NULL, a2 INT NOT NULL, +PRIMARY KEY(a1, a2)) ENGINE=INNODB; +CREATE TABLE t2(b1 INT, b2 INT, INDEX (b1, b2), +CONSTRAINT A1 +FOREIGN KEY (b1, b2) REFERENCES t1(a1, a2) +ON UPDATE CASCADE ON DELETE NO ACTION) ENGINE=INNODB; +CREATE TABLE t3(b1 INT, b2 INT, INDEX (b1, b2), +CONSTRAINT A2 +FOREIGN KEY (b1, b2) REFERENCES t2(b1, b2) +ON UPDATE SET NULL ON DELETE RESTRICT) ENGINE=INNODB; +CREATE TABLE t4(b1 INT, b2 INT, INDEX (b1, b2), +CONSTRAINT A3 +FOREIGN KEY (b1, b2) REFERENCES t3(b1, b2) +ON UPDATE NO ACTION ON DELETE SET NULL) ENGINE=INNODB; +CREATE TABLE t5(b1 INT, b2 INT, INDEX (b1, b2), +CONSTRAINT A4 +FOREIGN KEY (b1, b2) REFERENCES t4(b1, b2) +ON UPDATE RESTRICT ON DELETE CASCADE) ENGINE=INNODB; +select a.CONSTRAINT_SCHEMA, b.TABLE_NAME, CONSTRAINT_TYPE, +b.CONSTRAINT_NAME, UNIQUE_CONSTRAINT_SCHEMA, UNIQUE_CONSTRAINT_NAME, +MATCH_OPTION, UPDATE_RULE, DELETE_RULE +from information_schema.TABLE_CONSTRAINTS a, +information_schema.REFERENTIAL_CONSTRAINTS b +where a.CONSTRAINT_SCHEMA = 'test' and a.CONSTRAINT_SCHEMA = b.CONSTRAINT_SCHEMA and +a.CONSTRAINT_NAME = b.CONSTRAINT_NAME; +CONSTRAINT_SCHEMA TABLE_NAME CONSTRAINT_TYPE CONSTRAINT_NAME UNIQUE_CONSTRAINT_SCHEMA UNIQUE_CONSTRAINT_NAME MATCH_OPTION UPDATE_RULE DELETE_RULE +test t2 FOREIGN KEY A1 test t1 NONE CASCADE NO ACTION +test t3 FOREIGN KEY A2 test t2 NONE SET NULL RESTRICT +test t4 FOREIGN KEY A3 test t3 NONE NO ACTION SET NULL +test t5 FOREIGN KEY A4 test t4 NONE RESTRICT CASCADE +drop tables t5, t4, t3, t2, t1; diff --git a/mysql-test/t/information_schema_inno.test b/mysql-test/t/information_schema_inno.test index 9cd64a54ad9..195bf57a880 100644 --- a/mysql-test/t/information_schema_inno.test +++ b/mysql-test/t/information_schema_inno.test @@ -21,3 +21,35 @@ select * from information_schema.KEY_COLUMN_USAGE where TABLE_SCHEMA= "test"; drop table t3, t2, t1; + +# +# Test for REFERENTIAL_CONSTRAINTS table +# +CREATE TABLE t1(a1 INT NOT NULL, a2 INT NOT NULL, + PRIMARY KEY(a1, a2)) ENGINE=INNODB; +CREATE TABLE t2(b1 INT, b2 INT, INDEX (b1, b2), + CONSTRAINT A1 + FOREIGN KEY (b1, b2) REFERENCES t1(a1, a2) + ON UPDATE CASCADE ON DELETE NO ACTION) ENGINE=INNODB; +CREATE TABLE t3(b1 INT, b2 INT, INDEX (b1, b2), + CONSTRAINT A2 + FOREIGN KEY (b1, b2) REFERENCES t2(b1, b2) + ON UPDATE SET NULL ON DELETE RESTRICT) ENGINE=INNODB; +CREATE TABLE t4(b1 INT, b2 INT, INDEX (b1, b2), + CONSTRAINT A3 + FOREIGN KEY (b1, b2) REFERENCES t3(b1, b2) + ON UPDATE NO ACTION ON DELETE SET NULL) ENGINE=INNODB; +CREATE TABLE t5(b1 INT, b2 INT, INDEX (b1, b2), + CONSTRAINT A4 + FOREIGN KEY (b1, b2) REFERENCES t4(b1, b2) + ON UPDATE RESTRICT ON DELETE CASCADE) ENGINE=INNODB; + + +select a.CONSTRAINT_SCHEMA, b.TABLE_NAME, CONSTRAINT_TYPE, + b.CONSTRAINT_NAME, UNIQUE_CONSTRAINT_SCHEMA, UNIQUE_CONSTRAINT_NAME, + MATCH_OPTION, UPDATE_RULE, DELETE_RULE +from information_schema.TABLE_CONSTRAINTS a, + information_schema.REFERENTIAL_CONSTRAINTS b +where a.CONSTRAINT_SCHEMA = 'test' and a.CONSTRAINT_SCHEMA = b.CONSTRAINT_SCHEMA and +a.CONSTRAINT_NAME = b.CONSTRAINT_NAME; +drop tables t5, t4, t3, t2, t1; diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 42def845174..a02361a0eac 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -5827,34 +5827,55 @@ ha_innobase::get_foreign_key_list(THD *thd, List *f_key_list) break; } - ulong length= 0; - if (foreign->type == DICT_FOREIGN_ON_DELETE_CASCADE) { - length=17; - tmp_buff= "ON DELETE CASCADE"; - } - else if (foreign->type == DICT_FOREIGN_ON_DELETE_SET_NULL) { - length=18; - tmp_buff= "ON DELETE SET NULL"; - } - else if (foreign->type == DICT_FOREIGN_ON_DELETE_NO_ACTION) { - length=19; - tmp_buff= "ON DELETE NO ACTION"; - } - else if (foreign->type == DICT_FOREIGN_ON_UPDATE_CASCADE) { - length=17; - tmp_buff= "ON UPDATE CASCADE"; - } - else if (foreign->type == DICT_FOREIGN_ON_UPDATE_SET_NULL) { - length=18; - tmp_buff= "ON UPDATE SET NULL"; - } - else if (foreign->type == DICT_FOREIGN_ON_UPDATE_NO_ACTION) { - length=19; - tmp_buff= "ON UPDATE NO ACTION"; - } - f_key_info.constraint_method= make_lex_string(thd, - f_key_info.constraint_method, - tmp_buff, length, 1); + ulong length; + if (foreign->type & DICT_FOREIGN_ON_DELETE_CASCADE) + { + length=7; + tmp_buff= "CASCADE"; + } + else if (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL) + { + length=8; + tmp_buff= "SET NULL"; + } + else if (foreign->type & DICT_FOREIGN_ON_DELETE_NO_ACTION) + { + length=9; + tmp_buff= "NO ACTION"; + } + else + { + length=8; + tmp_buff= "RESTRICT"; + } + f_key_info.delete_method= make_lex_string(thd, f_key_info.delete_method, + tmp_buff, length, 1); + + + if (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE) + { + length=7; + tmp_buff= "CASCADE"; + } + else if (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL) + { + length=8; + tmp_buff= "SET NULL"; + } + else if (foreign->type & DICT_FOREIGN_ON_UPDATE_NO_ACTION) + { + length=9; + tmp_buff= "NO ACTION"; + } + else + { + length=8; + tmp_buff= "RESTRICT"; + } + f_key_info.update_method= make_lex_string(thd, f_key_info.update_method, + tmp_buff, length, 1); + + FOREIGN_KEY_INFO *pf_key_info= ((FOREIGN_KEY_INFO *) thd->memdup((gptr) &f_key_info, diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 95433828a1e..5e54040f0ae 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4231,6 +4231,75 @@ int fill_status(THD *thd, TABLE_LIST *tables, COND *cond) } +/* + Fill and store records into I_S.referential_constraints table + + SYNOPSIS + get_referential_constraints_record() + thd thread handle + tables table list struct(processed table) + table I_S table + res 1 means the error during opening of the processed table + 0 means processed table is opened without error + base_name db name + file_name table name + + RETURN + 0 ok + # error +*/ + +static int +get_referential_constraints_record(THD *thd, struct st_table_list *tables, + TABLE *table, bool res, + const char *base_name, const char *file_name) +{ + CHARSET_INFO *cs= system_charset_info; + DBUG_ENTER("get_referential_constraints_record"); + + if (res) + { + if (!tables->view) + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + thd->net.last_errno, thd->net.last_error); + thd->clear_error(); + DBUG_RETURN(0); + } + if (!tables->view) + { + List f_key_list; + TABLE *show_table= tables->table; + show_table->file->info(HA_STATUS_VARIABLE | + HA_STATUS_NO_LOCK | + HA_STATUS_TIME); + + show_table->file->get_foreign_key_list(thd, &f_key_list); + FOREIGN_KEY_INFO *f_key_info; + List_iterator_fast it(f_key_list); + while ((f_key_info= it++)) + { + restore_record(table, s->default_values); + table->field[1]->store(base_name, strlen(base_name), cs); + table->field[9]->store(file_name, strlen(file_name), cs); + table->field[2]->store(f_key_info->forein_id->str, + f_key_info->forein_id->length, cs); + table->field[4]->store(f_key_info->referenced_db->str, + f_key_info->referenced_db->length, cs); + table->field[5]->store(f_key_info->referenced_table->str, + f_key_info->referenced_table->length, cs); + table->field[6]->store(STRING_WITH_LEN("NONE"), cs); + table->field[7]->store(f_key_info->update_method->str, + f_key_info->update_method->length, cs); + table->field[8]->store(f_key_info->delete_method->str, + f_key_info->delete_method->length, cs); + if (schema_table_store_record(thd, table)) + DBUG_RETURN(1); + } + } + DBUG_RETURN(0); +} + + /* Find schema_tables elment by name @@ -5160,6 +5229,22 @@ ST_FIELD_INFO files_fields_info[]= {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} }; +ST_FIELD_INFO referential_constraints_fields_info[]= +{ + {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0}, + {"CONSTRAINT_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, + {"CONSTRAINT_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, + {"UNIQUE_CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0}, + {"UNIQUE_CONSTRAINT_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, + {"UNIQUE_CONSTRAINT_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, + {"MATCH_OPTION", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, + {"UPDATE_RULE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, + {"DELETE_RULE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, + {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} +}; + + /* Description of ST_FIELD_INFO in table.h @@ -5195,6 +5280,9 @@ ST_SCHEMA_TABLE schema_tables[]= fill_plugins, make_old_format, 0, -1, -1, 0}, {"PROCESSLIST", processlist_fields_info, create_schema_table, fill_schema_processlist, make_old_format, 0, -1, -1, 0}, + {"REFERENTIAL_CONSTRAINTS", referential_constraints_fields_info, + create_schema_table, get_all_tables, 0, get_referential_constraints_record, + 1, 9, 0}, {"ROUTINES", proc_fields_info, create_schema_table, fill_schema_proc, make_proc_old_format, 0, -1, -1, 0}, {"SCHEMATA", schema_fields_info, create_schema_table, diff --git a/sql/table.h b/sql/table.h index aec9a7115e6..85d49444b29 100644 --- a/sql/table.h +++ b/sql/table.h @@ -335,7 +335,8 @@ typedef struct st_foreign_key_info LEX_STRING *forein_id; LEX_STRING *referenced_db; LEX_STRING *referenced_table; - LEX_STRING *constraint_method; + LEX_STRING *update_method; + LEX_STRING *delete_method; List foreign_fields; List referenced_fields; } FOREIGN_KEY_INFO; @@ -359,6 +360,7 @@ enum enum_schema_tables SCH_PARTITIONS, SCH_PLUGINS, SCH_PROCESSLIST, + SCH_REFERENTIAL_CONSTRAINTS, SCH_PROCEDURES, SCH_SCHEMATA, SCH_SCHEMA_PRIVILEGES,