Changeset: 0b2a4184d7dd for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=0b2a4184d7dd Added Files: sql/test/BugTracker-2015/Tests/foreignkey_over_schemas.Bug-3855.sql sql/test/BugTracker-2015/Tests/foreignkey_over_schemas.Bug-3855.stable.err sql/test/BugTracker-2015/Tests/foreignkey_over_schemas.Bug-3855.stable.out Modified Files: sql/server/rel_schema.c sql/storage/store.c sql/test/BugTracker-2015/Tests/All Branch: Jul2015 Log Message:
add support for foreignkeys between tables in different schemas diffs (280 lines): diff --git a/sql/server/rel_schema.c b/sql/server/rel_schema.c --- a/sql/server/rel_schema.c +++ b/sql/server/rel_schema.c @@ -304,8 +304,10 @@ column_constraint_type(mvc *sql, char *n } break; case SQL_FOREIGN_KEY: { dnode *n = s->data.lval->h; + char *rsname = qname_schema(n->data.lval); char *rtname = qname_table(n->data.lval); int ref_actions = n->next->next->next->data.i_val; + sql_schema *rs; sql_table *rt; sql_fkey *fk; list *cols; @@ -318,7 +320,12 @@ column_constraint_type(mvc *sql, char *n return res; } */ - rt = _bind_table(t, ss, cur_schema(sql), rtname); + + if (rsname) + rs = mvc_bind_schema(sql, rsname); + else + rs = cur_schema(sql); + rt = _bind_table(t, ss, rs, rtname); if (!rt) { (void) sql_error(sql, 02, "42S02!CONSTRAINT FOREIGN KEY: no such table '%s'\n", rtname); return res; @@ -339,7 +346,7 @@ column_constraint_type(mvc *sql, char *n rk = &rt->pkey->k; } if (!rk) { - (void) sql_error(sql, 02, "42000!CONSTRAINT FOREIGN KEY: could not find referenced PRIMARY KEY in table %s\n", rtname); + (void) sql_error(sql, 02, "42000!CONSTRAINT FOREIGN KEY: could not find referenced PRIMARY KEY in table %s.%s\n", rsname, rtname); return res; } fk = mvc_create_fkey(sql, t, name, fkey, rk, ref_actions & 255, (ref_actions>>8) & 255); @@ -469,11 +476,18 @@ static int table_foreign_key(mvc *sql, char *name, symbol *s, sql_schema *ss, sql_table *t) { dnode *n = s->data.lval->h; + char *rsname = qname_schema(n->data.lval); char *rtname = qname_table(n->data.lval); - sql_table *ft = mvc_bind_table(sql, ss, rtname); + sql_schema *fs; + sql_table *ft; + if (rsname) + fs = mvc_bind_schema(sql, rsname); + else + fs = ss; + ft = mvc_bind_table(sql, fs, rtname); /* self referenced table */ - if (!ft && t->s == ss && strcmp(t->base.name, rtname) == 0) + if (!ft && t->s == fs && strcmp(t->base.name, rtname) == 0) ft = t; if (!ft) { sql_error(sql, 02, "42S02!CONSTRAINT FOREIGN KEY: no such table '%s'\n", rtname); diff --git a/sql/storage/store.c b/sql/storage/store.c --- a/sql/storage/store.c +++ b/sql/storage/store.c @@ -305,7 +305,8 @@ load_key(sql_trans *tr, sql_table *t, oi fk->rkey = uk; if (!uk->keys) uk->keys = list_new(tr->sa, NULL); - list_append(uk->keys, fk); + if (!list_find(uk->keys, &fk->k.base.id, (fcmp) &key_cmp)) + list_append(uk->keys, fk); } } else { /* could be a set of rkeys */ sql_ukey *uk = (sql_ukey *) nk; @@ -324,7 +325,8 @@ load_key(sql_trans *tr, sql_table *t, oi if (!uk->keys) uk->keys = list_new(tr->sa, NULL); - list_append(uk->keys, fk); + if (!list_find(uk->keys, &fk->k.base.id, (fcmp) &key_cmp)) + list_append(uk->keys, fk); fk->rkey = uk; } } @@ -1689,7 +1691,8 @@ kc_dup(sql_trans *tr, int flag, sql_kc * static sql_key * key_dup_(sql_trans *tr, int flag, sql_key *k, sql_table *t, int copy) { - sql_allocator *sa = (flag == TR_NEW && !copy)?tr->parent->sa:tr->sa; + sql_trans *ltr = (flag == TR_NEW && !copy)?tr->parent:tr; + sql_allocator *sa = ltr->sa; sql_key *nk = (k->type != fkey) ? (sql_key *) SA_ZNEW(sa, sql_ukey) : (sql_key *) SA_ZNEW(sa, sql_fkey); node *n; @@ -1732,18 +1735,24 @@ key_dup_(sql_trans *tr, int flag, sql_ke if (nk->type == fkey) { sql_fkey *fk = (sql_fkey *) nk; sql_fkey *ok = (sql_fkey *) k; - node *n; + node *n = NULL; if (ok->rkey) { - n = list_find(t->s->keys, &ok->rkey->k.base.id, (fcmp) &key_cmp); - + sql_schema *s; + + if ((s=find_sql_schema_id(ltr, ok->rkey->k.t->s->base.id)) == NULL) + s = nk->t->s; + n = list_find(s->keys, &ok->rkey->k.base.id, (fcmp) &key_cmp); if (n) { sql_ukey *uk = n->data; fk->rkey = uk; if (!uk->keys) uk->keys = list_new(sa, NULL); - list_append(uk->keys, fk); + if (!list_find(uk->keys, &fk->k.base.id, (fcmp) &key_cmp)) + list_append(uk->keys, fk); + else + assert(0); } } fk->on_delete = ok->on_delete; @@ -1755,15 +1764,20 @@ key_dup_(sql_trans *tr, int flag, sql_ke if (ok->keys) for (m = ok->keys->h; m; m = m->next) { + sql_schema *s; sql_fkey *ofk = m->data; - node *n = list_find(t->s->keys, &ofk->k.base.id, (fcmp) &key_cmp); - + node *n = NULL; + + if ((s=find_sql_schema_id(ltr, ofk->k.t->s->base.id)) == NULL) + s = nk->t->s; + n = list_find(s->keys, &ofk->k.base.id, (fcmp) &key_cmp); if (n) { sql_fkey *fk = n->data; if (!uk->keys) uk->keys = list_new(sa, NULL); - list_append(uk->keys, fk); + if (!list_find(uk->keys, &fk->k.base.id, (fcmp) &key_cmp)) + list_append(uk->keys, fk); fk->rkey = uk; } } @@ -1796,6 +1810,7 @@ sql_trans_copy_key( sql_trans *tr, sql_t if (nk->type == fkey) action = (fk->on_update<<8) + fk->on_delete; + assert( nk->type != fkey || ((sql_fkey*)nk)->rkey); table_funcs.table_insert(tr, syskey, &nk->base.id, &t->base.id, &nk->type, nk->base.name, (nk->type == fkey) ? &((sql_fkey *) nk)->rkey->k.base.id : &neg, &action); if (nk->type == fkey) @@ -2742,7 +2757,6 @@ rollforward_drop_key(sql_trans *tr, sql_ fk->rkey = NULL; } } - return LOG_OK; } @@ -3497,6 +3511,7 @@ sys_drop_key(sql_trans *tr, sql_key *k, if (k->type == fkey) { sql_fkey *fk = (sql_fkey *) k; + assert(fk->rkey); if (fk->rkey) { n = list_find_name(fk->rkey->keys, fk->k.base.name); list_remove_node(fk->rkey->keys, n); diff --git a/sql/test/BugTracker-2015/Tests/All b/sql/test/BugTracker-2015/Tests/All --- a/sql/test/BugTracker-2015/Tests/All +++ b/sql/test/BugTracker-2015/Tests/All @@ -93,4 +93,4 @@ msqldump_generates_incorrect_syntax_ON_U import-non-ascii.Bug-3864 mserver-creates-but-not-accept-column-types-decimal19-decimal39.Bug-3863 NOT_x_LIKE-triggers-too_many_nested_operators-error.Bug-3871 - +foreignkey_over_schemas.Bug-3855 diff --git a/sql/test/BugTracker-2015/Tests/foreignkey_over_schemas.Bug-3855.sql b/sql/test/BugTracker-2015/Tests/foreignkey_over_schemas.Bug-3855.sql new file mode 100644 --- /dev/null +++ b/sql/test/BugTracker-2015/Tests/foreignkey_over_schemas.Bug-3855.sql @@ -0,0 +1,8 @@ +start transaction; +create schema schema1; +create schema schema2; +create table schema1.basetable(id serial); +create table schema1.childtable(id serial, fk int references schema1.basetable(id)); +create table schema2.childtable(id serial, fk int references schema1.basetable(id)); + +rollback; diff --git a/sql/test/BugTracker-2015/Tests/foreignkey_over_schemas.Bug-3855.stable.err b/sql/test/BugTracker-2015/Tests/foreignkey_over_schemas.Bug-3855.stable.err new file mode 100644 --- /dev/null +++ b/sql/test/BugTracker-2015/Tests/foreignkey_over_schemas.Bug-3855.stable.err @@ -0,0 +1,37 @@ +stderr of test 'foreignkey_over_schemas.Bug-3855` in directory 'sql/test/BugTracker-2015` itself: + + +# 14:43:33 > +# 14:43:33 > "mserver5" "--debug=10" "--set" "gdk_nr_threads=0" "--set" "mapi_open=true" "--set" "mapi_port=31614" "--set" "mapi_usock=/var/tmp/mtest-3477/.s.monetdb.31614" "--set" "monet_prompt=" "--forcemito" "--set" "mal_listing=2" "--dbpath=/home/niels/scratch/rc-monetdb/Linux-x86_64/var/MonetDB/mTests_sql_test_BugTracker-2015" "--set" "mal_listing=0" "--set" "embedded_r=yes" +# 14:43:33 > + +# builtin opt gdk_dbpath = /home/niels/scratch/rc-monetdb/Linux-x86_64/var/monetdb5/dbfarm/demo +# builtin opt gdk_debug = 0 +# builtin opt gdk_vmtrim = no +# builtin opt monet_prompt = > +# builtin opt monet_daemon = no +# builtin opt mapi_port = 50000 +# builtin opt mapi_open = false +# builtin opt mapi_autosense = false +# builtin opt sql_optimizer = default_pipe +# builtin opt sql_debug = 0 +# cmdline opt gdk_nr_threads = 0 +# cmdline opt mapi_open = true +# cmdline opt mapi_port = 31614 +# cmdline opt mapi_usock = /var/tmp/mtest-3477/.s.monetdb.31614 +# cmdline opt monet_prompt = +# cmdline opt mal_listing = 2 +# cmdline opt gdk_dbpath = /home/niels/scratch/rc-monetdb/Linux-x86_64/var/MonetDB/mTests_sql_test_BugTracker-2015 +# cmdline opt mal_listing = 0 +# cmdline opt embedded_r = yes +# cmdline opt gdk_debug = 536870922 + +# 14:43:34 > +# 14:43:34 > "mclient" "-lsql" "-ftest" "-Eutf-8" "-i" "-e" "--host=/var/tmp/mtest-3477" "--port=31614" +# 14:43:34 > + + +# 14:43:34 > +# 14:43:34 > "Done." +# 14:43:34 > + diff --git a/sql/test/BugTracker-2015/Tests/foreignkey_over_schemas.Bug-3855.stable.out b/sql/test/BugTracker-2015/Tests/foreignkey_over_schemas.Bug-3855.stable.out new file mode 100644 --- /dev/null +++ b/sql/test/BugTracker-2015/Tests/foreignkey_over_schemas.Bug-3855.stable.out @@ -0,0 +1,43 @@ +stdout of test 'foreignkey_over_schemas.Bug-3855` in directory 'sql/test/BugTracker-2015` itself: + + +# 14:43:33 > +# 14:43:33 > "mserver5" "--debug=10" "--set" "gdk_nr_threads=0" "--set" "mapi_open=true" "--set" "mapi_port=31614" "--set" "mapi_usock=/var/tmp/mtest-3477/.s.monetdb.31614" "--set" "monet_prompt=" "--forcemito" "--set" "mal_listing=2" "--dbpath=/home/niels/scratch/rc-monetdb/Linux-x86_64/var/MonetDB/mTests_sql_test_BugTracker-2015" "--set" "mal_listing=0" "--set" "embedded_r=yes" +# 14:43:33 > + +# MonetDB 5 server v11.21.12 +# This is an unreleased version +# Serving database 'mTests_sql_test_BugTracker-2015', using 4 threads +# Compiled for x86_64-unknown-linux-gnu/64bit with 64bit OIDs and 128bit integers dynamically linked +# Found 7.333 GiB available main-memory. +# Copyright (c) 1993-July 2008 CWI. +# Copyright (c) August 2008-2015 MonetDB B.V., all rights reserved +# Visit http://www.monetdb.org/ for further information +# Listening for connection requests on mapi:monetdb://localhost.nes.nl:31614/ +# Listening for UNIX domain connection requests on mapi:monetdb:///var/tmp/mtest-3477/.s.monetdb.31614 +# MonetDB/GIS module loaded +# Start processing logs sql/sql_logs version 52200 +# Start reading the write-ahead log 'sql_logs/sql/log.59' +# Finished reading the write-ahead log 'sql_logs/sql/log.59' +# Finished processing logs sql/sql_logs +# MonetDB/SQL module loaded +# MonetDB/R module loaded + +Ready. + +# 14:43:34 > +# 14:43:34 > "mclient" "-lsql" "-ftest" "-Eutf-8" "-i" "-e" "--host=/var/tmp/mtest-3477" "--port=31614" +# 14:43:34 > + +#start transaction; +#create schema schema1; +#create schema schema2; +#create table schema1.basetable(id serial); +#create table schema1.childtable(id serial, fk int references schema1.basetable(id)); +#create table schema2.childtable(id serial, fk int references schema1.basetable(id)); +#rollback; + +# 14:43:34 > +# 14:43:34 > "Done." +# 14:43:34 > + _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list