3913 Pekka Nousiainen 2012-08-30
wl#6244 cleanup-x1
remove find_ndb_fk_tools.inc and enable windows
modified:
mysql-test/suite/ndb/t/ndb_fk_cascade_delete_multi.test
3912 Pekka Nousiainen 2012-08-30
wl#6244 cleanup
remove usage of $CREATE_FK and use alter table instead.
modified:
mysql-test/suite/ndb/r/ndb_fk_cascade_delete_multi.result
mysql-test/suite/ndb/t/ndb_fk_cascade_delete_multi.test
3911 Pekka Nousiainen 2012-08-30
wl#6244 mysql-is-x3
elide ndb error 21001
modified:
mysql-test/suite/ndb/r/ndb_fk_is.result
mysql-test/suite/ndb/t/ndb_fk_is.test
3910 Pekka Nousiainen 2012-08-30
wl#6244 mysql-is-x2
remove usage of have_ndb_fk.inc
modified:
mysql-test/suite/ndb/t/ndb_fk_is.test
3909 Pekka Nousiainen 2012-08-30
wl#6244 mysql-is-x1
a changed field name in 5.5
modified:
sql/ha_ndb_ddl_fk.cc
3908 Pekka Nousiainen 2012-08-30
wl#6244 mysql-is
Fix (and rudimentary test) information_schema wrt foreign keys in ndb
added:
mysql-test/suite/ndb/r/ndb_fk_is.result
mysql-test/suite/ndb/t/ndb_fk_is.test
modified:
sql/ha_ndb_ddl_fk.cc
3907 Pekka Nousiainen 2012-08-30
wl#6244 mysql-mysqldump-x2
elide ndb error 21001
modified:
mysql-test/suite/ndb/r/ndb_fk_mysqldump.result
mysql-test/suite/ndb/t/ndb_fk_mysqldump.test
3906 Pekka Nousiainen 2012-08-30
wl#6244 mysql-mysqldump-x1
remove usage of have_ndb_fk.inc
modified:
mysql-test/suite/ndb/t/ndb_fk_mysqldump.test
3905 Pekka Nousiainen 2012-08-30
wl#6244 mysql-mysqldump
Fix (and rudimentary test) mysqldump wrt foreign keys in ndb
added:
mysql-test/suite/ndb/r/ndb_fk_mysqldump.result
mysql-test/suite/ndb/t/ndb_fk_mysqldump.test
modified:
sql/ha_ndb_ddl_fk.cc
3904 Pekka Nousiainen 2012-08-30
wl#6244 mysql-db-x1
remove usage of have_ndb_fk.inc
modified:
mysql-test/suite/ndb/t/ndb_fk_db.test
3903 Pekka Nousiainen 2012-08-30
wl#6244 mysql-db
Fix (and rudimentary test) cross database foreign keys
added:
mysql-test/suite/ndb/r/ndb_fk_db.result
mysql-test/suite/ndb/t/ndb_fk_db.test
modified:
sql/ha_ndb_ddl_fk.cc
3902 magnus.blaudd@stripped 2012-07-13
ndb test
- don't run ndb_fk_cascade_delete_multi on Windows until we
have removed the use of create and drop_fk tools completely
modified:
mysql-test/suite/ndb/t/ndb_fk_cascade_delete_multi.test
=== modified file 'mysql-test/suite/ndb/r/ndb_fk_cascade_delete_multi.result'
--- a/mysql-test/suite/ndb/r/ndb_fk_cascade_delete_multi.result 2012-05-16 09:58:21 +0000
+++ b/mysql-test/suite/ndb/r/ndb_fk_cascade_delete_multi.result 2012-08-30 12:57:03 +0000
@@ -82,6 +82,8 @@ id value parent left_child right_child
4 2-leaf 1 NULL NULL
5 4-leaf 2 NULL NULL
6 6-leaf 2 NULL NULL
+alter table tree add constraint fk_parent foreign key (parent) references tree(id) on update restrict on delete cascade;
+alter table tree add constraint fk_left foreign key (left_child) references tree(id) on update restrict on delete cascade;
begin;
delete from tree where value = '5-inner';
select * from tree order by 1;
=== added file 'mysql-test/suite/ndb/r/ndb_fk_db.result'
--- a/mysql-test/suite/ndb/r/ndb_fk_db.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/r/ndb_fk_db.result 2012-08-30 11:55:25 +0000
@@ -0,0 +1,142 @@
+create database mydb0;
+use mydb0;
+create table parent (
+a int primary key,
+b int not null,
+c int not null,
+unique(b) using hash,
+index(c)) engine = ndb;
+create database mydb1;
+use mydb1;
+create table child (
+a int primary key,
+b int not null,
+c int not null,
+constraint fk1 foreign key(a) references mydb0.parent (a),
+unique(b) using hash,
+index(c)) engine = ndb;
+show create table child;
+Table Create Table
+child CREATE TABLE `child` (
+ `a` int(11) NOT NULL,
+ `b` int(11) NOT NULL,
+ `c` int(11) NOT NULL,
+ PRIMARY KEY (`a`),
+ UNIQUE KEY `b` (`b`) USING HASH,
+ KEY `c` (`c`),
+ CONSTRAINT `fk1` FOREIGN KEY(`a`) REFERENCES `mydb0`.`parent` (`a`) ON DELETE NO ACTION ON UPDATE NO ACTION
+) ENGINE=ndbcluster DEFAULT CHARSET=latin1
+alter offline table child add constraint fk2 foreign key (b)
+references mydb0.parent(a);
+show create table child;
+Table Create Table
+child CREATE TABLE `child` (
+ `a` int(11) NOT NULL,
+ `b` int(11) NOT NULL,
+ `c` int(11) NOT NULL,
+ PRIMARY KEY (`a`),
+ UNIQUE KEY `b` (`b`) USING HASH,
+ KEY `c` (`c`),
+ CONSTRAINT `fk1` FOREIGN KEY(`a`) REFERENCES `mydb0`.`parent` (`a`) ON DELETE NO ACTION ON UPDATE NO ACTION,
+ CONSTRAINT `fk2` FOREIGN KEY(`b`) REFERENCES `mydb0`.`parent` (`a`) ON DELETE NO ACTION ON UPDATE NO ACTION
+) ENGINE=ndbcluster DEFAULT CHARSET=latin1
+alter online table child add constraint fk3 foreign key (c)
+references mydb0.parent(a);
+show create table child;
+Table Create Table
+child CREATE TABLE `child` (
+ `a` int(11) NOT NULL,
+ `b` int(11) NOT NULL,
+ `c` int(11) NOT NULL,
+ PRIMARY KEY (`a`),
+ UNIQUE KEY `b` (`b`) USING HASH,
+ KEY `c` (`c`),
+ CONSTRAINT `fk1` FOREIGN KEY(`a`) REFERENCES `mydb0`.`parent` (`a`) ON DELETE NO ACTION ON UPDATE NO ACTION,
+ CONSTRAINT `fk2` FOREIGN KEY(`b`) REFERENCES `mydb0`.`parent` (`a`) ON DELETE NO ACTION ON UPDATE NO ACTION,
+ CONSTRAINT `fk3` FOREIGN KEY(`c`) REFERENCES `mydb0`.`parent` (`a`) ON DELETE NO ACTION ON UPDATE NO ACTION
+) ENGINE=ndbcluster DEFAULT CHARSET=latin1
+alter offline table child drop foreign key fk2;
+show create table child;
+Table Create Table
+child CREATE TABLE `child` (
+ `a` int(11) NOT NULL,
+ `b` int(11) NOT NULL,
+ `c` int(11) NOT NULL,
+ PRIMARY KEY (`a`),
+ UNIQUE KEY `b` (`b`) USING HASH,
+ KEY `c` (`c`),
+ CONSTRAINT `fk1` FOREIGN KEY(`a`) REFERENCES `mydb0`.`parent` (`a`) ON DELETE NO ACTION ON UPDATE NO ACTION,
+ CONSTRAINT `fk3` FOREIGN KEY(`c`) REFERENCES `mydb0`.`parent` (`a`) ON DELETE NO ACTION ON UPDATE NO ACTION
+) ENGINE=ndbcluster DEFAULT CHARSET=latin1
+alter online table child drop foreign key fk3;
+show create table child;
+Table Create Table
+child CREATE TABLE `child` (
+ `a` int(11) NOT NULL,
+ `b` int(11) NOT NULL,
+ `c` int(11) NOT NULL,
+ PRIMARY KEY (`a`),
+ UNIQUE KEY `b` (`b`) USING HASH,
+ KEY `c` (`c`),
+ CONSTRAINT `fk1` FOREIGN KEY(`a`) REFERENCES `mydb0`.`parent` (`a`) ON DELETE NO ACTION ON UPDATE NO ACTION
+) ENGINE=ndbcluster DEFAULT CHARSET=latin1
+alter offline table mydb0.parent rename mydb1.parent;
+show create table child;
+Table Create Table
+child CREATE TABLE `child` (
+ `a` int(11) NOT NULL,
+ `b` int(11) NOT NULL,
+ `c` int(11) NOT NULL,
+ PRIMARY KEY (`a`),
+ UNIQUE KEY `b` (`b`) USING HASH,
+ KEY `c` (`c`),
+ CONSTRAINT `fk1` FOREIGN KEY(`a`) REFERENCES `parent` (`a`) ON DELETE NO ACTION ON UPDATE NO ACTION
+) ENGINE=ndbcluster DEFAULT CHARSET=latin1
+alter online table mydb1.parent rename mydb0.parent;
+show create table child;
+Table Create Table
+child CREATE TABLE `child` (
+ `a` int(11) NOT NULL,
+ `b` int(11) NOT NULL,
+ `c` int(11) NOT NULL,
+ PRIMARY KEY (`a`),
+ UNIQUE KEY `b` (`b`) USING HASH,
+ KEY `c` (`c`),
+ CONSTRAINT `fk1` FOREIGN KEY(`a`) REFERENCES `mydb0`.`parent` (`a`) ON DELETE NO ACTION ON UPDATE NO ACTION
+) ENGINE=ndbcluster DEFAULT CHARSET=latin1
+use test;
+alter offline table mydb1.child add constraint fk2 foreign key (b)
+references mydb0.parent(a);
+use mydb1;
+show create table child;
+Table Create Table
+child CREATE TABLE `child` (
+ `a` int(11) NOT NULL,
+ `b` int(11) NOT NULL,
+ `c` int(11) NOT NULL,
+ PRIMARY KEY (`a`),
+ UNIQUE KEY `b` (`b`) USING HASH,
+ KEY `c` (`c`),
+ CONSTRAINT `fk1` FOREIGN KEY(`a`) REFERENCES `mydb0`.`parent` (`a`) ON DELETE NO ACTION ON UPDATE NO ACTION,
+ CONSTRAINT `fk2` FOREIGN KEY(`b`) REFERENCES `mydb0`.`parent` (`a`) ON DELETE NO ACTION ON UPDATE NO ACTION
+) ENGINE=ndbcluster DEFAULT CHARSET=latin1
+use test;
+alter online table mydb1.child add constraint fk3 foreign key (c)
+references mydb0.parent(a);
+use mydb1;
+show create table child;
+Table Create Table
+child CREATE TABLE `child` (
+ `a` int(11) NOT NULL,
+ `b` int(11) NOT NULL,
+ `c` int(11) NOT NULL,
+ PRIMARY KEY (`a`),
+ UNIQUE KEY `b` (`b`) USING HASH,
+ KEY `c` (`c`),
+ CONSTRAINT `fk1` FOREIGN KEY(`a`) REFERENCES `mydb0`.`parent` (`a`) ON DELETE NO ACTION ON UPDATE NO ACTION,
+ CONSTRAINT `fk2` FOREIGN KEY(`b`) REFERENCES `mydb0`.`parent` (`a`) ON DELETE NO ACTION ON UPDATE NO ACTION,
+ CONSTRAINT `fk3` FOREIGN KEY(`c`) REFERENCES `mydb0`.`parent` (`a`) ON DELETE NO ACTION ON UPDATE NO ACTION
+) ENGINE=ndbcluster DEFAULT CHARSET=latin1
+use test;
+drop database mydb0;
+drop database mydb1;
=== added file 'mysql-test/suite/ndb/r/ndb_fk_is.result'
--- a/mysql-test/suite/ndb/r/ndb_fk_is.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/r/ndb_fk_is.result 2012-08-30 12:56:15 +0000
@@ -0,0 +1,35 @@
+create table product (
+category int not null,
+id int not null,
+price decimal,
+primary key(category, id))
+engine=ndb;
+create table customer (
+id int not null,
+primary key (id))
+engine=ndb;
+create table product_order (
+no int not null auto_increment,
+product_category int not null,
+product_id int not null,
+customer_id int not null,
+primary key(no),
+index (product_category, product_id),
+foreign key (product_category, product_id) references product(category, id)
+on update restrict on delete cascade,
+index (customer_id),
+foreign key (customer_id) references customer(id))
+engine=ndb;
+select *
+from information_schema.table_constraints
+where table_schema = 'test'
+order by table_name, constraint_name;
+CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_SCHEMA TABLE_NAME CONSTRAINT_TYPE
+def test FK_12_17 test customer FOREIGN KEY
+def test PRIMARY test customer PRIMARY KEY
+def test FK_10_16 test product FOREIGN KEY
+def test PRIMARY test product PRIMARY KEY
+def test FK_10_16 test product_order FOREIGN KEY
+def test FK_12_17 test product_order FOREIGN KEY
+def test PRIMARY test product_order PRIMARY KEY
+drop table product, customer, product_order;
=== added file 'mysql-test/suite/ndb/r/ndb_fk_mysqldump.result'
--- a/mysql-test/suite/ndb/r/ndb_fk_mysqldump.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/r/ndb_fk_mysqldump.result 2012-08-30 12:53:40 +0000
@@ -0,0 +1,80 @@
+create table product (
+category int not null,
+id int not null,
+price decimal,
+primary key(category, id))
+engine=ndb;
+create table customer (
+id int not null,
+primary key (id))
+engine=ndb;
+create table product_order (
+no int not null auto_increment,
+product_category int not null,
+product_id int not null,
+customer_id int not null,
+primary key(no),
+index (product_category, product_id),
+foreign key (product_category, product_id) references product(category, id)
+on update restrict on delete cascade,
+index (customer_id),
+foreign key (customer_id) references customer(id))
+engine=ndb;
+show create table product;
+Table Create Table
+product CREATE TABLE `product` (
+ `category` int(11) NOT NULL,
+ `id` int(11) NOT NULL,
+ `price` decimal(10,0) DEFAULT NULL,
+ PRIMARY KEY (`category`,`id`)
+) ENGINE=ndbcluster DEFAULT CHARSET=latin1
+show create table customer;
+Table Create Table
+customer CREATE TABLE `customer` (
+ `id` int(11) NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=ndbcluster DEFAULT CHARSET=latin1
+show create table product_order;
+Table Create Table
+product_order CREATE TABLE `product_order` (
+ `no` int(11) NOT NULL AUTO_INCREMENT,
+ `product_category` int(11) NOT NULL,
+ `product_id` int(11) NOT NULL,
+ `customer_id` int(11) NOT NULL,
+ PRIMARY KEY (`no`),
+ KEY `product_category` (`product_category`,`product_id`),
+ KEY `customer_id` (`customer_id`),
+ CONSTRAINT `FK_10_16` FOREIGN KEY(`product_category`,`product_id`) REFERENCES `product` (`category`,`id`) ON DELETE CASCADE ON UPDATE RESTRICT,
+ CONSTRAINT `FK_12_17` FOREIGN KEY(`customer_id`) REFERENCES `customer` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
+) ENGINE=ndbcluster DEFAULT CHARSET=latin1
+insert into product values (1,1,5);
+insert into customer value (1);
+insert into product_order value (1,1,1,1);
+show create table product;
+Table Create Table
+product CREATE TABLE `product` (
+ `category` int(11) NOT NULL,
+ `id` int(11) NOT NULL,
+ `price` decimal(10,0) DEFAULT NULL,
+ PRIMARY KEY (`category`,`id`)
+) ENGINE=ndbcluster DEFAULT CHARSET=latin1
+show create table customer;
+Table Create Table
+customer CREATE TABLE `customer` (
+ `id` int(11) NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=ndbcluster DEFAULT CHARSET=latin1
+show create table product_order;
+Table Create Table
+product_order CREATE TABLE `product_order` (
+ `no` int(11) NOT NULL AUTO_INCREMENT,
+ `product_category` int(11) NOT NULL,
+ `product_id` int(11) NOT NULL,
+ `customer_id` int(11) NOT NULL,
+ PRIMARY KEY (`no`),
+ KEY `product_category` (`product_category`,`product_id`),
+ KEY `customer_id` (`customer_id`),
+ CONSTRAINT `FK_10_16` FOREIGN KEY(`product_category`,`product_id`) REFERENCES `product` (`category`,`id`) ON DELETE CASCADE ON UPDATE RESTRICT,
+ CONSTRAINT `FK_12_17` FOREIGN KEY(`customer_id`) REFERENCES `customer` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
+) ENGINE=ndbcluster AUTO_INCREMENT=2 DEFAULT CHARSET=latin1
+drop table product, customer, product_order;
=== modified file 'mysql-test/suite/ndb/t/ndb_fk_cascade_delete_multi.test'
--- a/mysql-test/suite/ndb/t/ndb_fk_cascade_delete_multi.test 2012-07-13 13:46:09 +0000
+++ b/mysql-test/suite/ndb/t/ndb_fk_cascade_delete_multi.test 2012-08-30 12:57:36 +0000
@@ -1,8 +1,4 @@
-# Does not work on Windows until we got rid of create_fk and drop_fk
--- source include/not_windows.inc
-
-- source include/have_ndb.inc
--- source find_ndb_fk_tools.inc
create table emp (
id int primary key auto_increment,
@@ -63,12 +59,8 @@ insert into tree values (6, '6-leaf',
select * from tree order by 1;
---let $parentname=parent
---let $leftname=left_child\$unique
---let $rightname=left_child\$unique
---exec $CREATE_FK --database=test --parent=tree --child=tree --child-index='$parentname' --on-update-action=restrict --on-delete-action=cascade fk_parent > /dev/null
---exec $CREATE_FK --database=test --parent=tree --child=tree --child-index='$leftname' --on-update-action=restrict --on-delete-action=cascade fk_left > /dev/null
---exec $CREATE_FK --database=test --parent=tree --child=tree --child-index='$rightname' --on-update-action=restrict --on-delete-action=cascade fk_right > /dev/null
+alter table tree add constraint fk_parent foreign key (parent) references tree(id) on update restrict on delete cascade;
+alter table tree add constraint fk_left foreign key (left_child) references tree(id) on update restrict on delete cascade;
begin;
delete from tree where value = '5-inner';
@@ -85,8 +77,4 @@ delete from tree where value = '3-root';
select * from tree order by 1;
commit;
---exec $DROP_FK --database=test fk_parent > /dev/null
---exec $DROP_FK --database=test fk_left > /dev/null
---exec $DROP_FK --database=test fk_right > /dev/null
-
drop table tree;
=== added file 'mysql-test/suite/ndb/t/ndb_fk_db.test'
--- a/mysql-test/suite/ndb/t/ndb_fk_db.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_fk_db.test 2012-08-30 12:50:34 +0000
@@ -0,0 +1,66 @@
+-- source include/have_ndb.inc
+
+create database mydb0;
+use mydb0;
+
+create table parent (
+ a int primary key,
+ b int not null,
+ c int not null,
+ unique(b) using hash,
+ index(c)) engine = ndb;
+
+create database mydb1;
+use mydb1;
+
+create table child (
+ a int primary key,
+ b int not null,
+ c int not null,
+ constraint fk1 foreign key(a) references mydb0.parent (a),
+ unique(b) using hash,
+ index(c)) engine = ndb;
+
+show create table child;
+
+alter offline table child add constraint fk2 foreign key (b)
+ references mydb0.parent(a);
+
+show create table child;
+
+alter online table child add constraint fk3 foreign key (c)
+ references mydb0.parent(a);
+
+show create table child;
+
+alter offline table child drop foreign key fk2;
+
+show create table child;
+
+alter online table child drop foreign key fk3;
+
+show create table child;
+
+alter offline table mydb0.parent rename mydb1.parent;
+
+show create table child;
+
+alter online table mydb1.parent rename mydb0.parent;
+
+show create table child;
+
+use test;
+alter offline table mydb1.child add constraint fk2 foreign key (b)
+ references mydb0.parent(a);
+use mydb1;
+show create table child;
+
+use test;
+alter online table mydb1.child add constraint fk3 foreign key (c)
+ references mydb0.parent(a);
+use mydb1;
+show create table child;
+
+use test;
+drop database mydb0;
+drop database mydb1;
=== added file 'mysql-test/suite/ndb/t/ndb_fk_is.test'
--- a/mysql-test/suite/ndb/t/ndb_fk_is.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_fk_is.test 2012-08-30 12:56:15 +0000
@@ -0,0 +1,33 @@
+-- source include/have_ndb.inc
+
+create table product (
+ category int not null,
+ id int not null,
+ price decimal,
+ primary key(category, id))
+engine=ndb;
+
+create table customer (
+ id int not null,
+ primary key (id))
+engine=ndb;
+
+create table product_order (
+ no int not null auto_increment,
+ product_category int not null,
+ product_id int not null,
+ customer_id int not null,
+ primary key(no),
+ index (product_category, product_id),
+ foreign key (product_category, product_id) references product(category, id)
+ on update restrict on delete cascade,
+ index (customer_id),
+ foreign key (customer_id) references customer(id))
+engine=ndb;
+
+select *
+from information_schema.table_constraints
+where table_schema = 'test'
+order by table_name, constraint_name;
+
+drop table product, customer, product_order;
=== added file 'mysql-test/suite/ndb/t/ndb_fk_mysqldump.test'
--- a/mysql-test/suite/ndb/t/ndb_fk_mysqldump.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_fk_mysqldump.test 2012-08-30 12:53:40 +0000
@@ -0,0 +1,47 @@
+-- source include/have_ndb.inc
+
+# test uses mysqldump, hence not in embedded
+-- source include/not_embedded.inc
+
+create table product (
+ category int not null,
+ id int not null,
+ price decimal,
+ primary key(category, id))
+engine=ndb;
+
+create table customer (
+ id int not null,
+ primary key (id))
+engine=ndb;
+
+create table product_order (
+ no int not null auto_increment,
+ product_category int not null,
+ product_id int not null,
+ customer_id int not null,
+ primary key(no),
+ index (product_category, product_id),
+ foreign key (product_category, product_id) references product(category, id)
+ on update restrict on delete cascade,
+ index (customer_id),
+ foreign key (customer_id) references customer(id))
+engine=ndb;
+
+show create table product;
+show create table customer;
+show create table product_order;
+
+insert into product values (1,1,5);
+insert into customer value (1);
+insert into product_order value (1,1,1,1);
+
+let $dump_file = $MYSQLTEST_VARDIR/tmp/ndb_fk_dump.sql;
+--exec $MYSQL_DUMP --databases test > $dump_file
+--exec $MYSQL test < $dump_file
+
+show create table product;
+show create table customer;
+show create table product_order;
+
+drop table product, customer, product_order;
=== modified file 'sql/ha_ndb_ddl_fk.cc'
--- a/sql/ha_ndb_ddl_fk.cc 2012-05-28 12:57:40 +0000
+++ b/sql/ha_ndb_ddl_fk.cc 2012-08-30 12:55:24 +0000
@@ -152,6 +152,35 @@ found:
return best_matching_index; // NOTE: also returns reference
}
+
+static
+void
+setDbName(Ndb* ndb, const char * name)
+{
+ if (name && strlen(name) != 0)
+ {
+ ndb->setDatabaseName(name);
+ }
+}
+
+struct Ndb_db_guard
+{
+ Ndb_db_guard(Ndb* ndb) {
+ this->ndb = ndb;
+ strcpy(save_db, ndb->getDatabaseName());
+ }
+
+ void restore() {
+ ndb->setDatabaseName(save_db);
+ }
+
+ ~Ndb_db_guard() {
+ ndb->setDatabaseName(save_db);
+ }
+private:
+ Ndb* ndb;
+ char save_db[FN_REFLEN + 1];
+};
/**
* ndbapi want's c-strings (null terminated)
@@ -198,9 +227,6 @@ ha_ndbcluster::create_fks(THD *thd, Ndb
const int er_default= ER_CANNOT_ADD_FOREIGN;
char tmpbuf[FN_REFLEN];
- /**
- * TODO handle databases too...
- */
assert(thd->lex != 0);
Key * key= 0;
List_iterator<Key> key_iterator(thd->lex->alter_info.key_list);
@@ -256,10 +282,31 @@ ha_ndbcluster::create_fks(THD *thd, Ndb
DBUG_RETURN(er_default); // TODO suitable error code
}
+ Ndb_db_guard db_guard(ndb); // save db
+
+ char parent_db[FN_REFLEN];
char parent_name[FN_REFLEN];
- my_snprintf(parent_name, sizeof(parent_name), "%*s",
- (int)fk->ref_table->table.length,
- fk->ref_table->table.str);
+ if (fk->ref_table->db.length != 0 && fk->ref_table->db.str != 0)
+ {
+ my_snprintf(parent_db, sizeof(parent_db), "%*s",
+ (int)fk->ref_table->db.length,
+ fk->ref_table->db.str);
+ }
+ else
+ {
+ parent_db[0]= 0;
+ }
+ if (fk->ref_table->table.length != 0 && fk->ref_table->table.str != 0)
+ {
+ my_snprintf(parent_name, sizeof(parent_name), "%*s",
+ (int)fk->ref_table->table.length,
+ fk->ref_table->table.str);
+ }
+ else
+ {
+ parent_name[0]= 0;
+ }
+ setDbName(ndb, parent_db);
Ndb_table_guard parent_tab(dict, parent_name);
if (parent_tab.get_table() == 0)
{
@@ -291,6 +338,8 @@ ha_ndbcluster::create_fks(THD *thd, Ndb
parentcols,
parent_primary_key);
+ db_guard.restore(); // restore db
+
if (!parent_primary_key && parent_index == 0)
{
DBUG_RETURN(er_default); // TODO suitable error code
@@ -397,24 +446,6 @@ ha_ndbcluster::is_fk_defined_on_table_or
return FALSE;
}
-int
-ha_ndbcluster::get_foreign_key_list(THD *thd,
- List<FOREIGN_KEY_INFO> * f_key_list)
-{
- DBUG_ENTER("ha_ndbcluster::get_foreign_key_list");
- Ndb *ndb= get_ndb(thd);
- if (ndb == 0)
- {
- DBUG_RETURN(0);
- }
-
- /**
- * TODO
- */
-
- DBUG_RETURN(0);
-}
-
uint
ha_ndbcluster::referenced_by_foreign_key()
{
@@ -515,6 +546,170 @@ fk_split_name(char dst[], const char * s
return dstptr;
}
+int
+ha_ndbcluster::get_foreign_key_list(THD *thd,
+ List<FOREIGN_KEY_INFO> * f_key_list)
+{
+ DBUG_ENTER("ha_ndbcluster::get_foreign_key_list");
+ if (thd == 0)
+ {
+ DBUG_RETURN(0);
+ }
+
+ if (m_table == 0)
+ {
+ DBUG_RETURN(0);
+ }
+
+ Ndb *ndb= get_ndb(thd);
+ if (ndb == 0)
+ {
+ DBUG_RETURN(0);
+ }
+
+ NDBDICT *dict= ndb->getDictionary();
+ NDBDICT::List obj_list;
+ dict->listDependentObjects(obj_list, *m_table);
+ for (unsigned i = 0; i < obj_list.count; i++)
+ {
+ if (obj_list.elements[i].type != NdbDictionary::Object::ForeignKey)
+ continue;
+
+ FOREIGN_KEY_INFO f_key_info;
+
+ NdbDictionary::ForeignKey fk;
+ int res= dict->getForeignKey(fk, obj_list.elements[i].name);
+ if (res != 0)
+ {
+ DBUG_RETURN(1); // TODO suitable error code
+ }
+
+ {
+ char fk_full_name[FN_LEN + 1];
+ const char * name = fk_split_name(fk_full_name, fk.getName());
+ f_key_info.foreign_id = thd_make_lex_string(thd, 0, name,
+ (uint)strlen(name), 1);
+ }
+
+ for (unsigned i = 0; i < fk.getParentColumnCount(); i++)
+ {
+ const NdbDictionary::Column * col =
+ m_table->getColumn(fk.getParentColumnNo(i));
+ if (col == 0)
+ {
+ DBUG_RETURN(1); // TODO suitable error code
+ }
+ LEX_STRING * name = thd_make_lex_string(thd, 0,
+ col->getName(),
+ (uint)strlen(col->getName()), 1);
+ f_key_info.foreign_fields.push_back(name);
+ }
+
+ {
+ char child_db_and_name[FN_LEN + 1];
+ const char * child_name = fk_split_name(child_db_and_name,
+ fk.getChildTable());
+ f_key_info.referenced_db =
+ thd_make_lex_string(thd, 0, child_db_and_name,
+ (uint)strlen(child_db_and_name),
+ 1);
+
+ Ndb_db_guard db_guard(ndb);
+ setDbName(ndb, child_db_and_name);
+ Ndb_table_guard child_tab(dict, child_name);
+ if (child_tab.get_table() == 0)
+ {
+ ERR_RETURN(dict->getNdbError());
+ }
+
+ for (unsigned i = 0; i < fk.getChildColumnCount(); i++)
+ {
+ const NdbDictionary::Column * col =
+ child_tab.get_table()->getColumn(fk.getChildColumnNo(i));
+ if (col == 0)
+ {
+ DBUG_RETURN(1); // TODO suitable error code
+ }
+ LEX_STRING * name =
+ thd_make_lex_string(thd, 0, col->getName(),
+ (uint)strlen(col->getName()), 1);
+ f_key_info.referenced_fields.push_back(name);
+ }
+ }
+
+ {
+ const char *update_method = 0;
+ switch(fk.getOnUpdateAction()){
+ case NdbDictionary::ForeignKey::NoAction:
+ update_method = "NO ACTION";
+ break;
+ case NdbDictionary::ForeignKey::Restrict:
+ update_method = "RESTRICT";
+ break;
+ case NdbDictionary::ForeignKey::Cascade:
+ update_method = "CASCADE";
+ break;
+ case NdbDictionary::ForeignKey::SetNull:
+ update_method = "SET NULL";
+ break;
+ case NdbDictionary::ForeignKey::SetDefault:
+ update_method = "SET DEFAULT";
+ break;
+ }
+ f_key_info.update_method =
+ thd_make_lex_string(thd, 0, update_method,
+ (uint)strlen(update_method),
+ 1);
+ }
+
+ {
+ const char *delete_method = "";
+ switch(fk.getOnDeleteAction()){
+ case NdbDictionary::ForeignKey::NoAction:
+ delete_method = "NO ACTION";
+ break;
+ case NdbDictionary::ForeignKey::Restrict:
+ delete_method = "RESTRICT";
+ break;
+ case NdbDictionary::ForeignKey::Cascade:
+ delete_method = "CASCADE";
+ break;
+ case NdbDictionary::ForeignKey::SetNull:
+ delete_method = "SET NULL";
+ break;
+ case NdbDictionary::ForeignKey::SetDefault:
+ delete_method = "SET DEFAULT";
+ break;
+ }
+ f_key_info.delete_method =
+ thd_make_lex_string(thd, 0, delete_method,
+ (uint)strlen(delete_method),
+ 1);
+ }
+
+ if (fk.getChildIndex() != 0)
+ {
+ f_key_info.referenced_key_name =
+ thd_make_lex_string(thd, 0, fk.getChildIndex(),
+ (uint)strlen(fk.getChildIndex()),
+ 1);
+ }
+ else
+ {
+ f_key_info.referenced_key_name = 0;
+ }
+
+ List<LEX_STRING> foreign_fields;
+ List<LEX_STRING> referenced_fields;
+
+ FOREIGN_KEY_INFO *pf_key_info = (FOREIGN_KEY_INFO *)
+ thd_memdup(thd, &f_key_info, sizeof(FOREIGN_KEY_INFO));
+ f_key_list->push_back(pf_key_info);
+ }
+
+ DBUG_RETURN(0);
+}
+
static
int
cmp_fk_name(const void * _e0, const void * _e1)
@@ -595,10 +790,10 @@ ha_ndbcluster::get_foreign_key_create_in
const NDBTAB * childtab= 0;
const NDBTAB * parenttab= 0;
+ char parent_db_and_name[FN_LEN + 1];
{
- char db_and_name[FN_LEN + 1];
- const char * name = fk_split_name(db_and_name, fk.getParentTable());
- ndb->setDatabaseName(db_and_name);
+ const char * name = fk_split_name(parent_db_and_name,fk.getParentTable());
+ setDbName(ndb, parent_db_and_name);
parenttab= dict->getTableGlobal(name);
if (parenttab == 0)
{
@@ -607,10 +802,10 @@ ha_ndbcluster::get_foreign_key_create_in
}
}
+ char child_db_and_name[FN_LEN + 1];
{
- char db_and_name[FN_LEN + 1];
- const char * name = fk_split_name(db_and_name, fk.getChildTable());
- ndb->setDatabaseName(db_and_name);
+ const char * name = fk_split_name(child_db_and_name, fk.getChildTable());
+ setDbName(ndb, child_db_and_name);
childtab= dict->getTableGlobal(name);
if (childtab == 0)
{
@@ -619,6 +814,17 @@ ha_ndbcluster::get_foreign_key_create_in
}
}
+ if (! (strcmp(child_db_and_name, m_dbname) == 0 &&
+ strcmp(childtab->getName(), m_tabname) == 0))
+ {
+ /**
+ * this was on parent table (fk are shown on child table in SQL)
+ */
+ assert(strcmp(parent_db_and_name, m_dbname) == 0);
+ assert(strcmp(parenttab->getName(), m_tabname) == 0);
+ continue;
+ }
+
fk_string.append(",");
fk_string.append("\n ");
fk_string.append("CONSTRAINT `");
@@ -646,6 +852,11 @@ ha_ndbcluster::get_foreign_key_create_in
}
fk_string.append(") REFERENCES `");
+ if (strcmp(parent_db_and_name, child_db_and_name) != 0)
+ {
+ fk_string.append(parent_db_and_name);
+ fk_string.append("`.`");
+ }
fk_string.append(parenttab->getName());
fk_string.append("` (");
@@ -746,6 +957,7 @@ ha_ndbcluster::copy_fk_for_offline_alter
DBUG_RETURN(0);
}
+ Ndb_db_guard db_guard(ndb);
const char * src_db = thd->lex->select_lex.table_list.first->db;
const char * src_tab = thd->lex->select_lex.table_list.first->table_name;
@@ -757,6 +969,7 @@ ha_ndbcluster::copy_fk_for_offline_alter
assert(thd->lex != 0);
NDBDICT* dict = ndb->getDictionary();
+ setDbName(ndb, src_db);
Ndb_table_guard srctab(dict, src_tab);
if (srctab.get_table() == 0)
{
@@ -766,12 +979,14 @@ ha_ndbcluster::copy_fk_for_offline_alter
DBUG_RETURN(0);
}
+ db_guard.restore();
Ndb_table_guard dsttab(dict, _dsttab->getName());
if (dsttab.get_table() == 0)
{
ERR_RETURN(dict->getNdbError());
}
+ setDbName(ndb, src_db);
NDBDICT::List obj_list;
dict->listDependentObjects(obj_list, *srctab.get_table());
for (unsigned i = 0; i < obj_list.count; i++)
@@ -820,6 +1035,7 @@ ha_ndbcluster::copy_fk_for_offline_alter
{
char db_and_name[FN_LEN + 1];
const char * name= fk_split_name(db_and_name, fk.getParentTable());
+ setDbName(ndb, db_and_name);
Ndb_table_guard org_parent(dict, name);
if (org_parent.get_table() == 0)
{
@@ -831,6 +1047,7 @@ ha_ndbcluster::copy_fk_for_offline_alter
{
char db_and_name[FN_LEN + 1];
const char * name= fk_split_name(db_and_name, fk.getChildTable());
+ setDbName(ndb, db_and_name);
Ndb_table_guard org_child(dict, name);
if (org_child.get_table() == 0)
{
@@ -858,6 +1075,7 @@ ha_ndbcluster::copy_fk_for_offline_alter
if (fk.getParentIndex() != 0)
{
name = fk_split_name(db_and_name, fk.getParentIndex(), true);
+ setDbName(ndb, db_and_name);
const NDBINDEX * idx = dict->getIndexGlobal(name,*dsttab.get_table());
if (idx == 0)
{
@@ -892,6 +1110,7 @@ ha_ndbcluster::copy_fk_for_offline_alter
if (fk.getChildIndex() != 0)
{
name = fk_split_name(db_and_name, fk.getChildIndex(), true);
+ setDbName(ndb, db_and_name);
const NDBINDEX * idx = dict->getIndexGlobal(name,*dsttab.get_table());
if (idx == 0)
{
@@ -918,6 +1137,7 @@ ha_ndbcluster::copy_fk_for_offline_alter
childObjectId,
name);
fk.setName(new_name);
+ setDbName(ndb, db_and_name);
if (dict->createForeignKey(fk) != 0)
{
ERR_RETURN(dict->getNdbError());
No bundle (reason: useless for push emails).
| Thread |
|---|
| • bzr push into mysql-5.5-cluster-7.3-fk branch (pekka.nousiainen:3902 to3913) WL#6244 | Pekka Nousiainen | 30 Aug |