diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c index 47f92d1e383a07dfaa96bdbe961e750d98ca2cb5..336b837c961f708cc295c742a09493c53ade603b 100644 --- a/src/pl/tcl/pltcl.c +++ b/src/pl/tcl/pltcl.c @@ -31,7 +31,7 @@ * ENHANCEMENTS, OR MODIFICATIONS. * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.48 2001/11/05 17:46:39 momjian Exp $ + * $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.49 2002/01/24 19:31:36 tgl Exp $ * **********************************************************************/ @@ -124,8 +124,6 @@ typedef struct pltcl_query_desc Oid *argtypes; FmgrInfo *arginfuncs; Oid *argtypelems; - bool *argbyvals; - Datum *argvalues; } pltcl_query_desc; @@ -819,9 +817,7 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS) if (strcmp(interp->result, "OK") == 0) return rettup; if (strcmp(interp->result, "SKIP") == 0) - { - return (HeapTuple) NULL;; - } + return (HeapTuple) NULL; /************************************************************ * Convert the result value from the Tcl interpreter @@ -889,6 +885,8 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS) attnum = SPI_fnumber(tupdesc, ret_values[i++]); if (attnum == SPI_ERROR_NOATTRIBUTE) elog(ERROR, "pltcl: invalid attribute '%s'", ret_values[--i]); + if (attnum <= 0) + elog(ERROR, "pltcl: cannot set system attribute '%s'", ret_values[--i]); /************************************************************ * Lookup the attribute type in the syscache @@ -1724,8 +1722,6 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp, qdesc->argtypes = (Oid *) malloc(nargs * sizeof(Oid)); qdesc->arginfuncs = (FmgrInfo *) malloc(nargs * sizeof(FmgrInfo)); qdesc->argtypelems = (Oid *) malloc(nargs * sizeof(Oid)); - qdesc->argbyvals = (bool *) malloc(nargs * sizeof(bool)); - qdesc->argvalues = (Datum *) malloc(nargs * sizeof(Datum)); /************************************************************ * Prepare to start a controlled return through all @@ -1739,8 +1735,6 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp, free(qdesc->argtypes); free(qdesc->arginfuncs); free(qdesc->argtypelems); - free(qdesc->argbyvals); - free(qdesc->argvalues); free(qdesc); ckfree((char *) args); return TCL_ERROR; @@ -1761,8 +1755,6 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp, perm_fmgr_info(((Form_pg_type) GETSTRUCT(typeTup))->typinput, &(qdesc->arginfuncs[i])); qdesc->argtypelems[i] = ((Form_pg_type) GETSTRUCT(typeTup))->typelem; - qdesc->argbyvals[i] = ((Form_pg_type) GETSTRUCT(typeTup))->typbyval; - qdesc->argvalues[i] = (Datum) NULL; ReleaseSysCache(typeTup); } @@ -1879,6 +1871,7 @@ pltcl_SPI_execp(ClientData cdata, Tcl_Interp *interp, int loop_body; Tcl_HashEntry *hashent; pltcl_query_desc *qdesc; + Datum *argvalues = NULL; char *volatile nulls = NULL; char *volatile arrayname = NULL; int count = 0; @@ -2033,15 +2026,6 @@ pltcl_SPI_execp(ClientData cdata, Tcl_Interp *interp, if (sigsetjmp(Warn_restart, 1) != 0) { memcpy(&Warn_restart, &save_restart, sizeof(Warn_restart)); - for (j = 0; j < callnargs; j++) - { - if (!qdesc->argbyvals[j] && - qdesc->argvalues[j] != (Datum) NULL) - { - pfree(DatumGetPointer(qdesc->argvalues[j])); - qdesc->argvalues[j] = (Datum) NULL; - } - } ckfree((char *) callargs); callargs = NULL; pltcl_restart_in_progress = 1; @@ -2053,15 +2037,25 @@ pltcl_SPI_execp(ClientData cdata, Tcl_Interp *interp, * Setup the value array for the SPI_execp() using * the type specific input functions ************************************************************/ + argvalues = (Datum *) palloc(callnargs * sizeof(Datum)); + for (j = 0; j < callnargs; j++) { - UTF_BEGIN; - qdesc->argvalues[j] = - FunctionCall3(&qdesc->arginfuncs[j], - CStringGetDatum(UTF_U2E(callargs[j])), - ObjectIdGetDatum(qdesc->argtypelems[j]), - Int32GetDatum(-1)); - UTF_END; + if (nulls && nulls[j] == 'n') + { + /* don't try to convert the input for a null */ + argvalues[j] = (Datum) 0; + } + else + { + UTF_BEGIN; + argvalues[j] = + FunctionCall3(&qdesc->arginfuncs[j], + CStringGetDatum(UTF_U2E(callargs[j])), + ObjectIdGetDatum(qdesc->argtypelems[j]), + Int32GetDatum(-1)); + UTF_END; + } } /************************************************************ @@ -2088,14 +2082,6 @@ pltcl_SPI_execp(ClientData cdata, Tcl_Interp *interp, if (sigsetjmp(Warn_restart, 1) != 0) { memcpy(&Warn_restart, &save_restart, sizeof(Warn_restart)); - for (j = 0; j < callnargs; j++) - { - if (!qdesc->argbyvals[j] && qdesc->argvalues[j] != (Datum) NULL) - { - pfree(DatumGetPointer(qdesc->argvalues[j])); - qdesc->argvalues[j] = (Datum) NULL; - } - } pltcl_restart_in_progress = 1; Tcl_SetResult(interp, "Transaction abort", TCL_VOLATILE); return TCL_ERROR; @@ -2104,21 +2090,9 @@ pltcl_SPI_execp(ClientData cdata, Tcl_Interp *interp, /************************************************************ * Execute the plan ************************************************************/ - spi_rc = SPI_execp(qdesc->plan, qdesc->argvalues, nulls, count); + spi_rc = SPI_execp(qdesc->plan, argvalues, nulls, count); memcpy(&Warn_restart, &save_restart, sizeof(Warn_restart)); - /************************************************************ - * For varlena data types, free the argument values - ************************************************************/ - for (j = 0; j < callnargs; j++) - { - if (!qdesc->argbyvals[j] && qdesc->argvalues[j] != (Datum) NULL) - { - pfree(DatumGetPointer(qdesc->argvalues[j])); - qdesc->argvalues[j] = (Datum) NULL; - } - } - /************************************************************ * Check the return code from SPI_execp() ************************************************************/