summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2002-01-24 19:31:36 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2002-01-24 19:31:36 +0000
commit47ccf37c62e364e75342de7e62d27d539c65dc14 (patch)
tree617ba1bdfed9e6a00b5e70c9e72bace4ffa9c171
parentdb42e32a74954cd017b3a284306a14900697b3ff (diff)
downloadpostgresql-47ccf37c62e364e75342de7e62d27d539c65dc14.tar.gz
pltcl's spi_execp didn't handle NULL arguments quite correctly.
It would try to call the input conversion routines for them anyway. So, a valid input string for the datatype had to be supplied.
-rw-r--r--src/pl/tcl/pltcl.c72
1 files changed, 23 insertions, 49 deletions
diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c
index 47f92d1e38..336b837c96 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,22 +2090,10 @@ 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()
************************************************************/
switch (spi_rc)