31
31
* ENHANCEMENTS, OR MODIFICATIONS.
32
32
*
33
33
* 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 $
35
35
*
36
36
**********************************************************************/
37
37
@@ -124,8 +124,6 @@ typedef struct pltcl_query_desc
124
124
Oid * argtypes ;
125
125
FmgrInfo * arginfuncs ;
126
126
Oid * argtypelems ;
127
- bool * argbyvals ;
128
- Datum * argvalues ;
129
127
} pltcl_query_desc ;
130
128
131
129
@@ -819,9 +817,7 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS)
819
817
if (strcmp (interp -> result , "OK" ) == 0 )
820
818
return rettup ;
821
819
if (strcmp (interp -> result , "SKIP" ) == 0 )
822
- {
823
- return (HeapTuple ) NULL ;;
824
- }
820
+ return (HeapTuple ) NULL ;
825
821
826
822
/************************************************************
827
823
* Convert the result value from the Tcl interpreter
@@ -889,6 +885,8 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS)
889
885
attnum = SPI_fnumber (tupdesc , ret_values [i ++ ]);
890
886
if (attnum == SPI_ERROR_NOATTRIBUTE )
891
887
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 ]);
892
890
893
891
/************************************************************
894
892
* Lookup the attribute type in the syscache
@@ -1724,8 +1722,6 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
1724
1722
qdesc -> argtypes = (Oid * ) malloc (nargs * sizeof (Oid ));
1725
1723
qdesc -> arginfuncs = (FmgrInfo * ) malloc (nargs * sizeof (FmgrInfo ));
1726
1724
qdesc -> argtypelems = (Oid * ) malloc (nargs * sizeof (Oid ));
1727
- qdesc -> argbyvals = (bool * ) malloc (nargs * sizeof (bool ));
1728
- qdesc -> argvalues = (Datum * ) malloc (nargs * sizeof (Datum ));
1729
1725
1730
1726
/************************************************************
1731
1727
* Prepare to start a controlled return through all
@@ -1739,8 +1735,6 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
1739
1735
free (qdesc -> argtypes );
1740
1736
free (qdesc -> arginfuncs );
1741
1737
free (qdesc -> argtypelems );
1742
- free (qdesc -> argbyvals );
1743
- free (qdesc -> argvalues );
1744
1738
free (qdesc );
1745
1739
ckfree ((char * ) args );
1746
1740
return TCL_ERROR ;
@@ -1761,8 +1755,6 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
1761
1755
perm_fmgr_info (((Form_pg_type ) GETSTRUCT (typeTup ))-> typinput ,
1762
1756
& (qdesc -> arginfuncs [i ]));
1763
1757
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 ;
1766
1758
ReleaseSysCache (typeTup );
1767
1759
}
1768
1760
@@ -1879,6 +1871,7 @@ pltcl_SPI_execp(ClientData cdata, Tcl_Interp *interp,
1879
1871
int loop_body ;
1880
1872
Tcl_HashEntry * hashent ;
1881
1873
pltcl_query_desc * qdesc ;
1874
+ Datum * argvalues = NULL ;
1882
1875
char * volatile nulls = NULL ;
1883
1876
char * volatile arrayname = NULL ;
1884
1877
int count = 0 ;
@@ -2033,15 +2026,6 @@ pltcl_SPI_execp(ClientData cdata, Tcl_Interp *interp,
2033
2026
if (sigsetjmp (Warn_restart , 1 ) != 0 )
2034
2027
{
2035
2028
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
- }
2045
2029
ckfree ((char * ) callargs );
2046
2030
callargs = NULL ;
2047
2031
pltcl_restart_in_progress = 1 ;
@@ -2053,15 +2037,25 @@ pltcl_SPI_execp(ClientData cdata, Tcl_Interp *interp,
2053
2037
* Setup the value array for the SPI_execp() using
2054
2038
* the type specific input functions
2055
2039
************************************************************/
2040
+ argvalues = (Datum * ) palloc (callnargs * sizeof (Datum ));
2041
+
2056
2042
for (j = 0 ; j < callnargs ; j ++ )
2057
2043
{
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
+ }
2065
2059
}
2066
2060
2067
2061
/************************************************************
@@ -2088,14 +2082,6 @@ pltcl_SPI_execp(ClientData cdata, Tcl_Interp *interp,
2088
2082
if (sigsetjmp (Warn_restart , 1 ) != 0 )
2089
2083
{
2090
2084
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
- }
2099
2085
pltcl_restart_in_progress = 1 ;
2100
2086
Tcl_SetResult (interp , "Transaction abort" , TCL_VOLATILE );
2101
2087
return TCL_ERROR ;
@@ -2104,21 +2090,9 @@ pltcl_SPI_execp(ClientData cdata, Tcl_Interp *interp,
2104
2090
/************************************************************
2105
2091
* Execute the plan
2106
2092
************************************************************/
2107
- spi_rc = SPI_execp (qdesc -> plan , qdesc -> argvalues , nulls , count );
2093
+ spi_rc = SPI_execp (qdesc -> plan , argvalues , nulls , count );
2108
2094
memcpy (& Warn_restart , & save_restart , sizeof (Warn_restart ));
2109
2095
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
-
2122
2096
/************************************************************
2123
2097
* Check the return code from SPI_execp()
2124
2098
************************************************************/
0 commit comments