Changeset: 04856e162497 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/04856e162497
Modified Files:
        sql/storage/store.c
        sql/test/sql_xml/Tests/cleanupfuncs.test
Branch: Jan2022
Log Message:

Fixed drop cascade for type dependencies. The depedency is the other way 
around. Also make sure type depedencies are cleaned when a column or function 
is dropped


diffs (206 lines):

diff --git a/sql/storage/store.c b/sql/storage/store.c
--- a/sql/storage/store.c
+++ b/sql/storage/store.c
@@ -4047,6 +4047,20 @@ sql_trans_commit(sql_trans *tr)
        return (ok==LOG_OK)?SQL_OK:SQL_ERR;
 }
 
+static sql_table *
+find_table_by_columnid(sql_trans *tr, const char *schema, sqlid id)
+{
+       sqlstore *store = tr->store;
+       sql_table *syscolumn = find_sql_table(tr, find_sql_schema(tr, schema), 
"_columns");
+
+       oid rid = store->table_api.column_find_row(tr, 
find_sql_column(syscolumn, "id"), &id, NULL);
+       if (!is_oid_nil(rid)) {
+               sqlid tid = store->table_api.column_find_sqlid(tr, 
find_sql_column(syscolumn, "table_id"), rid);
+               return sql_trans_find_table(tr, tid);
+       }
+       return NULL;
+}
+
 static int
 sql_trans_drop_all_dependencies(sql_trans *tr, sqlid id, sql_dependency type)
 {
@@ -4080,7 +4094,9 @@ sql_trans_drop_all_dependencies(sql_tran
                                case COLUMN_DEPENDENCY: {
                                        if ((t_id = 
sql_trans_get_dependency_type(tr, dep_id, TABLE_DEPENDENCY)) > 0) {
                                                sql_table *t = 
sql_trans_find_table(tr, dep_id);
-                                               if (t)
+                                               if (t && ol_length(t->columns) 
== 1) /* only column left, drop the table instead */
+                                                       res = 
sql_trans_drop_table_id(tr, t->s, t->base.id, DROP_CASCADE);
+                                               else if (t)
                                                        res = 
sql_trans_drop_column(tr, t, dep_id, DROP_CASCADE);
                                        }
                                        } break;
@@ -4103,11 +4119,24 @@ sql_trans_drop_all_dependencies(sql_tran
                                case PROC_DEPENDENCY:
                                case FUNC_DEPENDENCY: {
                                        sql_func *f = sql_trans_find_func(tr, 
dep_id);
-                                       res = sql_trans_drop_func(tr, f->s, 
dep_id, DROP_CASCADE);
+                                       if (f)
+                                               res = sql_trans_drop_func(tr, 
f->s, dep_id, DROP_CASCADE);
                                        } break;
                                case TYPE_DEPENDENCY: {
-                                       sql_type *t = sql_trans_find_type(tr, 
NULL, dep_id);
-                                       res = sql_trans_drop_type(tr, t->s, 
dep_id, DROP_CASCADE);
+                                       /* Unlike other dependencies, for type 
dependencies,
+                                          the dependent object depends on the 
type, rather the other way around.
+                                          At this moment, only functions or 
columns depend on types, so try both */
+                                       sql_table *t = NULL;
+                                       sql_func *f = sql_trans_find_func(tr, 
dep_id);
+                                       if (f) {
+                                               res = sql_trans_drop_func(tr, 
f->s, dep_id, DROP_CASCADE);
+                                       } else if ((t = 
find_table_by_columnid(tr, "sys", dep_id)) ||
+                                                          (t = 
find_table_by_columnid(tr, "tmp", dep_id))) {
+                                               if (ol_length(t->columns) == 1) 
/* only column left, drop the table instead */
+                                                       res = 
sql_trans_drop_table_id(tr, t->s, t->base.id, DROP_CASCADE);
+                                               else
+                                                       res = 
sql_trans_drop_column(tr, t, dep_id, DROP_CASCADE);
+                                       }
                                        } break;
                                case USER_DEPENDENCY:  /*TODO schema and users 
dependencies*/
                                        break;
@@ -4425,7 +4454,7 @@ sys_drop_column(sql_trans *tr, sql_colum
 
        if (drop_action && (res = sql_trans_drop_all_dependencies(tr, 
col->base.id, COLUMN_DEPENDENCY)))
                return res;
-       if (col->type.type->s && (res = sql_trans_drop_dependency(tr, 
col->base.id, col->type.type->base.id, TYPE_DEPENDENCY)))
+       if (col->type.type->s && (res = sql_trans_drop_dependency(tr, 
col->type.type->base.id, col->base.id, TYPE_DEPENDENCY)))
                return res;
        return res;
 }
@@ -4689,6 +4718,22 @@ sys_drop_func(sql_trans *tr, sql_func *f
 
        if (drop_action && (res = sql_trans_drop_all_dependencies(tr, 
func->base.id, !IS_PROC(func) ? FUNC_DEPENDENCY : PROC_DEPENDENCY)))
                return res;
+       if (!func->vararg && func->ops) {
+               for (node *n = func->ops->h; n; n = n->next) {
+                       sql_arg *a = n->data;
+
+                       if (a->type.type->s && (res = 
sql_trans_drop_dependency(tr, a->type.type->base.id, func->base.id, 
TYPE_DEPENDENCY)))
+                               return res;
+               }
+       }
+       if (!func->varres && func->res) {
+               for (node *n = func->res->h; n; n = n->next) {
+                       sql_arg *a = n->data;
+
+                       if (a->type.type->s && (res = 
sql_trans_drop_dependency(tr, a->type.type->base.id, func->base.id, 
TYPE_DEPENDENCY)))
+                               return res;
+               }
+       }
        return res;
 }
 
diff --git a/sql/test/sql_xml/Tests/cleanupfuncs.test 
b/sql/test/sql_xml/Tests/cleanupfuncs.test
--- a/sql/test/sql_xml/Tests/cleanupfuncs.test
+++ b/sql/test/sql_xml/Tests/cleanupfuncs.test
@@ -1,3 +1,5 @@
+# Also testing dependencies on types
+
 statement error 42000!DROP TYPE: unable to drop type xml (there are database 
objects which depend on it)
 DROP TYPE xml
 
@@ -10,22 +12,96 @@ DROP FUNCTION str(xml)
 statement ok
 DROP FUNCTION "comment"(STRING)
 
+statement ok
+CREATE TABLE x (x XML)
+
+statement ok
+CREATE TABLE y (x XML, y XML)
+
+statement ok
+CREATE TABLE z (x XML, y XML, z INT)
+
+statement ok
+CREATE INDEX z1 ON z(x)
+
+statement ok
+CREATE INDEX z2 ON z(x,y)
+
+statement ok
+CREATE INDEX z3 ON z(y,z)
+
+statement ok
+CREATE INDEX z4 ON z(z)
+
+statement ok rowcount 1
+INSERT INTO z VALUES (NULL, NULL, 1)
+
+query T nosort
+SELECT "sqlname" FROM "types" WHERE "sqlname" = 'xml'
+----
+xml
+
+query T nosort
+SELECT "name" FROM "sys"."tables" WHERE "name" IN ('x', 'y', 'z')
+----
+x
+y
+z
+
+query TTI nosort
+SELECT * FROM z
+----
+NULL
+NULL
+1
+
+query T nosort
+SELECT "name" FROM "sys"."idxs" WHERE "name" IN ('z1', 'z2', 'z3', 'z4')
+----
+z1
+z2
+z3
+z4
 
 -- quicker way to drop all functions which use xml datatype
 statement ok
 DROP TYPE xml CASCADE
 
+query T nosort
+SELECT "sqlname" FROM "types" WHERE "sqlname" = 'xml'
+----
 
--- cleanup remainder of created functions which do not rely on xml datatype
-statement ok
-DROP FUNCTION parse (STRING, STRING, STRING)
+query T nosort
+SELECT "name" FROM "sys"."tables" WHERE "name" IN ('x', 'y', 'z')
+----
+z
+
+query I nosort
+SELECT * FROM z
+----
+1
+
+query T nosort
+SELECT "name" FROM "sys"."idxs" WHERE "name" IN ('z1', 'z2', 'z3', 'z4')
+----
+z4
 
 statement ok
-DROP FUNCTION pi (STRING, STRING)
+DROP INDEX z4
 
 statement ok
+DROP TABLE z
+
+-- these functions return xml so they depend on it and were removed by the 
drop cascade statement
+statement error 42000!DROP FUNCTION: no such function 'parse' (clob, clob, 
clob)
+DROP FUNCTION parse (STRING, STRING, STRING)
+
+statement error 42000!DROP FUNCTION: no such function 'pi' (clob, clob)
+DROP FUNCTION pi (STRING, STRING)
+
+statement error 42000!DROP FUNCTION: no such function 'attribute' (clob, clob)
 DROP FUNCTION attribute (STRING, STRING)
 
-statement ok
+statement error 42000!DROP FUNCTION: no such function 'isdocument' (clob)
 DROP FUNCTION isdocument (STRING)
 
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to