31
31
* ENHANCEMENTS, OR MODIFICATIONS.
32
32
*
33
33
* IDENTIFICATION
34
- * $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.31 2000/12/08 00:09:07 tgl Exp $
34
+ * $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.32 2001/02/16 03:26:40 tgl Exp $
35
35
*
36
36
**********************************************************************/
37
37
@@ -103,7 +103,7 @@ static Tcl_Interp *pltcl_safe_interp = NULL;
103
103
static Tcl_HashTable * pltcl_proc_hash = NULL ;
104
104
static Tcl_HashTable * pltcl_norm_query_hash = NULL ;
105
105
static Tcl_HashTable * pltcl_safe_query_hash = NULL ;
106
- static FunctionCallInfo pltcl_actual_fcinfo = NULL ;
106
+ static FunctionCallInfo pltcl_current_fcinfo = NULL ;
107
107
108
108
/**********************************************************************
109
109
* Forward declarations
@@ -354,18 +354,18 @@ pltcl_call_handler(PG_FUNCTION_ARGS)
354
354
* Determine if called as function or trigger and
355
355
* call appropriate subhandler
356
356
************************************************************/
357
- save_fcinfo = pltcl_actual_fcinfo ;
357
+ save_fcinfo = pltcl_current_fcinfo ;
358
358
359
359
if (CALLED_AS_TRIGGER (fcinfo ))
360
360
{
361
- pltcl_actual_fcinfo = NULL ;
361
+ pltcl_current_fcinfo = NULL ;
362
362
retval = PointerGetDatum (pltcl_trigger_handler (fcinfo ));
363
363
} else {
364
- pltcl_actual_fcinfo = fcinfo ;
364
+ pltcl_current_fcinfo = fcinfo ;
365
365
retval = pltcl_func_handler (fcinfo );
366
366
}
367
367
368
- pltcl_actual_fcinfo = save_fcinfo ;
368
+ pltcl_current_fcinfo = save_fcinfo ;
369
369
370
370
pltcl_call_level -- ;
371
371
@@ -743,17 +743,27 @@ pltcl_func_handler(PG_FUNCTION_ARGS)
743
743
* Disconnect from SPI manager and then create the return
744
744
* values datum (if the input function does a palloc for it
745
745
* this must not be allocated in the SPI memory context
746
- * because SPI_finish would free it).
746
+ * because SPI_finish would free it). But don't try to call
747
+ * the result_in_func if we've been told to return a NULL;
748
+ * the contents of interp->result may not be a valid value of
749
+ * the result type in that case.
747
750
************************************************************/
748
751
if (SPI_finish () != SPI_OK_FINISH )
749
752
elog (ERROR , "pltcl: SPI_finish() failed" );
750
753
751
- retval = FunctionCall3 (& prodesc -> result_in_func ,
752
- PointerGetDatum (interp -> result ),
753
- ObjectIdGetDatum (prodesc -> result_in_elem ),
754
- Int32GetDatum (-1 ));
754
+ if (fcinfo -> isnull )
755
+ retval = (Datum ) 0 ;
756
+ else
757
+ retval = FunctionCall3 (& prodesc -> result_in_func ,
758
+ PointerGetDatum (interp -> result ),
759
+ ObjectIdGetDatum (prodesc -> result_in_elem ),
760
+ Int32GetDatum (-1 ));
755
761
762
+ /************************************************************
763
+ * Finally we may restore normal error handling.
764
+ ************************************************************/
756
765
memcpy (& Warn_restart , & save_restart , sizeof (Warn_restart ));
766
+
757
767
return retval ;
758
768
}
759
769
@@ -1345,7 +1355,7 @@ pltcl_argisnull(ClientData cdata, Tcl_Interp *interp,
1345
1355
int argc , char * argv [])
1346
1356
{
1347
1357
int argno ;
1348
- FunctionCallInfo fcinfo = pltcl_actual_fcinfo ;
1358
+ FunctionCallInfo fcinfo = pltcl_current_fcinfo ;
1349
1359
1350
1360
/************************************************************
1351
1361
* Check call syntax
@@ -1356,22 +1366,22 @@ pltcl_argisnull(ClientData cdata, Tcl_Interp *interp,
1356
1366
return TCL_ERROR ;
1357
1367
}
1358
1368
1359
- /************************************************************
1360
- * Get the argument number
1361
- ************************************************************/
1362
- if (Tcl_GetInt (interp , argv [1 ], & argno ) != TCL_OK )
1363
- return TCL_ERROR ;
1364
-
1365
1369
/************************************************************
1366
1370
* Check that we're called as a normal function
1367
1371
************************************************************/
1368
1372
if (fcinfo == NULL )
1369
1373
{
1370
1374
Tcl_SetResult (interp , "argisnull cannot be used in triggers" ,
1371
- TCL_VOLATILE );
1375
+ TCL_VOLATILE );
1372
1376
return TCL_ERROR ;
1373
1377
}
1374
1378
1379
+ /************************************************************
1380
+ * Get the argument number
1381
+ ************************************************************/
1382
+ if (Tcl_GetInt (interp , argv [1 ], & argno ) != TCL_OK )
1383
+ return TCL_ERROR ;
1384
+
1375
1385
/************************************************************
1376
1386
* Check that the argno is valid
1377
1387
************************************************************/
@@ -1402,7 +1412,7 @@ pltcl_returnnull(ClientData cdata, Tcl_Interp *interp,
1402
1412
int argc , char * argv [])
1403
1413
{
1404
1414
int argno ;
1405
- FunctionCallInfo fcinfo = pltcl_actual_fcinfo ;
1415
+ FunctionCallInfo fcinfo = pltcl_current_fcinfo ;
1406
1416
1407
1417
/************************************************************
1408
1418
* Check call syntax
@@ -1413,11 +1423,22 @@ pltcl_returnnull(ClientData cdata, Tcl_Interp *interp,
1413
1423
return TCL_ERROR ;
1414
1424
}
1415
1425
1426
+ /************************************************************
1427
+ * Check that we're called as a normal function
1428
+ ************************************************************/
1429
+ if (fcinfo == NULL )
1430
+ {
1431
+ Tcl_SetResult (interp , "return_null cannot be used in triggers" ,
1432
+ TCL_VOLATILE );
1433
+ return TCL_ERROR ;
1434
+ }
1435
+
1416
1436
/************************************************************
1417
1437
* Set the NULL return flag and cause Tcl to return from the
1418
1438
* procedure.
1419
1439
************************************************************/
1420
1440
fcinfo -> isnull = true;
1441
+
1421
1442
return TCL_RETURN ;
1422
1443
}
1423
1444
0 commit comments