Changeset: ecbd31cf12c8 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=ecbd31cf12c8
Added Files:
        sql/test/Tests/drop-function-if-exists.sql
        sql/test/Tests/drop-function-if-exists.stable.err
        sql/test/Tests/drop-function-if-exists.stable.out
        sql/test/Tests/drop-trigger-if-exists.sql
        sql/test/Tests/drop-trigger-if-exists.stable.err
        sql/test/Tests/drop-trigger-if-exists.stable.out
Modified Files:
        clients/mapiclient/mhelp.c
        monetdb5/modules/mal/wlc.mal
        sql/backends/monet5/sql_cat.c
        sql/backends/monet5/sqlcatalog.mal
        sql/backends/monet5/wlr.mal
        sql/server/rel_psm.c
        sql/server/rel_psm.h
        sql/server/rel_schema.c
        sql/server/sql_parser.y
        sql/test/Tests/All
Branch: sqlextra
Log Message:

Drop UDFs and triggers if they exist


diffs (truncated from 768 to 300 lines):

diff --git a/clients/mapiclient/mhelp.c b/clients/mapiclient/mhelp.c
--- a/clients/mapiclient/mhelp.c
+++ b/clients/mapiclient/mhelp.c
@@ -266,13 +266,13 @@ SQLhelp sqlhelp[] = {
        {"DROP AGGREGATE",
         "",
         "DROP ALL AGGREGATE qname [ RESTRICT | CASCADE ]\n"
-        "DROP AGGREGATE qname [ '(' [ param [',' ...]] ')' ] [ RESTRICT | 
CASCADE ]",
+        "DROP AGGREGATE [ IF EXISTS ] qname [ '(' [ param [',' ...]] ')' ] [ 
RESTRICT | CASCADE ]",
         NULL,
         NULL},
        {"DROP FUNCTION",
         "",
         "DROP ALL [FILTER] FUNCTION qname [ RESTRICT | CASCADE ]\n"
-        "DROP [FILTER] FUNCTION qname [ '(' [ param [',' ...]] ')' ] [ 
RESTRICT | CASCADE ]",
+        "DROP [FILTER] FUNCTION [ IF EXISTS ] qname [ '(' [ param [',' ...]] 
')' ] [ RESTRICT | CASCADE ]",
         NULL,
         NULL},
        {"DROP INDEX",
@@ -283,13 +283,13 @@ SQLhelp sqlhelp[] = {
        {"DROP LOADER",
         "",
         "DROP ALL LOADER qname [ RESTRICT | CASCADE ]\n"
-        "DROP LOADER qname [ '(' [ param [',' ...]] ')' ] [ RESTRICT | CASCADE 
]",
+        "DROP LOADER [ IF EXISTS ] qname [ '(' [ param [',' ...]] ')' ] [ 
RESTRICT | CASCADE ]",
         NULL,
         NULL},
        {"DROP PROCEDURE",
         "",
         "DROP ALL PROCEDURE qname [ RESTRICT | CASCADE ]\n"
-        "DROP PROCEDURE qname [ '(' [ param [',' ...]] ')' ] [ RESTRICT | 
CASCADE ]",
+        "DROP PROCEDURE [ IF EXISTS ] qname [ '(' [ param [',' ...]] ')' ] [ 
RESTRICT | CASCADE ]",
         NULL,
         NULL},
        {"DROP ROLE",
@@ -314,7 +314,7 @@ SQLhelp sqlhelp[] = {
         NULL},
        {"DROP TRIGGER",
         "",
-        "DROP TRIGGER qname",
+        "DROP TRIGGER [ IF EXISTS ] qname",
         NULL,
         NULL},
        {"DROP TYPE",
diff --git a/monetdb5/modules/mal/wlc.mal b/monetdb5/modules/mal/wlc.mal
--- a/monetdb5/modules/mal/wlc.mal
+++ b/monetdb5/modules/mal/wlc.mal
@@ -206,7 +206,7 @@ pattern create_trigger( sname:str, tname
 address WLCgeneric
 comment "Catalog operation create_trigger";
 
-pattern drop_trigger(sname:str,nme:str )
+pattern drop_trigger(sname:str, nme:str, ifexists:int)
 address WLCgeneric
 comment "Catalog operation drop_trigger";
 
diff --git a/sql/backends/monet5/sql_cat.c b/sql/backends/monet5/sql_cat.c
--- a/sql/backends/monet5/sql_cat.c
+++ b/sql/backends/monet5/sql_cat.c
@@ -226,7 +226,7 @@ create_trigger(mvc *sql, char *sname, ch
 }
 
 static char *
-drop_trigger(mvc *sql, char *sname, char *tname)
+drop_trigger(mvc *sql, char *sname, char *tname, int if_exists)
 {
        sql_trigger *tri = NULL;
        sql_schema *s = NULL;
@@ -239,8 +239,11 @@ drop_trigger(mvc *sql, char *sname, char
        if (!mvc_schema_privs(sql, s))
                throw(SQL,"sql.drop_trigger",SQLSTATE(3F000) "DROP TRIGGER: 
access denied for %s to schema ;'%s'", stack_get_string(sql, "current_user"), 
s->base.name);
 
-       if ((tri = mvc_bind_trigger(sql, s, tname)) == NULL)
+       if ((tri = mvc_bind_trigger(sql, s, tname)) == NULL) {
+               if(if_exists)
+                       return MAL_SUCCEED;
                throw(SQL,"sql.drop_trigger", SQLSTATE(3F000) "DROP TRIGGER: 
unknown trigger %s\n", tname);
+       }
        mvc_drop_trigger(sql, s, tri);
        return MAL_SUCCEED;
 }
@@ -476,7 +479,9 @@ drop_func(mvc *sql, char *sname, char *n
 
                        mvc_drop_func(sql, s, func, action);
                }
-       } else {
+       } else if(fid == -2) { //if exists option
+               return MAL_SUCCEED;
+       } else { //fid == -1
                node *n = NULL;
                list *list_func = schema_bind_func(sql, s, name, type);
 
@@ -1258,9 +1263,10 @@ SQLdrop_trigger(Client cntxt, MalBlkPtr 
        str msg;
        str sname = *getArgReference_str(stk, pci, 1); 
        char *triggername = *getArgReference_str(stk, pci, 2);
+       int if_exists = *getArgReference_int(stk, pci, 3);
 
        initcontext();
-       msg = drop_trigger(sql, sname, triggername);
+       msg = drop_trigger(sql, sname, triggername, if_exists);
        return msg;
 }
 
diff --git a/sql/backends/monet5/sqlcatalog.mal 
b/sql/backends/monet5/sqlcatalog.mal
--- a/sql/backends/monet5/sqlcatalog.mal
+++ b/sql/backends/monet5/sqlcatalog.mal
@@ -119,7 +119,7 @@ pattern drop_index( sname:str, iname:str
 address SQLdrop_index 
 comment "Catalog operation drop_index";
 
-pattern drop_function( sname:str, fname:str, fid:int, type:int, action:int) 
+pattern drop_function( sname:str, fname:str, fid:int, type:int, action:int)
 address SQLdrop_function 
 comment "Catalog operation drop_function";
 
@@ -131,7 +131,7 @@ pattern create_trigger( sname:str, tname
 address SQLcreate_trigger 
 comment "Catalog operation create_trigger";
 
-pattern drop_trigger(sname:str,nme:str ) 
+pattern drop_trigger(sname:str, nme:str, ifexists:int)
 address SQLdrop_trigger 
 comment "Catalog operation drop_trigger";
 
diff --git a/sql/backends/monet5/wlr.mal b/sql/backends/monet5/wlr.mal
--- a/sql/backends/monet5/wlr.mal
+++ b/sql/backends/monet5/wlr.mal
@@ -211,7 +211,7 @@ pattern create_trigger( sname:str, tname
 address WLRgeneric
 comment "Catalog operation create_trigger";
 
-pattern drop_trigger(sname:str,nme:str )
+pattern drop_trigger(sname:str, nme:str, ifexists:int)
 address WLRgeneric
 comment "Catalog operation drop_trigger";
 
diff --git a/sql/server/rel_psm.c b/sql/server/rel_psm.c
--- a/sql/server/rel_psm.c
+++ b/sql/server/rel_psm.c
@@ -984,7 +984,7 @@ rel_drop_function(sql_allocator *sa, con
 }
 
 sql_func *
-resolve_func( mvc *sql, sql_schema *s, const char *name, dlist *typelist, int 
type, char *op) 
+resolve_func( mvc *sql, sql_schema *s, const char *name, dlist *typelist, int 
type, char *op, int if_exists)
 {
        sql_func *func = NULL;
        list *list_func = NULL, *type_list = NULL;
@@ -1018,13 +1018,13 @@ resolve_func( mvc *sql, sql_schema *s, c
                        func = (sql_func*) list_func->h->data;
        }
 
-       if (!func) { 
+       if (!func) {
+               void *e = NULL;
                if (typelist) {
                        char *arg_list = NULL;
                        node *n;
                        
                        if (type_list->cnt > 0) {
-                               void *e;
                                for (n = type_list->h; n; n = n->next) {
                                        char *tpe =  
subtype2string((sql_subtype *) n->data);
                                
@@ -1039,16 +1039,21 @@ resolve_func( mvc *sql, sql_schema *s, c
                                }
                                list_destroy(list_func);
                                list_destroy(type_list);
-                               e = sql_error(sql, 02, SQLSTATE(42000) "%s 
%s%s: no such %s%s '%s' (%s)", op, KF, F, kf, f, name, arg_list);
+                               if(!if_exists)
+                                       e = sql_error(sql, 02, SQLSTATE(42000) 
"%s %s%s: no such %s%s '%s' (%s)", op, KF, F, kf, f, name, arg_list);
                                _DELETE(arg_list);
                                return e;
                        }
                        list_destroy(list_func);
                        list_destroy(type_list);
-                       return sql_error(sql, 02, SQLSTATE(42000) "%s %s%s: no 
such %s%s '%s' ()", op, KF, F, kf, f, name);
+                       if(!if_exists)
+                               e = sql_error(sql, 02, SQLSTATE(42000) "%s 
%s%s: no such %s%s '%s' ()", op, KF, F, kf, f, name);
+                       return e;
 
                } else {
-                       return sql_error(sql, 02, SQLSTATE(42000) "%s %s%s: no 
such %s%s '%s'", op, KF, F, kf, f, name);
+                       if(!if_exists)
+                               e = sql_error(sql, 02, SQLSTATE(42000) "%s 
%s%s: no such %s%s '%s'", op, KF, F, kf, f, name);
+                       return e;
                }
        } else if (((is_func && type != F_FILT) && !func->res) || 
                   (!is_func && func->res)) {
@@ -1063,7 +1068,7 @@ resolve_func( mvc *sql, sql_schema *s, c
 }
 
 static sql_rel* 
-rel_drop_func(mvc *sql, dlist *qname, dlist *typelist, int drop_action, int 
type)
+rel_drop_func(mvc *sql, dlist *qname, dlist *typelist, int drop_action, int 
type, int if_exists)
 {
        const char *name = qname_table(qname);
        const char *sname = qname_schema(qname);
@@ -1081,13 +1086,15 @@ rel_drop_func(mvc *sql, dlist *qname, dl
        if (s == NULL) 
                s =  cur_schema(sql);
        
-       func = resolve_func(sql, s, name, typelist, type, "DROP");
+       func = resolve_func(sql, s, name, typelist, type, "DROP", if_exists);
        if (!func && !sname) {
                s = tmp_schema(sql);
-               func = resolve_func(sql, s, name, typelist, type, "DROP");
+               func = resolve_func(sql, s, name, typelist, type, "DROP", 
if_exists);
        }
        if (func)
                return rel_drop_function(sql->sa, s->base.name, name, 
func->base.id, type, drop_action);
+       else if(if_exists && !sql->session->status)
+               return rel_drop_function(sql->sa, s->base.name, name, -2, type, 
drop_action);
        return NULL;
 }
 
@@ -1276,7 +1283,7 @@ create_trigger(mvc *sql, dlist *qname, i
 }
 
 static sql_rel *
-rel_drop_trigger(mvc *sql, const char *sname, const char *tname)
+rel_drop_trigger(mvc *sql, const char *sname, const char *tname, int if_exists)
 {
        sql_rel *rel = rel_create(sql->sa);
        list *exps = new_exp_list(sql->sa);
@@ -1285,6 +1292,7 @@ rel_drop_trigger(mvc *sql, const char *s
 
        append(exps, exp_atom_str(sql->sa, sname, sql_bind_localtype("str") ));
        append(exps, exp_atom_str(sql->sa, tname, sql_bind_localtype("str") ));
+       append(exps, exp_atom_int(sql->sa, if_exists));
        rel->l = NULL;
        rel->r = NULL;
        rel->op = op_ddl;
@@ -1296,7 +1304,7 @@ rel_drop_trigger(mvc *sql, const char *s
 }
 
 static sql_rel *
-drop_trigger(mvc *sql, dlist *qname)
+drop_trigger(mvc *sql, dlist *qname, int if_exists)
 {
        const char *sname = qname_schema(qname);
        const char *tname = qname_table(qname);
@@ -1310,7 +1318,7 @@ drop_trigger(mvc *sql, dlist *qname)
 
        if (!mvc_schema_privs(sql, ss)) 
                return sql_error(sql, 02, SQLSTATE(3F000) "DROP TRIGGER: access 
denied for %s to schema ;'%s'", stack_get_string(sql, "current_user"), 
ss->base.name);
-       return rel_drop_trigger(sql, ss->base.name, tname);
+       return rel_drop_trigger(sql, ss->base.name, tname, if_exists);
 }
 
 static sql_rel *
@@ -1441,16 +1449,18 @@ rel_psm(mvc *sql, symbol *s)
                dlist *qname = l->h->data.lval;
                dlist *typelist = l->h->next->data.lval;
                int type = l->h->next->next->data.i_val;
-               int all = l->h->next->next->next->data.i_val;
-               int drop_action = l->h->next->next->next->next->data.i_val;
+               int if_exists = l->h->next->next->next->data.i_val;
+               int all = l->h->next->next->next->next->data.i_val;
+               int drop_action = 
l->h->next->next->next->next->next->data.i_val;
 
                if (STORE_READONLY) 
                        return sql_error(sql, 06, SQLSTATE(42000) "Schema 
statements cannot be executed on a readonly database.");
                        
                if (all)
                        ret = rel_drop_all_func(sql, qname, drop_action, type);
-               else
-                       ret = rel_drop_func(sql, qname, typelist, drop_action, 
type);
+               else {
+                       ret = rel_drop_func(sql, qname, typelist, drop_action, 
type, if_exists);
+               }
 
                sql->type = Q_SCHEMA;
        }       break;
@@ -1488,8 +1498,10 @@ rel_psm(mvc *sql, symbol *s)
        case SQL_DROP_TRIGGER:
        {
                dlist *l = s->data.lval;
+               dlist *qname = l->h->data.lval;
+               int if_exists = l->h->next->data.i_val;
 
-               ret = drop_trigger(sql, l);
+               ret = drop_trigger(sql, qname, if_exists);
                sql->type = Q_SCHEMA;
        }
                break;
diff --git a/sql/server/rel_psm.h b/sql/server/rel_psm.h
--- a/sql/server/rel_psm.h
+++ b/sql/server/rel_psm.h
@@ -14,7 +14,7 @@
 #include "sql_symbol.h"
 #include "sql_mvc.h"
 
-extern sql_func *resolve_func( mvc *sql, sql_schema *s, const char *name, 
dlist *typelist, int type, char *op);
+extern sql_func *resolve_func( mvc *sql, sql_schema *s, const char *name, 
dlist *typelist, int type, char *op, int if_exists);
 extern sql_rel *rel_psm(mvc *sql, symbol *sym);
 extern sql_rel *rel_select_with_into( mvc *sql, symbol *sq);
 
diff --git a/sql/server/rel_schema.c b/sql/server/rel_schema.c
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to