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