diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c index 6e8c5c0..9eaf22b 100644 *** a/src/pl/tcl/pltcl.c --- b/src/pl/tcl/pltcl.c *************** PG_MODULE_MAGIC; *** 95,104 **** **********************************************************************/ typedef struct pltcl_interp_desc { ! Oid user_id; /* Hash key (must be first!) */ ! Tcl_Interp *interp; /* The interpreter */ ! Tcl_HashTable query_hash; /* pltcl_query_desc structs */ ! } pltcl_interp_desc; /********************************************************************** --- 95,104 ---- **********************************************************************/ typedef struct pltcl_interp_desc { ! Oid user_id; /* Hash key (must be first!) */ ! Tcl_Interp *interp; /* The interpreter */ ! Tcl_HashTable query_hash; /* pltcl_query_desc structs */ ! } pltcl_interp_desc; /********************************************************************** *************** typedef struct pltcl_proc_desc *** 118,124 **** int nargs; FmgrInfo arg_out_func[FUNC_MAX_ARGS]; bool arg_is_rowtype[FUNC_MAX_ARGS]; ! } pltcl_proc_desc; /********************************************************************** --- 118,124 ---- int nargs; FmgrInfo arg_out_func[FUNC_MAX_ARGS]; bool arg_is_rowtype[FUNC_MAX_ARGS]; ! } pltcl_proc_desc; /********************************************************************** *************** typedef struct pltcl_query_desc *** 132,138 **** Oid *argtypes; FmgrInfo *arginfuncs; Oid *argtypioparams; ! } pltcl_query_desc; /********************************************************************** --- 132,138 ---- Oid *argtypes; FmgrInfo *arginfuncs; Oid *argtypioparams; ! } pltcl_query_desc; /********************************************************************** *************** typedef struct pltcl_query_desc *** 148,167 **** **********************************************************************/ typedef struct pltcl_proc_key { ! Oid proc_id; /* Function OID */ /* * is_trigger is really a bool, but declare as Oid to ensure this struct * contains no padding */ ! Oid is_trigger; /* is it a trigger function? */ ! Oid user_id; /* User calling the function, or 0 */ ! } pltcl_proc_key; typedef struct pltcl_proc_ptr { ! pltcl_proc_key proc_key; /* Hash key (must be first!) */ pltcl_proc_desc *proc_ptr; ! } pltcl_proc_ptr; /********************************************************************** --- 148,167 ---- **********************************************************************/ typedef struct pltcl_proc_key { ! Oid proc_id; /* Function OID */ /* * is_trigger is really a bool, but declare as Oid to ensure this struct * contains no padding */ ! Oid is_trigger; /* is it a trigger function? */ ! Oid user_id; /* User calling the function, or 0 */ ! } pltcl_proc_key; typedef struct pltcl_proc_ptr { ! pltcl_proc_key proc_key; /* Hash key (must be first!) */ pltcl_proc_desc *proc_ptr; ! } pltcl_proc_ptr; /********************************************************************** *************** Datum pltcl_call_handler(PG_FUNCTION_AR *** 183,191 **** Datum pltclu_call_handler(PG_FUNCTION_ARGS); void _PG_init(void); ! static void pltcl_init_interp(pltcl_interp_desc *interp_desc, bool pltrusted); static pltcl_interp_desc *pltcl_fetch_interp(bool pltrusted); ! static void pltcl_init_load_unknown(Tcl_Interp *interp); static Datum pltcl_handler(PG_FUNCTION_ARGS, bool pltrusted); --- 183,191 ---- Datum pltclu_call_handler(PG_FUNCTION_ARGS); void _PG_init(void); ! static void pltcl_init_interp(pltcl_interp_desc * interp_desc, bool pltrusted); static pltcl_interp_desc *pltcl_fetch_interp(bool pltrusted); ! static void pltcl_init_load_unknown(Tcl_Interp * interp); static Datum pltcl_handler(PG_FUNCTION_ARGS, bool pltrusted); *************** static Datum pltcl_func_handler(PG_FUNCT *** 193,231 **** static HeapTuple pltcl_trigger_handler(PG_FUNCTION_ARGS, bool pltrusted); ! static void throw_tcl_error(Tcl_Interp *interp, const char *proname); static pltcl_proc_desc *compile_pltcl_function(Oid fn_oid, Oid tgreloid, ! bool pltrusted); ! static int pltcl_elog(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]); ! static int pltcl_quote(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]); ! static int pltcl_argisnull(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]); ! static int pltcl_returnnull(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]); ! static int pltcl_SPI_execute(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]); ! static int pltcl_process_SPI_result(Tcl_Interp *interp, CONST84 char *arrayname, CONST84 char *loop_body, int spi_rc, ! SPITupleTable *tuptable, int ntuples); ! static int pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]); ! static int pltcl_SPI_execute_plan(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]); ! static int pltcl_SPI_lastoid(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]); ! static void pltcl_set_tuple_values(Tcl_Interp *interp, CONST84 char *arrayname, int tupno, HeapTuple tuple, TupleDesc tupdesc); static void pltcl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc, ! Tcl_DString *retval); /* --- 193,231 ---- static HeapTuple pltcl_trigger_handler(PG_FUNCTION_ARGS, bool pltrusted); ! static void throw_tcl_error(Tcl_Interp * interp, const char *proname); static pltcl_proc_desc *compile_pltcl_function(Oid fn_oid, Oid tgreloid, ! bool pltrusted); ! static int pltcl_elog(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]); ! static int pltcl_quote(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]); ! static int pltcl_argisnull(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]); ! static int pltcl_returnnull(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]); ! static int pltcl_SPI_execute(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]); ! static int pltcl_process_SPI_result(Tcl_Interp * interp, CONST84 char *arrayname, CONST84 char *loop_body, int spi_rc, ! SPITupleTable * tuptable, int ntuples); ! static int pltcl_SPI_prepare(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]); ! static int pltcl_SPI_execute_plan(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]); ! static int pltcl_SPI_lastoid(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]); ! static void pltcl_set_tuple_values(Tcl_Interp * interp, CONST84 char *arrayname, int tupno, HeapTuple tuple, TupleDesc tupdesc); static void pltcl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc, ! Tcl_DString * retval); /* *************** pltcl_FinalizeNotifier(ClientData client *** 256,262 **** } static void ! pltcl_SetTimer(Tcl_Time *timePtr) { } --- 256,262 ---- } static void ! pltcl_SetTimer(Tcl_Time * timePtr) { } *************** pltcl_AlertNotifier(ClientData clientDat *** 267,273 **** static void pltcl_CreateFileHandler(int fd, int mask, ! Tcl_FileProc *proc, ClientData clientData) { } --- 267,273 ---- static void pltcl_CreateFileHandler(int fd, int mask, ! Tcl_FileProc * proc, ClientData clientData) { } *************** pltcl_ServiceModeHook(int mode) *** 282,288 **** } static int ! pltcl_WaitForEvent(Tcl_Time *timePtr) { return 0; } --- 282,288 ---- } static int ! pltcl_WaitForEvent(Tcl_Time * timePtr) { return 0; } *************** _PG_init(void) *** 390,396 **** * pltcl_init_interp() - initialize a new Tcl interpreter **********************************************************************/ static void ! pltcl_init_interp(pltcl_interp_desc *interp_desc, bool pltrusted) { Tcl_Interp *interp; char interpname[32]; --- 390,396 ---- * pltcl_init_interp() - initialize a new Tcl interpreter **********************************************************************/ static void ! pltcl_init_interp(pltcl_interp_desc * interp_desc, bool pltrusted) { Tcl_Interp *interp; char interpname[32]; *************** pltcl_fetch_interp(bool pltrusted) *** 471,477 **** * table pltcl_modules (if it exists) **********************************************************************/ static void ! pltcl_init_load_unknown(Tcl_Interp *interp) { Relation pmrel; char *pmrelname, --- 471,477 ---- * table pltcl_modules (if it exists) **********************************************************************/ static void ! pltcl_init_load_unknown(Tcl_Interp * interp) { Relation pmrel; char *pmrelname, *************** pltcl_trigger_handler(PG_FUNCTION_ARGS, *** 1126,1132 **** * throw_tcl_error - ereport an error returned from the Tcl interpreter **********************************************************************/ static void ! throw_tcl_error(Tcl_Interp *interp, const char *proname) { /* * Caution is needed here because Tcl_GetVar could overwrite the --- 1126,1132 ---- * throw_tcl_error - ereport an error returned from the Tcl interpreter **********************************************************************/ static void ! throw_tcl_error(Tcl_Interp * interp, const char *proname) { /* * Caution is needed here because Tcl_GetVar could overwrite the *************** compile_pltcl_function(Oid fn_oid, Oid t *** 1495,1501 **** * pltcl_elog() - elog() support for PLTcl **********************************************************************/ static int ! pltcl_elog(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]) { volatile int level; --- 1495,1501 ---- * pltcl_elog() - elog() support for PLTcl **********************************************************************/ static int ! pltcl_elog(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]) { volatile int level; *************** pltcl_elog(ClientData cdata, Tcl_Interp *** 1583,1589 **** * be used in SPI_execute query strings **********************************************************************/ static int ! pltcl_quote(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]) { char *tmp; --- 1583,1589 ---- * be used in SPI_execute query strings **********************************************************************/ static int ! pltcl_quote(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]) { char *tmp; *************** pltcl_quote(ClientData cdata, Tcl_Interp *** 1636,1642 **** * pltcl_argisnull() - determine if a specific argument is NULL **********************************************************************/ static int ! pltcl_argisnull(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]) { int argno; --- 1636,1642 ---- * pltcl_argisnull() - determine if a specific argument is NULL **********************************************************************/ static int ! pltcl_argisnull(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]) { int argno; *************** pltcl_argisnull(ClientData cdata, Tcl_In *** 1694,1700 **** * pltcl_returnnull() - Cause a NULL return from a function **********************************************************************/ static int ! pltcl_returnnull(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]) { FunctionCallInfo fcinfo = pltcl_current_fcinfo; --- 1694,1700 ---- * pltcl_returnnull() - Cause a NULL return from a function **********************************************************************/ static int ! pltcl_returnnull(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]) { FunctionCallInfo fcinfo = pltcl_current_fcinfo; *************** pltcl_subtrans_commit(MemoryContext oldc *** 1777,1783 **** } static void ! pltcl_subtrans_abort(Tcl_Interp *interp, MemoryContext oldcontext, ResourceOwner oldowner) { ErrorData *edata; --- 1777,1783 ---- } static void ! pltcl_subtrans_abort(Tcl_Interp * interp, MemoryContext oldcontext, ResourceOwner oldowner) { ErrorData *edata; *************** pltcl_subtrans_abort(Tcl_Interp *interp, *** 1812,1818 **** * for the Tcl interpreter **********************************************************************/ static int ! pltcl_SPI_execute(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]) { int my_rc; --- 1812,1818 ---- * for the Tcl interpreter **********************************************************************/ static int ! pltcl_SPI_execute(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]) { int my_rc; *************** pltcl_SPI_execute(ClientData cdata, Tcl_ *** 1915,1925 **** * Shared code between pltcl_SPI_execute and pltcl_SPI_execute_plan */ static int ! pltcl_process_SPI_result(Tcl_Interp *interp, CONST84 char *arrayname, CONST84 char *loop_body, int spi_rc, ! SPITupleTable *tuptable, int ntuples) { int my_rc = TCL_OK; --- 1915,1925 ---- * Shared code between pltcl_SPI_execute and pltcl_SPI_execute_plan */ static int ! pltcl_process_SPI_result(Tcl_Interp * interp, CONST84 char *arrayname, CONST84 char *loop_body, int spi_rc, ! SPITupleTable * tuptable, int ntuples) { int my_rc = TCL_OK; *************** pltcl_process_SPI_result(Tcl_Interp *int *** 2027,2033 **** * and not save the plan currently. **********************************************************************/ static int ! pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]) { int nargs; --- 2027,2033 ---- * and not save the plan currently. **********************************************************************/ static int ! pltcl_SPI_prepare(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]) { int nargs; *************** pltcl_SPI_prepare(ClientData cdata, Tcl_ *** 2155,2161 **** * pltcl_SPI_execute_plan() - Execute a prepared plan **********************************************************************/ static int ! pltcl_SPI_execute_plan(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]) { int my_rc; --- 2155,2161 ---- * pltcl_SPI_execute_plan() - Execute a prepared plan **********************************************************************/ static int ! pltcl_SPI_execute_plan(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]) { int my_rc; *************** pltcl_SPI_execute_plan(ClientData cdata, *** 2373,2379 **** * be used after insert queries **********************************************************************/ static int ! pltcl_SPI_lastoid(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]) { char buf[64]; --- 2373,2379 ---- * be used after insert queries **********************************************************************/ static int ! pltcl_SPI_lastoid(ClientData cdata, Tcl_Interp * interp, int argc, CONST84 char *argv[]) { char buf[64]; *************** pltcl_SPI_lastoid(ClientData cdata, Tcl_ *** 2389,2395 **** * of a given tuple **********************************************************************/ static void ! pltcl_set_tuple_values(Tcl_Interp *interp, CONST84 char *arrayname, int tupno, HeapTuple tuple, TupleDesc tupdesc) { int i; --- 2389,2395 ---- * of a given tuple **********************************************************************/ static void ! pltcl_set_tuple_values(Tcl_Interp * interp, CONST84 char *arrayname, int tupno, HeapTuple tuple, TupleDesc tupdesc) { int i; *************** pltcl_set_tuple_values(Tcl_Interp *inter *** 2480,2486 **** **********************************************************************/ static void pltcl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc, ! Tcl_DString *retval) { int i; char *outputstr; --- 2480,2486 ---- **********************************************************************/ static void pltcl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc, ! Tcl_DString * retval) { int i; char *outputstr;