Changeset: 990c7202b0e8 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/990c7202b0e8
Modified Files:
        sql/backends/monet5/sql_scenario.c
        sql/backends/monet5/sql_scenario.h
        sql/common/sql_backend.c
        sql/common/sql_backend.h
        sql/include/sql_catalog.h
        sql/server/sql_mvc.h
        sql/server/sql_qc.c
        sql/storage/store.c
        sql/test/miscellaneous/Tests/simple_selects.test
Branch: sqlfuncfix
Log Message:

When a SQL function gets destroyed, delete corresponding backend code so it 
won't leak. Extended backend call to pass a module name to retrieve the 
function from


diffs (196 lines):

diff --git a/sql/backends/monet5/sql_scenario.c 
b/sql/backends/monet5/sql_scenario.c
--- a/sql/backends/monet5/sql_scenario.c
+++ b/sql/backends/monet5/sql_scenario.c
@@ -77,13 +77,22 @@ int SQLdebug = 0;
 static const char *sqlinit = NULL;
 static MT_Lock sql_contextLock = MT_LOCK_INITIALIZER(sql_contextLock);
 
+/* if 'mod' not NULL, use it otherwise get the module from the client id */
 static void
-monet5_freecode(int clientid, const char *name)
+monet5_freecode(const char *mod, int clientid, const char *name)
 {
-       str msg;
+       Module m = NULL;
+       str msg = MAL_SUCCEED;
 
-       msg = SQLCacheRemove(MCgetClient(clientid), name);
-       if (msg)
+       if (mod) {
+               m = getModule(putName(mod));
+       } else {
+               Client c = MCgetClient(clientid);
+               if (c)
+                       m = c->usermodule;
+       }
+
+       if (m && (msg = SQLCacheRemove(m, name)))
                freeException(msg);     /* do something with error? */
 }
 
@@ -1322,14 +1331,12 @@ SQLengine(Client c)
 }
 
 str
-SQLCacheRemove(Client c, const char *nme)
+SQLCacheRemove(Module m, const char *nme)
 {
-       Symbol s;
-
-       s = findSymbolInModule(c->usermodule, nme);
+       Symbol s = findSymbolInModule(m, nme);
        if (s == NULL)
                throw(MAL, "cache.remove", SQLSTATE(42000) "internal error, 
symbol missing\n");
-       deleteSymbol(c->usermodule, s);
+       deleteSymbol(m, s);
        return MAL_SUCCEED;
 }
 
diff --git a/sql/backends/monet5/sql_scenario.h 
b/sql/backends/monet5/sql_scenario.h
--- a/sql/backends/monet5/sql_scenario.h
+++ b/sql/backends/monet5/sql_scenario.h
@@ -31,7 +31,7 @@ extern str handle_error(mvc *m, int psta
 extern str SQLstatement(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr 
pci);
 extern str SQLcompile(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
 extern str SQLinclude(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
-extern str SQLCacheRemove(Client c, const char *nme);
+extern str SQLCacheRemove(Module m, const char *nme);
 sql5_export str SQLescapeString(str s);
 
 extern str SYSupdate_tables(Client cntxt, MalBlkPtr mb, MalStkPtr stk, 
InstrPtr pci);
diff --git a/sql/common/sql_backend.c b/sql/common/sql_backend.c
--- a/sql/common/sql_backend.c
+++ b/sql/common/sql_backend.c
@@ -28,10 +28,10 @@
 backend_functions be_funcs;
 
 void
-backend_freecode(int clientid, const char *name)
+backend_freecode(const char *mod, int clientid, const char *name)
 {
        if (be_funcs.fcode != NULL)
-               be_funcs.fcode(clientid, name);
+               be_funcs.fcode(mod, clientid, name);
 }
 
 char *
diff --git a/sql/common/sql_backend.h b/sql/common/sql_backend.h
--- a/sql/common/sql_backend.h
+++ b/sql/common/sql_backend.h
@@ -13,7 +13,7 @@
 #include "sql_catalog.h"
 #include "sql_relation.h"
 
-typedef void (*freecode_fptr) (int clientid, const char *name);
+typedef void (*freecode_fptr) (const char *mod, int clientid, const char 
*name);
 
 typedef char *(*create_user_fptr) (ptr mvc, char *user, char *passwd, char 
enc, char *fullname, sqlid schema_id, char *schema_path, sqlid grantor_id);
 typedef int  (*drop_user_fptr) (ptr mvc, char *user);
@@ -44,7 +44,7 @@ typedef struct _backend_functions {
        create_sub_backend sub_backend;
 } backend_functions;
 
-extern void backend_freecode(int clientid, const char *name);
+extern void backend_freecode(const char *mod, int clientid, const char *name);
 
 extern char *backend_create_user(ptr mvc, char *user, char *passwd, char enc, 
char *fullname, sqlid defschemid, char *schema_path, sqlid grantor);
 extern int  backend_drop_user(ptr mvc, char *user);
diff --git a/sql/include/sql_catalog.h b/sql/include/sql_catalog.h
--- a/sql/include/sql_catalog.h
+++ b/sql/include/sql_catalog.h
@@ -16,6 +16,9 @@
 #include "stream.h"
 #include "matomic.h"
 
+#define sql_shared_module_name "sql"
+#define sql_private_module_name "user"
+
 #define tr_none                0
 #define tr_readonly    1
 #define tr_writable    2
diff --git a/sql/server/sql_mvc.h b/sql/server/sql_mvc.h
--- a/sql/server/sql_mvc.h
+++ b/sql/server/sql_mvc.h
@@ -67,9 +67,6 @@
 #define mod_explain    4
 #define mod_exec       8
 
-#define sql_shared_module_name "sql"
-#define sql_private_module_name "user"
-
 typedef struct sql_groupby_expression {
        symbol *sdef;
        tokens token;
diff --git a/sql/server/sql_qc.c b/sql/server/sql_qc.c
--- a/sql/server/sql_qc.c
+++ b/sql/server/sql_qc.c
@@ -31,7 +31,7 @@ static void
 cq_delete(int clientid, cq *q)
 {
        if (q->name)
-               backend_freecode(clientid, q->name);
+               backend_freecode(NULL, clientid, q->name);
        /* q, params and name are allocated using sa, ie need to be delete last 
*/
        if (q->sa)
                sa_destroy(q->sa);
diff --git a/sql/storage/store.c b/sql/storage/store.c
--- a/sql/storage/store.c
+++ b/sql/storage/store.c
@@ -124,6 +124,10 @@ func_destroy(sqlstore *store, sql_func *
        assert(f->base.refcnt > 0);
        if (--(f->base.refcnt) > 0)
                return;
+       if (f->lang == FUNC_LANG_SQL && f->instantiated) {
+               /* clean backend code */
+               backend_freecode(sql_shared_module_name, 0, f->imp);
+       }
        if (f->res)
                list_destroy2(f->res, store);
        list_destroy2(f->ops, store);
@@ -3274,8 +3278,12 @@ store_reset_sql_functions(sql_trans *tr,
                sql_func *f = sql_trans_find_func(tr, fid); /* could have 
changed by depending changes */
                /* if it is on the same transaction, then don't dup it again */
                if (isNew(f) || os_obj_intransaction(f->s->funcs, tr, 
&f->base)) {
-                       f->instantiated = 0;
-                       _DELETE(f->imp);
+                       if (f->instantiated) {
+                               /* clean backend code */
+                               backend_freecode(sql_shared_module_name, 0, 
f->imp);
+                               f->instantiated = FALSE;
+                               _DELETE(f->imp);
+                       }
                } else if ((res = func_dup(tr, f, f->s))) {
                        store->table_api.rids_destroy(joined);
                        return res;
diff --git a/sql/test/miscellaneous/Tests/simple_selects.test 
b/sql/test/miscellaneous/Tests/simple_selects.test
--- a/sql/test/miscellaneous/Tests/simple_selects.test
+++ b/sql/test/miscellaneous/Tests/simple_selects.test
@@ -869,3 +869,28 @@ select json 'iamwrongjson'
 statement error
 select inet '192.168.1.0/26 thisstringshouldnotbehere'
 
+statement ok
+create function dosomething() returns int begin return 1; end
+
+query I rowsort
+select dosomething()
+----
+1
+
+statement ok
+start transaction
+
+statement ok
+drop function dosomething
+
+statement ok
+rollback
+
+# make sure the function has backend set if the transaction has to rollback
+query I rowsort
+select dosomething()
+----
+1
+
+statement ok
+drop function dosomething
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to