Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 47ccf37

Browse files
committed
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.
1 parent db42e32 commit 47ccf37

File tree

1 file changed

+23
-49
lines changed

1 file changed

+23
-49
lines changed

src/pl/tcl/pltcl.c

+23-49
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
* ENHANCEMENTS, OR MODIFICATIONS.
3232
*
3333
* IDENTIFICATION
34-
* $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.48 2001/11/05 17:46:39 momjian Exp $
34+
* $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.49 2002/01/24 19:31:36 tgl Exp $
3535
*
3636
**********************************************************************/
3737

@@ -124,8 +124,6 @@ typedef struct pltcl_query_desc
124124
Oid *argtypes;
125125
FmgrInfo *arginfuncs;
126126
Oid *argtypelems;
127-
bool *argbyvals;
128-
Datum *argvalues;
129127
} pltcl_query_desc;
130128

131129

@@ -819,9 +817,7 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS)
819817
if (strcmp(interp->result, "OK") == 0)
820818
return rettup;
821819
if (strcmp(interp->result, "SKIP") == 0)
822-
{
823-
return (HeapTuple) NULL;;
824-
}
820+
return (HeapTuple) NULL;
825821

826822
/************************************************************
827823
* Convert the result value from the Tcl interpreter
@@ -889,6 +885,8 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS)
889885
attnum = SPI_fnumber(tupdesc, ret_values[i++]);
890886
if (attnum == SPI_ERROR_NOATTRIBUTE)
891887
elog(ERROR, "pltcl: invalid attribute '%s'", ret_values[--i]);
888+
if (attnum <= 0)
889+
elog(ERROR, "pltcl: cannot set system attribute '%s'", ret_values[--i]);
892890

893891
/************************************************************
894892
* Lookup the attribute type in the syscache
@@ -1724,8 +1722,6 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
17241722
qdesc->argtypes = (Oid *) malloc(nargs * sizeof(Oid));
17251723
qdesc->arginfuncs = (FmgrInfo *) malloc(nargs * sizeof(FmgrInfo));
17261724
qdesc->argtypelems = (Oid *) malloc(nargs * sizeof(Oid));
1727-
qdesc->argbyvals = (bool *) malloc(nargs * sizeof(bool));
1728-
qdesc->argvalues = (Datum *) malloc(nargs * sizeof(Datum));
17291725

17301726
/************************************************************
17311727
* Prepare to start a controlled return through all
@@ -1739,8 +1735,6 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
17391735
free(qdesc->argtypes);
17401736
free(qdesc->arginfuncs);
17411737
free(qdesc->argtypelems);
1742-
free(qdesc->argbyvals);
1743-
free(qdesc->argvalues);
17441738
free(qdesc);
17451739
ckfree((char *) args);
17461740
return TCL_ERROR;
@@ -1761,8 +1755,6 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
17611755
perm_fmgr_info(((Form_pg_type) GETSTRUCT(typeTup))->typinput,
17621756
&(qdesc->arginfuncs[i]));
17631757
qdesc->argtypelems[i] = ((Form_pg_type) GETSTRUCT(typeTup))->typelem;
1764-
qdesc->argbyvals[i] = ((Form_pg_type) GETSTRUCT(typeTup))->typbyval;
1765-
qdesc->argvalues[i] = (Datum) NULL;
17661758
ReleaseSysCache(typeTup);
17671759
}
17681760

@@ -1879,6 +1871,7 @@ pltcl_SPI_execp(ClientData cdata, Tcl_Interp *interp,
18791871
int loop_body;
18801872
Tcl_HashEntry *hashent;
18811873
pltcl_query_desc *qdesc;
1874+
Datum *argvalues = NULL;
18821875
char *volatile nulls = NULL;
18831876
char *volatile arrayname = NULL;
18841877
int count = 0;
@@ -2033,15 +2026,6 @@ pltcl_SPI_execp(ClientData cdata, Tcl_Interp *interp,
20332026
if (sigsetjmp(Warn_restart, 1) != 0)
20342027
{
20352028
memcpy(&Warn_restart, &save_restart, sizeof(Warn_restart));
2036-
for (j = 0; j < callnargs; j++)
2037-
{
2038-
if (!qdesc->argbyvals[j] &&
2039-
qdesc->argvalues[j] != (Datum) NULL)
2040-
{
2041-
pfree(DatumGetPointer(qdesc->argvalues[j]));
2042-
qdesc->argvalues[j] = (Datum) NULL;
2043-
}
2044-
}
20452029
ckfree((char *) callargs);
20462030
callargs = NULL;
20472031
pltcl_restart_in_progress = 1;
@@ -2053,15 +2037,25 @@ pltcl_SPI_execp(ClientData cdata, Tcl_Interp *interp,
20532037
* Setup the value array for the SPI_execp() using
20542038
* the type specific input functions
20552039
************************************************************/
2040+
argvalues = (Datum *) palloc(callnargs * sizeof(Datum));
2041+
20562042
for (j = 0; j < callnargs; j++)
20572043
{
2058-
UTF_BEGIN;
2059-
qdesc->argvalues[j] =
2060-
FunctionCall3(&qdesc->arginfuncs[j],
2061-
CStringGetDatum(UTF_U2E(callargs[j])),
2062-
ObjectIdGetDatum(qdesc->argtypelems[j]),
2063-
Int32GetDatum(-1));
2064-
UTF_END;
2044+
if (nulls && nulls[j] == 'n')
2045+
{
2046+
/* don't try to convert the input for a null */
2047+
argvalues[j] = (Datum) 0;
2048+
}
2049+
else
2050+
{
2051+
UTF_BEGIN;
2052+
argvalues[j] =
2053+
FunctionCall3(&qdesc->arginfuncs[j],
2054+
CStringGetDatum(UTF_U2E(callargs[j])),
2055+
ObjectIdGetDatum(qdesc->argtypelems[j]),
2056+
Int32GetDatum(-1));
2057+
UTF_END;
2058+
}
20652059
}
20662060

20672061
/************************************************************
@@ -2088,14 +2082,6 @@ pltcl_SPI_execp(ClientData cdata, Tcl_Interp *interp,
20882082
if (sigsetjmp(Warn_restart, 1) != 0)
20892083
{
20902084
memcpy(&Warn_restart, &save_restart, sizeof(Warn_restart));
2091-
for (j = 0; j < callnargs; j++)
2092-
{
2093-
if (!qdesc->argbyvals[j] && qdesc->argvalues[j] != (Datum) NULL)
2094-
{
2095-
pfree(DatumGetPointer(qdesc->argvalues[j]));
2096-
qdesc->argvalues[j] = (Datum) NULL;
2097-
}
2098-
}
20992085
pltcl_restart_in_progress = 1;
21002086
Tcl_SetResult(interp, "Transaction abort", TCL_VOLATILE);
21012087
return TCL_ERROR;
@@ -2104,21 +2090,9 @@ pltcl_SPI_execp(ClientData cdata, Tcl_Interp *interp,
21042090
/************************************************************
21052091
* Execute the plan
21062092
************************************************************/
2107-
spi_rc = SPI_execp(qdesc->plan, qdesc->argvalues, nulls, count);
2093+
spi_rc = SPI_execp(qdesc->plan, argvalues, nulls, count);
21082094
memcpy(&Warn_restart, &save_restart, sizeof(Warn_restart));
21092095

2110-
/************************************************************
2111-
* For varlena data types, free the argument values
2112-
************************************************************/
2113-
for (j = 0; j < callnargs; j++)
2114-
{
2115-
if (!qdesc->argbyvals[j] && qdesc->argvalues[j] != (Datum) NULL)
2116-
{
2117-
pfree(DatumGetPointer(qdesc->argvalues[j]));
2118-
qdesc->argvalues[j] = (Datum) NULL;
2119-
}
2120-
}
2121-
21222096
/************************************************************
21232097
* Check the return code from SPI_execp()
21242098
************************************************************/

0 commit comments

Comments
 (0)