diff --git a/wasm/wasm_executor--1.0.sql b/wasm/wasm_executor--1.0.sql index f5fc82220c99dc3e17f4a29ea12956c2aa8cd3e1..5215aa7d31c30c6237815775c87056183ed46f0c 100644 --- a/wasm/wasm_executor--1.0.sql +++ b/wasm/wasm_executor--1.0.sql @@ -47,6 +47,11 @@ RETURNS int8 AS 'MODULE_PATHNAME', 'wasm_create_instance_wat' LANGUAGE C STRICT; +CREATE FUNCTION wasm_drop_instance(int8) +RETURNS text +AS 'MODULE_PATHNAME', 'wasm_drop_instance' +LANGUAGE C STRICT; + CREATE FUNCTION wasm_invoke_function_0(text, text) RETURNS int8 AS 'MODULE_PATHNAME', 'wasm_invoke_function_0' @@ -183,7 +188,7 @@ BEGIN -- Insert the wasm information to gloable table INSERT INTO wasm.instances SELECT id, wasm_file FROM wasm_get_instances() WHERE id = current_instance_id; - INSERT INTO wasm.exported_functions SELECT current_instance_id, funcname, inputs, outputs FROM wasm_get_exported_functions(current_instance_id); + INSERT INTO wasm.exported_functions SELECT current_instance_id, namespace, funcname, inputs, outputs FROM wasm_get_exported_functions(current_instance_id); -- Generate functions for each exported functions from the WebAssembly instance. FOR @@ -238,4 +243,40 @@ BEGIN RETURN current_instance_id; END; +$$ LANGUAGE plpgsql; + + +CREATE OR REPLACE FUNCTION wasm_delete_instance(delete_instance int8) RETURNS text AS $$ +DECLARE + instance_module_path text; + exported_function RECORD; +BEGIN + -- Create a new instance, and stores its ID in `current_instance_id`. + SELECT wasm_drop_instance(delete_instance) INTO STRICT instance_module_path; + + -- Generate functions for each exported functions from the WebAssembly instance. + FOR + exported_function + IN + SELECT + namespace, + funcname, + inputs + FROM + wasm.exported_functions WHERE instanceid = delete_instance + LOOP + + EXECUTE format( + 'DROP FUNCTION %I_%I(%3$s)', + exported_function.namespace, -- 1 + exported_function.funcname, -- 2 + exported_function.inputs + ); + END LOOP; + + DELETE FROM wasm.instances WHERE id = delete_instance; + DELETE FROM wasm.exported_functions WHERE instanceid = delete_instance; + + RETURN instance_module_path; +END; $$ LANGUAGE plpgsql; \ No newline at end of file diff --git a/wasm/wasm_executor.cpp b/wasm/wasm_executor.cpp index 73b412698929010ec6e0b8c7757048e48294a970..838e406744b3aa7e995411409c560a6453ce7494 100644 --- a/wasm/wasm_executor.cpp +++ b/wasm/wasm_executor.cpp @@ -15,6 +15,7 @@ PG_MODULE_MAGIC; extern "C" Datum wasm_create_instance_wat(PG_FUNCTION_ARGS); extern "C" Datum wasm_create_instance(PG_FUNCTION_ARGS); +extern "C" Datum wasm_drop_instance(PG_FUNCTION_ARGS); extern "C" Datum wasm_get_instances(PG_FUNCTION_ARGS); extern "C" Datum wasm_get_exported_functions(PG_FUNCTION_ARGS); extern "C" Datum wasm_invoke_function_0(PG_FUNCTION_ARGS); @@ -376,6 +377,34 @@ Datum wasm_create_instance(PG_FUNCTION_ARGS) return Int64GetDatum(uuid); } +PG_FUNCTION_INFO_V1(wasm_drop_instance); +Datum wasm_drop_instance(PG_FUNCTION_ARGS) +{ + int64 instanceid = PG_GETARG_INT64(0); + Datum module_path; + + if (!superuser()) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("wasm_executor: must be system admin to delete wasm instance")))); + + std::map::iterator institor = instances.begin(); + while (institor != instances.end() && institor->first != instanceid) { + institor++; + } + if (institor == instances.end()) { + ereport(ERROR, (errmsg("wasm_executor:instance with id=%ld not exist", instanceid))); + } + module_path = CStringGetTextDatum(institor->second->wasm_file.c_str()); + instances.erase(institor); + + std::map*>::iterator funcitor = exported_functions.begin(); + while (funcitor != exported_functions.end() && funcitor->first == instanceid) { + exported_functions.erase(funcitor++); + } + + return module_path; +} + PG_FUNCTION_INFO_V1(wasm_get_instances); Datum wasm_get_instances(PG_FUNCTION_ARGS) {