@ -2031,6 +2031,7 @@ static int
pltcl_SPI_prepare ( ClientData cdata , Tcl_Interp * interp ,
pltcl_SPI_prepare ( ClientData cdata , Tcl_Interp * interp ,
int argc , CONST84 char * argv [ ] )
int argc , CONST84 char * argv [ ] )
{
{
volatile MemoryContext plan_cxt = NULL ;
int nargs ;
int nargs ;
CONST84 char * * args ;
CONST84 char * * args ;
pltcl_query_desc * qdesc ;
pltcl_query_desc * qdesc ;
@ -2060,13 +2061,24 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
/************************************************************
/************************************************************
* Allocate the new querydesc structure
* Allocate the new querydesc structure
*
* struct qdesc and subsidiary data all live in plan_cxt . Note that if the
* function is recompiled for whatever reason , permanent memory leaks
* occur . FIXME someday .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
qdesc = ( pltcl_query_desc * ) malloc ( sizeof ( pltcl_query_desc ) ) ;
plan_cxt = AllocSetContextCreate ( TopMemoryContext ,
" PL/TCL spi_prepare query " ,
ALLOCSET_SMALL_MINSIZE ,
ALLOCSET_SMALL_INITSIZE ,
ALLOCSET_SMALL_MAXSIZE ) ;
MemoryContextSwitchTo ( plan_cxt ) ;
qdesc = ( pltcl_query_desc * ) palloc0 ( sizeof ( pltcl_query_desc ) ) ;
snprintf ( qdesc - > qname , sizeof ( qdesc - > qname ) , " %p " , qdesc ) ;
snprintf ( qdesc - > qname , sizeof ( qdesc - > qname ) , " %p " , qdesc ) ;
qdesc - > nargs = nargs ;
qdesc - > nargs = nargs ;
qdesc - > argtypes = ( Oid * ) malloc ( nargs * sizeof ( Oid ) ) ;
qdesc - > argtypes = ( Oid * ) palloc ( nargs * sizeof ( Oid ) ) ;
qdesc - > arginfuncs = ( FmgrInfo * ) malloc ( nargs * sizeof ( FmgrInfo ) ) ;
qdesc - > arginfuncs = ( FmgrInfo * ) palloc ( nargs * sizeof ( FmgrInfo ) ) ;
qdesc - > argtypioparams = ( Oid * ) malloc ( nargs * sizeof ( Oid ) ) ;
qdesc - > argtypioparams = ( Oid * ) palloc ( nargs * sizeof ( Oid ) ) ;
MemoryContextSwitchTo ( oldcontext ) ;
/************************************************************
/************************************************************
* Execute the prepare inside a sub - transaction , so we can cope with
* Execute the prepare inside a sub - transaction , so we can cope with
@ -2094,7 +2106,7 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
getTypeInputInfo ( typId , & typInput , & typIOParam ) ;
getTypeInputInfo ( typId , & typInput , & typIOParam ) ;
qdesc - > argtypes [ i ] = typId ;
qdesc - > argtypes [ i ] = typId ;
perm_ fmgr_info( typInput , & ( qdesc - > arginfuncs [ i ] ) ) ;
fmgr_info_cxt ( typInput , & ( qdesc - > arginfuncs [ i ] ) , plan_cxt ) ;
qdesc - > argtypioparams [ i ] = typIOParam ;
qdesc - > argtypioparams [ i ] = typIOParam ;
}
}
@ -2125,10 +2137,7 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
{
{
pltcl_subtrans_abort ( interp , oldcontext , oldowner ) ;
pltcl_subtrans_abort ( interp , oldcontext , oldowner ) ;
free ( qdesc - > argtypes ) ;
MemoryContextDelete ( plan_cxt ) ;
free ( qdesc - > arginfuncs ) ;
free ( qdesc - > argtypioparams ) ;
free ( qdesc ) ;
ckfree ( ( char * ) args ) ;
ckfree ( ( char * ) args ) ;
return TCL_ERROR ;
return TCL_ERROR ;