Clean up plpython error reporting so that its regression test passes
with some amount of cleanliness. I see no need to report the internal Python name rather than the SQL procedure name in error tracebacks.
This commit is contained in:
parent
9d00798720
commit
6f49703f0e
|
@ -1,12 +1,15 @@
|
||||||
SELECT invalid_type_uncaught('rick');
|
SELECT invalid_type_uncaught('rick');
|
||||||
WARNING: plpython: in function __plpython_procedure_invalid_type_uncaught_49801:
|
WARNING: plpython: in function invalid_type_uncaught:
|
||||||
plpy.SPIError: Cache lookup for type `test' failed.
|
plpy.SPIError: Unknown error in PLy_spi_prepare.
|
||||||
|
ERROR: Type "test" does not exist
|
||||||
SELECT invalid_type_caught('rick');
|
SELECT invalid_type_caught('rick');
|
||||||
WARNING: plpython: in function __plpython_procedure_invalid_type_caught_49802:
|
WARNING: plpython: in function invalid_type_caught:
|
||||||
plpy.SPIError: Cache lookup for type `test' failed.
|
plpy.SPIError: Unknown error in PLy_spi_prepare.
|
||||||
|
ERROR: Type "test" does not exist
|
||||||
SELECT invalid_type_reraised('rick');
|
SELECT invalid_type_reraised('rick');
|
||||||
WARNING: plpython: in function __plpython_procedure_invalid_type_reraised_49803:
|
WARNING: plpython: in function invalid_type_reraised:
|
||||||
plpy.SPIError: Cache lookup for type `test' failed.
|
plpy.SPIError: Unknown error in PLy_spi_prepare.
|
||||||
|
ERROR: Type "test" does not exist
|
||||||
SELECT valid_type('rick');
|
SELECT valid_type('rick');
|
||||||
valid_type
|
valid_type
|
||||||
------------
|
------------
|
||||||
|
@ -14,20 +17,20 @@ SELECT valid_type('rick');
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT read_file('/etc/passwd');
|
SELECT read_file('/etc/passwd');
|
||||||
ERROR: plpython: Call of function `__plpython_procedure_read_file_49809' failed.
|
ERROR: plpython: Call of function `read_file' failed.
|
||||||
exceptions.IOError: can't open files in restricted mode
|
exceptions.IOError: can't open files in restricted mode
|
||||||
SELECT write_file('/tmp/plpython','This is very bad');
|
SELECT write_file('/tmp/plpython','This is very bad');
|
||||||
ERROR: plpython: Call of function `__plpython_procedure_write_file_49810' failed.
|
ERROR: plpython: Call of function `write_file' failed.
|
||||||
exceptions.IOError: can't open files in restricted mode
|
exceptions.IOError: can't open files in restricted mode
|
||||||
SELECT getpid();
|
SELECT getpid();
|
||||||
ERROR: plpython: Call of function `__plpython_procedure_getpid_49811' failed.
|
ERROR: plpython: Call of function `getpid' failed.
|
||||||
exceptions.AttributeError: getpid
|
exceptions.AttributeError: 'module' object has no attribute 'getpid'
|
||||||
SELECT uname();
|
SELECT uname();
|
||||||
ERROR: plpython: Call of function `__plpython_procedure_uname_49812' failed.
|
ERROR: plpython: Call of function `uname' failed.
|
||||||
exceptions.AttributeError: uname
|
exceptions.AttributeError: 'module' object has no attribute 'uname'
|
||||||
SELECT sys_exit();
|
SELECT sys_exit();
|
||||||
ERROR: plpython: Call of function `__plpython_procedure_sys_exit_49813' failed.
|
ERROR: plpython: Call of function `sys_exit' failed.
|
||||||
exceptions.AttributeError: exit
|
exceptions.AttributeError: 'module' object has no attribute 'exit'
|
||||||
SELECT sys_argv();
|
SELECT sys_argv();
|
||||||
sys_argv
|
sys_argv
|
||||||
----------------
|
----------------
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/pl/plpython/plpython.c,v 1.27 2002/11/22 16:25:30 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/pl/plpython/plpython.c,v 1.28 2003/01/31 22:25:13 tgl Exp $
|
||||||
*
|
*
|
||||||
*********************************************************************
|
*********************************************************************
|
||||||
*/
|
*/
|
||||||
|
@ -127,7 +127,8 @@ typedef struct PLyTypeInfo
|
||||||
*/
|
*/
|
||||||
typedef struct PLyProcedure
|
typedef struct PLyProcedure
|
||||||
{
|
{
|
||||||
char *proname;
|
char *proname; /* SQL name of procedure */
|
||||||
|
char *pyname; /* Python name of procedure */
|
||||||
TransactionId fn_xmin;
|
TransactionId fn_xmin;
|
||||||
CommandId fn_cmin;
|
CommandId fn_cmin;
|
||||||
PLyTypeInfo result; /* also used to store info for trigger
|
PLyTypeInfo result; /* also used to store info for trigger
|
||||||
|
@ -1050,7 +1051,7 @@ static PLyProcedure *
|
||||||
PLy_procedure_create(FunctionCallInfo fcinfo, bool is_trigger,
|
PLy_procedure_create(FunctionCallInfo fcinfo, bool is_trigger,
|
||||||
HeapTuple procTup, char *key)
|
HeapTuple procTup, char *key)
|
||||||
{
|
{
|
||||||
char procName[256];
|
char procName[NAMEDATALEN+256];
|
||||||
|
|
||||||
DECLARE_EXC();
|
DECLARE_EXC();
|
||||||
Form_pg_proc procStruct;
|
Form_pg_proc procStruct;
|
||||||
|
@ -1073,8 +1074,10 @@ PLy_procedure_create(FunctionCallInfo fcinfo, bool is_trigger,
|
||||||
elog(FATAL, "plpython: Procedure name would overrun buffer");
|
elog(FATAL, "plpython: Procedure name would overrun buffer");
|
||||||
|
|
||||||
proc = PLy_malloc(sizeof(PLyProcedure));
|
proc = PLy_malloc(sizeof(PLyProcedure));
|
||||||
proc->proname = PLy_malloc(strlen(procName) + 1);
|
proc->proname = PLy_malloc(strlen(NameStr(procStruct->proname)) + 1);
|
||||||
strcpy(proc->proname, procName);
|
strcpy(proc->proname, NameStr(procStruct->proname));
|
||||||
|
proc->pyname = PLy_malloc(strlen(procName) + 1);
|
||||||
|
strcpy(proc->pyname, procName);
|
||||||
proc->fn_xmin = HeapTupleHeaderGetXmin(procTup->t_data);
|
proc->fn_xmin = HeapTupleHeaderGetXmin(procTup->t_data);
|
||||||
proc->fn_cmin = HeapTupleHeaderGetCmin(procTup->t_data);
|
proc->fn_cmin = HeapTupleHeaderGetCmin(procTup->t_data);
|
||||||
PLy_typeinfo_init(&proc->result);
|
PLy_typeinfo_init(&proc->result);
|
||||||
|
@ -1235,21 +1238,21 @@ PLy_procedure_compile(PLyProcedure * proc, const char *src)
|
||||||
/*
|
/*
|
||||||
* insert the function code into the interpreter
|
* insert the function code into the interpreter
|
||||||
*/
|
*/
|
||||||
msrc = PLy_procedure_munge_source(proc->proname, src);
|
msrc = PLy_procedure_munge_source(proc->pyname, src);
|
||||||
crv = PyObject_CallMethod(proc->interp, "r_exec", "s", msrc);
|
crv = PyObject_CallMethod(proc->interp, "r_exec", "s", msrc);
|
||||||
free(msrc);
|
free(msrc);
|
||||||
|
|
||||||
if ((crv != NULL) && (!PyErr_Occurred()))
|
if ((crv != NULL) && (!PyErr_Occurred()))
|
||||||
{
|
{
|
||||||
int clen;
|
int clen;
|
||||||
char call[256];
|
char call[NAMEDATALEN+256];
|
||||||
|
|
||||||
Py_DECREF(crv);
|
Py_DECREF(crv);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* compile a call to the function
|
* compile a call to the function
|
||||||
*/
|
*/
|
||||||
clen = snprintf(call, sizeof(call), "%s()", proc->proname);
|
clen = snprintf(call, sizeof(call), "%s()", proc->pyname);
|
||||||
if ((clen < 0) || (clen >= sizeof(call)))
|
if ((clen < 0) || (clen >= sizeof(call)))
|
||||||
elog(ERROR, "plpython: string would overflow buffer.");
|
elog(ERROR, "plpython: string would overflow buffer.");
|
||||||
proc->code = Py_CompileString(call, "<string>", Py_eval_input);
|
proc->code = Py_CompileString(call, "<string>", Py_eval_input);
|
||||||
|
@ -1321,6 +1324,8 @@ PLy_procedure_delete(PLyProcedure * proc)
|
||||||
Py_XDECREF(proc->me);
|
Py_XDECREF(proc->me);
|
||||||
if (proc->proname)
|
if (proc->proname)
|
||||||
PLy_free(proc->proname);
|
PLy_free(proc->proname);
|
||||||
|
if (proc->pyname)
|
||||||
|
PLy_free(proc->pyname);
|
||||||
for (i = 0; i < proc->nargs; i++)
|
for (i = 0; i < proc->nargs; i++)
|
||||||
if (proc->args[i].is_rel == 1)
|
if (proc->args[i].is_rel == 1)
|
||||||
{
|
{
|
||||||
|
@ -2748,9 +2753,12 @@ PLy_output(volatile int level, PyObject * self, PyObject * args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Get the last procedure name called by the backend ( the innermost,
|
/*
|
||||||
|
* Get the last procedure name called by the backend ( the innermost,
|
||||||
* If a plpython procedure call calls the backend and the backend calls
|
* If a plpython procedure call calls the backend and the backend calls
|
||||||
* another plpython procedure )
|
* another plpython procedure )
|
||||||
|
*
|
||||||
|
* NB: this returns SQL name, not the internal Python procedure name
|
||||||
*/
|
*/
|
||||||
|
|
||||||
char *
|
char *
|
||||||
|
|
|
@ -30,8 +30,8 @@ echo -n "*** Running error handling tests."
|
||||||
psql -q -e $DBNAME < plpython_error.sql > error.output 2>&1
|
psql -q -e $DBNAME < plpython_error.sql > error.output 2>&1
|
||||||
echo " Done. ***"
|
echo " Done. ***"
|
||||||
|
|
||||||
echo -n "*** Checking the results of the feature tests"
|
echo -n "*** Checking the results of the feature tests."
|
||||||
if diff -u feature.expected feature.output > feature.diff 2>&1 ; then
|
if diff -c feature.expected feature.output > feature.diff 2>&1 ; then
|
||||||
echo -n " passed!"
|
echo -n " passed!"
|
||||||
else
|
else
|
||||||
echo -n " failed! Please examine feature.diff."
|
echo -n " failed! Please examine feature.diff."
|
||||||
|
@ -39,10 +39,9 @@ fi
|
||||||
echo " Done. ***"
|
echo " Done. ***"
|
||||||
|
|
||||||
echo -n "*** Checking the results of the error handling tests."
|
echo -n "*** Checking the results of the error handling tests."
|
||||||
diff -u error.expected error.output > error.diff 2>&1
|
if diff -c error.expected error.output > error.diff 2>&1 ; then
|
||||||
|
echo -n " passed!"
|
||||||
|
else
|
||||||
|
echo -n " failed! Please examine error.diff."
|
||||||
|
fi
|
||||||
echo " Done. ***"
|
echo " Done. ***"
|
||||||
echo "*** You need to check the file error.diff and make sure that"
|
|
||||||
echo " any differences are due only to the oid encoded in the "
|
|
||||||
echo " python function name. ***"
|
|
||||||
|
|
||||||
# or write a fancier error checker...
|
|
||||||
|
|
Loading…
Reference in New Issue