WL#2257 REFERENTIAL_CONSTRAINTS view
added I_S.REFARENTIAL_CONSTRAINTS table
This commit is contained in:
parent
b050f975c4
commit
19de86dd63
@ -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
|
||||
|
@ -13,6 +13,7 @@ KEY_COLUMN_USAGE
|
||||
PARTITIONS
|
||||
PLUGINS
|
||||
PROCESSLIST
|
||||
REFERENTIAL_CONSTRAINTS
|
||||
ROUTINES
|
||||
SCHEMATA
|
||||
SCHEMA_PRIVILEGES
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -5827,34 +5827,55 @@ ha_innobase::get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *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,
|
||||
|
@ -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<FOREIGN_KEY_INFO> 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<FOREIGN_KEY_INFO> 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,
|
||||
|
@ -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<LEX_STRING> foreign_fields;
|
||||
List<LEX_STRING> 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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user