Changeset: 3812616d921c for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/3812616d921c Modified Files: sql/backends/monet5/sql.c sql/backends/monet5/sql_upgrades.c sql/scripts/22_clients.sql Branch: default Log Message:
Add system function sys.unclosed_result_sets() Returns a tuple (query_id, res_id) for every unclosed result set. This is useful for checking for resource leaks in client libraries. diffs (94 lines): diff --git a/sql/backends/monet5/sql.c b/sql/backends/monet5/sql.c --- a/sql/backends/monet5/sql.c +++ b/sql/backends/monet5/sql.c @@ -3542,6 +3542,47 @@ dump_trace(Client cntxt, MalBlkPtr mb, M } static str +sql_unclosed_result_sets(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) +{ + (void)mb; + bat *ret_query_id = getArgReference_bat(stk, pci, 0); + bat *ret_res_id = getArgReference_bat(stk, pci, 1); + backend *be = cntxt->sqlcontext; + + BUN count = 0; + for (res_table *p = be->results; p != NULL; p = p->next) + count++; + + BAT *query_ids = COLnew(0, TYPE_oid, count, TRANSIENT); + BAT *res_ids = COLnew(0, TYPE_int, count, TRANSIENT); + + if (query_ids == NULL || res_ids == NULL) { + BBPreclaim(query_ids); + BBPreclaim(res_ids); + throw(SQL, "sql.sql_unclosed_result_sets", SQLSTATE(HY013) MAL_MALLOC_FAIL); + } + + for (res_table *p = be->results; p != NULL; p = p->next) { + if (BUNappend(query_ids, &p->query_id, false) != GDK_SUCCEED) + goto bailout; + if (BUNappend(res_ids, &p->id, false) != GDK_SUCCEED) + goto bailout; + } + + *ret_query_id = query_ids->batCacheid; + BBPkeepref(query_ids); + *ret_res_id = res_ids->batCacheid; + BBPkeepref(res_ids); + + return MAL_SUCCEED; + +bailout: + BBPunfix(query_ids->batCacheid); + BBPunfix(res_ids->batCacheid); + throw(SQL, "sql.sql_unclosed_result_sets", SQLSTATE(42000)"failed to retrieve result tables"); +} + +static str sql_sessions_wrap(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) { BAT *id = NULL, *user = NULL, *login = NULL, *sessiontimeout = NULL, @@ -5629,6 +5670,7 @@ static mel_func sql_init_funcs[] = { pattern("sql", "argRecord", SQLargRecord, false, "Glue together the calling sequence", args(1,2, arg("",str),varargany("a",0))), pattern("sql", "sql_variables", sql_variables, false, "return the table with session variables", args(4,4, batarg("sname",str),batarg("name",str),batarg("type",str),batarg("value",str))), pattern("sql", "sessions", sql_sessions_wrap, false, "SQL export table of active sessions, their timeouts and idle status",args(16,16,batarg("id",int),batarg("user",str),batarg("start",timestamp),batarg("idle",timestamp),batarg("optimizer",str),batarg("stimeout",int),batarg("qtimeout",int),batarg("wlimit",int),batarg("mlimit",int),batarg("language", str),batarg("peer", str),batarg("hostname", str),batarg("application", str),batarg("client", str),batarg("clientpid", lng),batarg("remark", str),)), + pattern("sql", "unclosed_result_sets", sql_unclosed_result_sets, false, "return query_id/res_id of unclosed result sets", args(2,2, batarg("query_id",oid),batarg("res_id", int))), pattern("sql", "password", SQLuser_password, false, "Return password hash of user", args(1,2, arg("",str),arg("user",str))), pattern("sql", "decypher", SQLdecypher, false, "Return decyphered password", args(1,2, arg("",str),arg("hash",str))), pattern("sql", "dump_cache", dump_cache, false, "dump the content of the query cache", args(2,2, batarg("query",str),batarg("count",int))), diff --git a/sql/backends/monet5/sql_upgrades.c b/sql/backends/monet5/sql_upgrades.c --- a/sql/backends/monet5/sql_upgrades.c +++ b/sql/backends/monet5/sql_upgrades.c @@ -4384,6 +4384,13 @@ sql_update_default(Client c, mvc *sql, s "external name sql.vacuum;\n" "create procedure sys.stop_vacuum(sname string, tname string)\n" "external name sql.stop_vacuum;\n" + "create function sys.unclosed_result_sets()\n" + "returns table(\n" + " \"query_id\" oid,\n" + " \"res_id\" int\n" + ")\n" + "external name sql.unclosed_result_sets;\n" + "grant execute on function sys.unclosed_result_sets() to public;\n" "update sys.functions set system = true where system <> true and schema_id = 2000 and name in ('vacuum', 'stop_vacuum');\n"; printf("Running database upgrade commands:\n%s\n", query); fflush(stdout); diff --git a/sql/scripts/22_clients.sql b/sql/scripts/22_clients.sql --- a/sql/scripts/22_clients.sql +++ b/sql/scripts/22_clients.sql @@ -41,6 +41,14 @@ external name sql.sessions; create view sys.sessions as select * from sys.sessions(); grant select on sys.sessions to public; +create function sys.unclosed_result_sets() +returns table( + "query_id" oid, + "res_id" int +) +external name sql.unclosed_result_sets; +grant execute on function sys.unclosed_result_sets() to public; + create procedure sys.setclientinfo(property string, value string) external name clients.setinfo; grant execute on procedure sys.setclientinfo(string, string) to public; _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org