2929 * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
3030 *
3131 * IDENTIFICATION
32- *$PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.68 2005/12/29 21 :47:32 neilc Exp $
32+ *$PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.69 2006/01/09 02 :47:09 neilc Exp $
3333 *
3434 *********************************************************************
3535 */
@@ -124,8 +124,7 @@ typedef struct PLyTypeInfo
124124}PLyTypeInfo ;
125125
126126
127- /* cached procedure data
128- */
127+ /* cached procedure data */
129128typedef struct PLyProcedure
130129{
131130char * proname ;/* SQL name of procedure */
@@ -145,8 +144,7 @@ typedef struct PLyProcedure
145144}PLyProcedure ;
146145
147146
148- /* Python objects.
149- */
147+ /* Python objects */
150148typedef struct PLyPlanObject
151149{
152150PyObject_HEAD
@@ -167,8 +165,7 @@ typedef struct PLyResultObject
167165}PLyResultObject ;
168166
169167
170- /* function declarations
171- */
168+ /* function declarations */
172169
173170/* Two exported functions: first is the magic telling Postgresql
174171 * what function call interface it implements. Second allows
@@ -179,8 +176,7 @@ voidplpython_init(void);
179176
180177PG_FUNCTION_INFO_V1 (plpython_call_handler );
181178
182- /* most of the remaining of the declarations, all static
183- */
179+ /* most of the remaining of the declarations, all static */
184180
185181/* these should only be called once at the first call
186182 * of plpython_call_handler. initialize the python interpreter
@@ -190,18 +186,15 @@ static void PLy_init_all(void);
190186static void PLy_init_interp (void );
191187static void PLy_init_plpy (void );
192188
193- /* call PyErr_SetString with a vprint interface
194- */
189+ /* call PyErr_SetString with a vprint interface */
195190static void
196191PLy_exception_set (PyObject * ,const char * ,...)
197192__attribute__((format (printf ,2 ,3 )));
198193
199- /* Get the innermost python procedure called from the backend.
200- */
194+ /* Get the innermost python procedure called from the backend */
201195static char * PLy_procedure_name (PLyProcedure * );
202196
203- /* some utility functions
204- */
197+ /* some utility functions */
205198static void PLy_elog (int ,const char * ,...);
206199static char * PLy_traceback (int * );
207200static char * PLy_vprintf (const char * fmt ,va_list ap );
@@ -212,8 +205,7 @@ static void *PLy_realloc(void *, size_t);
212205static char * PLy_strdup (const char * );
213206static void PLy_free (void * );
214207
215- /* sub handlers for functions and triggers
216- */
208+ /* sub handlers for functions and triggers */
217209static Datum PLy_function_handler (FunctionCallInfo fcinfo ,PLyProcedure * );
218210static HeapTuple PLy_trigger_handler (FunctionCallInfo fcinfo ,PLyProcedure * );
219211
@@ -245,8 +237,7 @@ static void PLy_input_datum_func2(PLyDatumToOb *, Oid, HeapTuple);
245237static void PLy_output_tuple_funcs (PLyTypeInfo * ,TupleDesc );
246238static void PLy_input_tuple_funcs (PLyTypeInfo * ,TupleDesc );
247239
248- /* conversion functions
249- */
240+ /* conversion functions */
250241static PyObject * PLyDict_FromTuple (PLyTypeInfo * ,HeapTuple ,TupleDesc );
251242static PyObject * PLyBool_FromString (const char * );
252243static PyObject * PLyFloat_FromString (const char * );
@@ -255,8 +246,7 @@ static PyObject *PLyLong_FromString(const char *);
255246static PyObject * PLyString_FromString (const char * );
256247
257248
258- /* global data
259- */
249+ /* global data */
260250static bool PLy_first_call = true;
261251
262252/*
@@ -281,14 +271,12 @@ static PyObject *PLy_interp_globals = NULL;
281271static PyObject * PLy_interp_safe_globals = NULL ;
282272static PyObject * PLy_procedure_cache = NULL ;
283273
284- /* Python exceptions
285- */
274+ /* Python exceptions */
286275static PyObject * PLy_exc_error = NULL ;
287276static PyObject * PLy_exc_fatal = NULL ;
288277static PyObject * PLy_exc_spi_error = NULL ;
289278
290- /* some globals for the python module
291- */
279+ /* some globals for the python module */
292280static char PLy_plan_doc []= {
293281"Store a PostgreSQL plan"
294282};
@@ -412,7 +400,10 @@ PLy_trigger_handler(FunctionCallInfo fcinfo, PLyProcedure * proc)
412400char * srv ;
413401
414402if (!PyString_Check (plrv ))
415- elog (ERROR ,"expected trigger to return None or a String" );
403+ ereport (ERROR ,
404+ (errcode (ERRCODE_DATA_EXCEPTION ),
405+ errmsg ("unexpected return value from trigger procedure" ),
406+ errdetail ("expected None or a String" )));
416407
417408srv = PyString_AsString (plrv );
418409if (pg_strcasecmp (srv ,"SKIP" )== 0 )
@@ -430,11 +421,13 @@ PLy_trigger_handler(FunctionCallInfo fcinfo, PLyProcedure * proc)
430421else if (pg_strcasecmp (srv ,"OK" )!= 0 )
431422{
432423/*
433- * hmmm, perhaps they only read the pltcl page, not a
434- * surprising thing since i've written no documentation, so
435- * accept a belated OK
424+ * accept "OK" as an alternative to None; otherwise,
425+ * raise an error
436426 */
437- elog (ERROR ,"expected return to be \"SKIP\" or \"MODIFY\"" );
427+ ereport (ERROR ,
428+ (errcode (ERRCODE_DATA_EXCEPTION ),
429+ errmsg ("unexpected return value from trigger procedure" ),
430+ errdetail ("expected None, \"OK\", \"SKIP\", or \"MODIFY\"" )));
438431}
439432}
440433}
@@ -533,7 +526,7 @@ PLy_modify_tuple(PLyProcedure * proc, PyObject * pltd, TriggerData *tdata,
533526}
534527else
535528{
536- modvalues [i ]= ( Datum ) 0 ;
529+ modvalues [i ]= PointerGetDatum ( NULL ) ;
537530modnulls [i ]= 'n' ;
538531}
539532
@@ -737,8 +730,7 @@ PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure * proc, HeapTuple *
737730
738731
739732
740- /* function handler and friends
741- */
733+ /* function handler and friends */
742734static Datum
743735PLy_function_handler (FunctionCallInfo fcinfo ,PLyProcedure * proc )
744736{
@@ -771,7 +763,7 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure * proc)
771763if (plrv == Py_None )
772764{
773765fcinfo -> isnull = true;
774- rv = ( Datum ) NULL ;
766+ rv = PointerGetDatum ( NULL ) ;
775767}
776768else
777769{
@@ -785,7 +777,6 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure * proc)
785777ObjectIdGetDatum (proc -> result .out .d .typioparam ),
786778Int32GetDatum (-1 ));
787779}
788-
789780}
790781PG_CATCH ();
791782{
@@ -1150,8 +1141,8 @@ PLy_procedure_compile(PLyProcedure * proc, const char *src)
11501141proc -> globals = PyDict_Copy (PLy_interp_globals );
11511142
11521143/*
1153- * SD is private preserved data between calls GD is global data shared by
1154- * all functions
1144+ * SD is private preserved data between calls. GD is global data
1145+ *shared by all functions
11551146 */
11561147proc -> statics = PyDict_New ();
11571148PyDict_SetItemString (proc -> globals ,"SD" ,proc -> statics );
@@ -1406,8 +1397,7 @@ PLy_typeinfo_dealloc(PLyTypeInfo * arg)
14061397}
14071398}
14081399
1409- /* assumes that a bool is always returned as a 't' or 'f'
1410- */
1400+ /* assumes that a bool is always returned as a 't' or 'f' */
14111401static PyObject *
14121402PLyBool_FromString (const char * src )
14131403{
@@ -1514,11 +1504,9 @@ PLyDict_FromTuple(PLyTypeInfo * info, HeapTuple tuple, TupleDesc desc)
15141504return dict ;
15151505}
15161506
1517- /* initialization, some python variables function declared here
1518- */
1507+ /* initialization, some python variables function declared here */
15191508
1520- /* interface to postgresql elog
1521- */
1509+ /* interface to postgresql elog */
15221510static PyObject * PLy_debug (PyObject * ,PyObject * );
15231511static PyObject * PLy_log (PyObject * ,PyObject * );
15241512static PyObject * PLy_info (PyObject * ,PyObject * );
@@ -1527,8 +1515,7 @@ static PyObject *PLy_warning(PyObject *, PyObject *);
15271515static PyObject * PLy_error (PyObject * ,PyObject * );
15281516static PyObject * PLy_fatal (PyObject * ,PyObject * );
15291517
1530- /* PLyPlanObject, PLyResultObject and SPI interface
1531- */
1518+ /* PLyPlanObject, PLyResultObject and SPI interface */
15321519#define is_PLyPlanObject (x ) ((x)->ob_type == &PLy_PlanType)
15331520static PyObject * PLy_plan_new (void );
15341521static void PLy_plan_dealloc (PyObject * );
@@ -1660,8 +1647,7 @@ static PyMethodDef PLy_methods[] = {
16601647};
16611648
16621649
1663- /* plan object methods
1664- */
1650+ /* plan object methods */
16651651static PyObject *
16661652PLy_plan_new (void )
16671653{
@@ -1722,8 +1708,7 @@ PLy_plan_status(PyObject * self, PyObject * args)
17221708
17231709
17241710
1725- /* result object methods
1726- */
1711+ /* result object methods */
17271712
17281713static PyObject *
17291714PLy_result_new (void )
@@ -1833,8 +1818,7 @@ PLy_result_ass_slice(PyObject * arg, int lidx, int hidx, PyObject * slice)
18331818return rv ;
18341819}
18351820
1836- /* SPI interface
1837- */
1821+ /* SPI interface */
18381822static PyObject *
18391823PLy_spi_prepare (PyObject * self ,PyObject * args )
18401824{
@@ -1893,7 +1877,7 @@ PLy_spi_prepare(PyObject * self, PyObject * args)
18931877for (i = 0 ;i < nargs ;i ++ )
18941878{
18951879PLy_typeinfo_init (& plan -> args [i ]);
1896- plan -> values [i ]= ( Datum ) NULL ;
1880+ plan -> values [i ]= PointerGetDatum ( NULL ) ;
18971881}
18981882
18991883for (i = 0 ;i < nargs ;i ++ )
@@ -2073,7 +2057,7 @@ PLy_spi_execute_plan(PyObject * ob, PyObject * list, long limit)
20732057else
20742058{
20752059Py_DECREF (elem );
2076- plan -> values [i ]= ( Datum ) 0 ;
2060+ plan -> values [i ]= PointerGetDatum ( NULL ) ;
20772061nulls [i ]= 'n' ;
20782062}
20792063}
@@ -2095,10 +2079,10 @@ PLy_spi_execute_plan(PyObject * ob, PyObject * list, long limit)
20952079for (i = 0 ;i < nargs ;i ++ )
20962080{
20972081if (!plan -> args [i ].out .d .typbyval &&
2098- (plan -> values [i ]!= ( Datum ) NULL ))
2082+ (plan -> values [i ]!= PointerGetDatum ( NULL ) ))
20992083{
21002084pfree (DatumGetPointer (plan -> values [i ]));
2101- plan -> values [i ]= ( Datum ) NULL ;
2085+ plan -> values [i ]= PointerGetDatum ( NULL ) ;
21022086}
21032087}
21042088
@@ -2115,10 +2099,10 @@ PLy_spi_execute_plan(PyObject * ob, PyObject * list, long limit)
21152099for (i = 0 ;i < nargs ;i ++ )
21162100{
21172101if (!plan -> args [i ].out .d .typbyval &&
2118- (plan -> values [i ]!= ( Datum ) NULL ))
2102+ (plan -> values [i ]!= PointerGetDatum ( NULL ) ))
21192103{
21202104pfree (DatumGetPointer (plan -> values [i ]));
2121- plan -> values [i ]= ( Datum ) NULL ;
2105+ plan -> values [i ]= PointerGetDatum ( NULL ) ;
21222106}
21232107}
21242108
@@ -2436,13 +2420,12 @@ PLy_output(volatile int level, PyObject * self, PyObject * args)
24362420
24372421
24382422/*
2439- * Get the last procedurename called by the backend ( the innermost,
2440- *If a plpython procedure call calls the backend and the backend calls
2441- * another plpython procedure )
2423+ * Get thename of the last procedure called by the backend (the
2424+ *innermost, if a plpython procedure call calls the backend and the
2425+ *backend calls another plpython procedure).
24422426 *
24432427 * NB: this returns the SQL name, not the internal Python procedure name
24442428 */
2445-
24462429static char *
24472430PLy_procedure_name (PLyProcedure * proc )
24482431{
@@ -2606,13 +2589,9 @@ PLy_vprintf(const char *fmt, va_list ap)
26062589return NULL ;
26072590}
26082591
2609- /* python module code
2610- */
2611-
2612-
2613- /* some dumb utility functions
2614- */
2592+ /* python module code */
26152593
2594+ /* some dumb utility functions */
26162595static void *
26172596PLy_malloc (size_t bytes )
26182597{
@@ -2650,8 +2629,7 @@ PLy_strdup(const char *str)
26502629return result ;
26512630}
26522631
2653- /* define this away
2654- */
2632+ /* define this away */
26552633static void
26562634PLy_free (void * ptr )
26572635{