On 21/02/12 18:28, Jan Urbański wrote:
> On 21/02/12 18:05, Peter Eisentraut wrote:
>>> it might be better to use ereport, to expose the message
>>> for translation.
>>>
> After giving it some thought some of these elogs could be changed into
> PLy_elogs (which is meant to propagate a Python error into Postgres) and
> the others made into ereports.
> 
> I'll send updated patches this evening (CET).

Inevitably, this turned into the next morning CET.

Here are the updated patches which use PLy_elog instead of plain elog.
The difference is that they will get marked for translation and that the
original Python exception will show up in the errdetail field.

Cheers,
Jan
diff --git a/src/pl/plpython/plpy_elog.c b/src/pl/plpython/plpy_elog.c
index 741980c..332898d 100644
*** a/src/pl/plpython/plpy_elog.c
--- b/src/pl/plpython/plpy_elog.c
*************** get_source_line(const char *src, int lin
*** 365,370 ****
--- 365,374 ----
  	const char *next = src;
  	int			current = 0;
  
+ 	/* sanity check */
+ 	if (lineno <= 0)
+ 		return NULL;
+ 
  	while (current < lineno)
  	{
  		s = next;
diff --git a/src/pl/plpython/plpy_main.c b/src/pl/plpython/plpy_main.c
index ae9d87e..f259ecf 100644
*** a/src/pl/plpython/plpy_main.c
--- b/src/pl/plpython/plpy_main.c
*************** PLy_init_interp(void)
*** 133,138 ****
--- 133,140 ----
  	Py_INCREF(mainmod);
  	PLy_interp_globals = PyModule_GetDict(mainmod);
  	PLy_interp_safe_globals = PyDict_New();
+ 	if (PLy_interp_safe_globals == NULL)
+ 		PLy_elog(ERROR, "could not create globals");
  	PyDict_SetItemString(PLy_interp_globals, "GD", PLy_interp_safe_globals);
  	Py_DECREF(mainmod);
  	if (PLy_interp_globals == NULL || PyErr_Occurred())
diff --git a/src/pl/plpython/plpy_plpymodule.c b/src/pl/plpython/plpy_plpymodule.c
index d2d0a2a..0c96f03 100644
*** a/src/pl/plpython/plpy_plpymodule.c
--- b/src/pl/plpython/plpy_plpymodule.c
*************** PLy_init_plpy(void)
*** 173,181 ****
  	main_mod = PyImport_AddModule("__main__");
  	main_dict = PyModule_GetDict(main_mod);
  	plpy_mod = PyImport_AddModule("plpy");
  	PyDict_SetItemString(main_dict, "plpy", plpy_mod);
  	if (PyErr_Occurred())
! 		elog(ERROR, "could not initialize plpy");
  }
  
  static void
--- 173,183 ----
  	main_mod = PyImport_AddModule("__main__");
  	main_dict = PyModule_GetDict(main_mod);
  	plpy_mod = PyImport_AddModule("plpy");
+ 	if (plpy_mod == NULL)
+ 		PLy_elog(ERROR, "could not initialize plpy");
  	PyDict_SetItemString(main_dict, "plpy", plpy_mod);
  	if (PyErr_Occurred())
! 		PLy_elog(ERROR, "could not initialize plpy");
  }
  
  static void
*************** PLy_add_exceptions(PyObject *plpy)
*** 208,213 ****
--- 210,220 ----
  	PLy_exc_fatal = PyErr_NewException("plpy.Fatal", NULL, NULL);
  	PLy_exc_spi_error = PyErr_NewException("plpy.SPIError", NULL, NULL);
  
+ 	if (PLy_exc_error == NULL ||
+ 		PLy_exc_fatal == NULL ||
+ 		PLy_exc_spi_error == NULL)
+ 		PLy_elog(ERROR, "could not create the base SPI exceptions");
+ 
  	Py_INCREF(PLy_exc_error);
  	PyModule_AddObject(plpy, "Error", PLy_exc_error);
  	Py_INCREF(PLy_exc_fatal);
*************** PLy_generate_spi_exceptions(PyObject *mo
*** 241,247 ****
--- 248,260 ----
  		PyObject   *sqlstate;
  		PyObject   *dict = PyDict_New();
  
+ 		if (dict == NULL)
+ 			PLy_elog(ERROR, "could not generate SPI exceptions");
+ 
  		sqlstate = PyString_FromString(unpack_sql_state(exception_map[i].sqlstate));
+ 		if (sqlstate == NULL)
+ 			PLy_elog(ERROR, "could not generate SPI exceptions");
+ 
  		PyDict_SetItemString(dict, "sqlstate", sqlstate);
  		Py_DECREF(sqlstate);
  		exc = PyErr_NewException(exception_map[i].name, base, dict);
*************** PLy_output(volatile int level, PyObject
*** 369,376 ****
  		 * decoration.
  		 */
  		PyObject   *o;
  
- 		PyArg_UnpackTuple(args, "plpy.elog", 1, 1, &o);
  		so = PyObject_Str(o);
  	}
  	else
--- 382,393 ----
  		 * decoration.
  		 */
  		PyObject   *o;
+ 		int			result;
+ 
+ 		result = PyArg_UnpackTuple(args, "plpy.elog", 1, 1, &o);
+ 		if (!result)
+ 			PLy_elog(ERROR, "could not unpack arguments in plpy.elog");
  
  		so = PyObject_Str(o);
  	}
  	else
diff --git a/src/pl/plpython/plpy_spi.c b/src/pl/plpython/plpy_spi.c
index 0d63c4f..20b93cd 100644
*** a/src/pl/plpython/plpy_spi.c
--- b/src/pl/plpython/plpy_spi.c
*************** PLy_spi_execute_query(char *query, long
*** 338,344 ****
  	int			rv;
  	volatile MemoryContext oldcontext;
  	volatile ResourceOwner oldowner;
! 	PyObject   *ret;
  
  	oldcontext = CurrentMemoryContext;
  	oldowner = CurrentResourceOwner;
--- 338,344 ----
  	int			rv;
  	volatile MemoryContext oldcontext;
  	volatile ResourceOwner oldowner;
! 	PyObject   *ret = NULL;
  
  	oldcontext = CurrentMemoryContext;
  	oldowner = CurrentResourceOwner;
*************** PLy_spi_execute_query(char *query, long
*** 362,367 ****
--- 362,368 ----
  
  	if (rv < 0)
  	{
+ 		Py_XDECREF(ret);
  		PLy_exception_set(PLy_exc_spi_error,
  						  "SPI_execute failed: %s",
  						  SPI_result_code_string(rv));
diff --git a/src/pl/plpython/plpy_typeio.c b/src/pl/plpython/plpy_typeio.c
index d5cac9f..83806a7 100644
*** a/src/pl/plpython/plpy_typeio.c
--- b/src/pl/plpython/plpy_typeio.c
*************** PLyList_FromArray(PLyDatumToOb *arg, Dat
*** 558,563 ****
--- 558,565 ----
  	length = ARR_DIMS(array)[0];
  	lbound = ARR_LBOUND(array)[0];
  	list = PyList_New(length);
+ 	if (list == NULL)
+ 		PLy_elog(ERROR, "could not create new Python list");
  
  	for (i = 0; i < length; i++)
  	{
diff --git a/src/pl/plpython/plpython.c b/src/pl/plpython/plpython.c
index 530b5f0..ec8ecf9 100644
*** a/src/pl/plpython/plpython.c
--- b/src/pl/plpython/plpython.c
*************** PLyList_FromArray(PLyDatumToOb *arg, Dat
*** 2345,2350 ****
--- 2345,2352 ----
  	length = ARR_DIMS(array)[0];
  	lbound = ARR_LBOUND(array)[0];
  	list = PyList_New(length);
+ 	if (list == NULL)
+ 		PLy_elog(ERROR, "could not create new list");
  
  	for (i = 0; i < length; i++)
  	{
*************** PLy_spi_execute_query(char *query, long
*** 3664,3670 ****
  	int			rv;
  	volatile MemoryContext oldcontext;
  	volatile ResourceOwner oldowner;
! 	PyObject   *ret;
  
  	oldcontext = CurrentMemoryContext;
  	oldowner = CurrentResourceOwner;
--- 3666,3672 ----
  	int			rv;
  	volatile MemoryContext oldcontext;
  	volatile ResourceOwner oldowner;
! 	PyObject   *ret = NULL;
  
  	oldcontext = CurrentMemoryContext;
  	oldowner = CurrentResourceOwner;
*************** PLy_spi_execute_query(char *query, long
*** 3727,3732 ****
--- 3729,3735 ----
  
  	if (rv < 0)
  	{
+ 		Py_XDECREF(ret);
  		PLy_exception_set(PLy_exc_spi_error,
  						  "SPI_execute failed: %s",
  						  SPI_result_code_string(rv));
*************** PLy_generate_spi_exceptions(PyObject *mo
*** 3967,3973 ****
--- 3970,3982 ----
  		PyObject   *sqlstate;
  		PyObject   *dict = PyDict_New();
  
+ 		if (dict == NULL)
+ 			PLy_elog(ERROR, "could not generate SPI exceptions");
+ 
  		sqlstate = PyString_FromString(unpack_sql_state(exception_map[i].sqlstate));
+ 		if (sqlstate == NULL)
+ 			PLy_elog(ERROR, "could not generate SPI exceptions");
+ 
  		PyDict_SetItemString(dict, "sqlstate", sqlstate);
  		Py_DECREF(sqlstate);
  		exc = PyErr_NewException(exception_map[i].name, base, dict);
*************** PLy_add_exceptions(PyObject *plpy)
*** 4008,4013 ****
--- 4017,4027 ----
  	PLy_exc_fatal = PyErr_NewException("plpy.Fatal", NULL, NULL);
  	PLy_exc_spi_error = PyErr_NewException("plpy.SPIError", NULL, NULL);
  
+ 	if (PLy_exc_error == NULL ||
+ 		PLy_exc_fatal == NULL ||
+ 		PLy_exc_spi_error == NULL)
+ 		PLy_elog(ERROR, "could not create the base SPI exceptions");
+ 
  	Py_INCREF(PLy_exc_error);
  	PyModule_AddObject(plpy, "Error", PLy_exc_error);
  	Py_INCREF(PLy_exc_fatal);
*************** PLy_init_interp(void)
*** 4124,4129 ****
--- 4138,4145 ----
  	Py_INCREF(mainmod);
  	PLy_interp_globals = PyModule_GetDict(mainmod);
  	PLy_interp_safe_globals = PyDict_New();
+ 	if (PLy_interp_safe_globals == NULL)
+ 		PLy_elog(ERROR, "could not create globals");
  	PyDict_SetItemString(PLy_interp_globals, "GD", PLy_interp_safe_globals);
  	Py_DECREF(mainmod);
  	if (PLy_interp_globals == NULL || PyErr_Occurred())
*************** PLy_init_plpy(void)
*** 4164,4172 ****
  	main_mod = PyImport_AddModule("__main__");
  	main_dict = PyModule_GetDict(main_mod);
  	plpy_mod = PyImport_AddModule("plpy");
  	PyDict_SetItemString(main_dict, "plpy", plpy_mod);
  	if (PyErr_Occurred())
! 		elog(ERROR, "could not initialize plpy");
  }
  
  /* the python interface to the elog function
--- 4180,4190 ----
  	main_mod = PyImport_AddModule("__main__");
  	main_dict = PyModule_GetDict(main_mod);
  	plpy_mod = PyImport_AddModule("plpy");
+ 	if (plpy_mod == NULL)
+ 		PLy_elog(ERROR, "could not initialize plpy");
  	PyDict_SetItemString(main_dict, "plpy", plpy_mod);
  	if (PyErr_Occurred())
! 		PLy_elog(ERROR, "could not initialize plpy");
  }
  
  /* the python interface to the elog function
*************** PLy_output(volatile int level, PyObject
*** 4231,4238 ****
  		 * decoration.
  		 */
  		PyObject   *o;
  
- 		PyArg_UnpackTuple(args, "plpy.elog", 1, 1, &o);
  		so = PyObject_Str(o);
  	}
  	else
--- 4249,4260 ----
  		 * decoration.
  		 */
  		PyObject   *o;
+ 		int			result;
+ 
+ 		result = PyArg_UnpackTuple(args, "plpy.elog", 1, 1, &o);
+ 		if (!result)
+ 			PLy_elog(ERROR, "could not unpack arguments in plpy.elog");
  
  		so = PyObject_Str(o);
  	}
  	else
*************** get_source_line(const char *src, int lin
*** 4554,4559 ****
--- 4576,4585 ----
  	const char *next = src;
  	int			current = 0;
  
+ 	/* sanity check */
+ 	if (lineno <= 0)
+ 		return NULL;
+ 
  	while (current < lineno)
  	{
  		s = next;
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to