@ -28,13 +28,13 @@ static void PLy_add_exceptions(PyObject *plpy);
static void PLy_generate_spi_exceptions ( PyObject * mod , PyObject * base ) ;
/* module functions */
static PyObject * PLy_debug ( PyObject * self , PyObject * args ) ;
static PyObject * PLy_log ( PyObject * self , PyObject * args ) ;
static PyObject * PLy_info ( PyObject * self , PyObject * args ) ;
static PyObject * PLy_notice ( PyObject * self , PyObject * args ) ;
static PyObject * PLy_warning ( PyObject * self , PyObject * args ) ;
static PyObject * PLy_error ( PyObject * self , PyObject * args ) ;
static PyObject * PLy_fatal ( PyObject * self , PyObject * args ) ;
static PyObject * PLy_debug ( PyObject * self , PyObject * args , PyObject * kw ) ;
static PyObject * PLy_log ( PyObject * self , PyObject * args , PyObject * kw ) ;
static PyObject * PLy_info ( PyObject * self , PyObject * args , PyObject * kw ) ;
static PyObject * PLy_notice ( PyObject * self , PyObject * args , PyObject * kw ) ;
static PyObject * PLy_warning ( PyObject * self , PyObject * args , PyObject * kw ) ;
static PyObject * PLy_error ( PyObject * self , PyObject * args , PyObject * kw ) ;
static PyObject * PLy_fatal ( PyObject * self , PyObject * args , PyObject * kw ) ;
static PyObject * PLy_quote_literal ( PyObject * self , PyObject * args ) ;
static PyObject * PLy_quote_nullable ( PyObject * self , PyObject * args ) ;
static PyObject * PLy_quote_ident ( PyObject * self , PyObject * args ) ;
@ -57,13 +57,13 @@ static PyMethodDef PLy_methods[] = {
/*
* logging methods
*/
{ " debug " , PLy_debug , METH_VARARGS , NULL } ,
{ " log " , PLy_log , METH_VARARGS , NULL } ,
{ " info " , PLy_info , METH_VARARGS , NULL } ,
{ " notice " , PLy_notice , METH_VARARGS , NULL } ,
{ " warning " , PLy_warning , METH_VARARGS , NULL } ,
{ " error " , PLy_error , METH_VARARGS , NULL } ,
{ " fatal " , PLy_fatal , METH_VARARGS , NULL } ,
{ " debug " , ( PyCFunction ) PLy_debug , METH_VARARGS | METH_KEYWORD S , NULL } ,
{ " log " , ( PyCFunction ) PLy_log , METH_VARARGS | METH_KEYWORD S , NULL } ,
{ " info " , ( PyCFunction ) PLy_info , METH_VARARGS | METH_KEYWORD S , NULL } ,
{ " notice " , ( PyCFunction ) PLy_notice , METH_VARARGS | METH_KEYWORD S , NULL } ,
{ " warning " , ( PyCFunction ) PLy_warning , METH_VARARGS | METH_KEYWORD S , NULL } ,
{ " error " , ( PyCFunction ) PLy_error , METH_VARARGS | METH_KEYWORD S , NULL } ,
{ " fatal " , ( PyCFunction ) PLy_fatal , METH_VARARGS | METH_KEYWORD S , NULL } ,
/*
* create a stored plan
@ -271,48 +271,49 @@ PLy_generate_spi_exceptions(PyObject *mod, PyObject *base)
* the python interface to the elog function
* don ' t confuse these with PLy_elog
*/
static PyObject * PLy_output ( volatile int , PyObject * , PyObject * ) ;
static PyObject * PLy_output ( volatile int level , PyObject * self ,
PyObject * args , PyObject * kw ) ;
static PyObject *
PLy_debug ( PyObject * self , PyObject * args )
PLy_debug ( PyObject * self , PyObject * args , PyObject * kw )
{
return PLy_output ( DEBUG2 , self , args ) ;
return PLy_output ( DEBUG2 , self , args , kw ) ;
}
static PyObject *
PLy_log ( PyObject * self , PyObject * args )
PLy_log ( PyObject * self , PyObject * args , PyObject * kw )
{
return PLy_output ( LOG , self , args ) ;
return PLy_output ( LOG , self , args , kw ) ;
}
static PyObject *
PLy_info ( PyObject * self , PyObject * args )
PLy_info ( PyObject * self , PyObject * args , PyObject * kw )
{
return PLy_output ( INFO , self , args ) ;
return PLy_output ( INFO , self , args , kw ) ;
}
static PyObject *
PLy_notice ( PyObject * self , PyObject * args )
PLy_notice ( PyObject * self , PyObject * args , PyObject * kw )
{
return PLy_output ( NOTICE , self , args ) ;
return PLy_output ( NOTICE , self , args , kw ) ;
}
static PyObject *
PLy_warning ( PyObject * self , PyObject * args )
PLy_warning ( PyObject * self , PyObject * args , PyObject * kw )
{
return PLy_output ( WARNING , self , args ) ;
return PLy_output ( WARNING , self , args , kw ) ;
}
static PyObject *
PLy_error ( PyObject * self , PyObject * args )
PLy_error ( PyObject * self , PyObject * args , PyObject * kw )
{
return PLy_output ( ERROR , self , args ) ;
return PLy_output ( ERROR , self , args , kw ) ;
}
static PyObject *
PLy_fatal ( PyObject * self , PyObject * args )
PLy_fatal ( PyObject * self , PyObject * args , PyObject * kw )
{
return PLy_output ( FATAL , self , args ) ;
return PLy_output ( FATAL , self , args , kw ) ;
}
static PyObject *
@ -368,12 +369,45 @@ PLy_quote_ident(PyObject *self, PyObject *args)
return ret ;
}
/* enforce cast of object to string */
static char *
object_to_string ( PyObject * obj )
{
if ( obj )
{
PyObject * so = PyObject_Str ( obj ) ;
if ( so ! = NULL )
{
char * str ;
str = pstrdup ( PyString_AsString ( so ) ) ;
Py_DECREF ( so ) ;
return str ;
}
}
return NULL ;
}
static PyObject *
PLy_output ( volatile int level , PyObject * self , PyObject * args )
PLy_output ( volatile int level , PyObject * self , PyObject * args , PyObject * kw )
{
PyObject * volatile so ;
char * volatile sv ;
volatile MemoryContext oldcontext ;
int sqlstate = 0 ;
char * volatile sqlstatestr = NULL ;
char * volatile message = NULL ;
char * volatile detail = NULL ;
char * volatile hint = NULL ;
char * volatile column = NULL ;
char * volatile constraint = NULL ;
char * volatile datatype = NULL ;
char * volatile table = NULL ;
char * volatile schema = NULL ;
MemoryContext oldcontext ;
PyObject * key , * value ;
PyObject * volatile so ;
Py_ssize_t pos = 0 ;
if ( PyTuple_Size ( args ) = = 1 )
{
@ -389,40 +423,118 @@ PLy_output(volatile int level, PyObject *self, PyObject *args)
}
else
so = PyObject_Str ( args ) ;
if ( so = = NULL | | ( ( sv = PyString_AsString ( so ) ) = = NULL ) )
if ( so = = NULL | | ( ( message = pstrdup ( PyString_AsString ( so ) ) ) = = NULL ) )
{
level = ERROR ;
sv = dgettext ( TEXTDOMAIN , " could not parse error message in plpy.elog " ) ;
message = dgettext ( TEXTDOMAIN , " could not parse error message in plpy.elog " ) ;
}
Py_XDECREF ( so ) ;
if ( kw ! = NULL )
{
while ( PyDict_Next ( kw , & pos , & key , & value ) )
{
char * keyword = PyString_AsString ( key ) ;
if ( strcmp ( keyword , " message " ) = = 0 )
{
/* the message should not be overwriten */
if ( PyTuple_Size ( args ) ! = 0 )
PLy_elog ( ERROR , " the message is already specified " ) ;
pfree ( message ) ;
message = object_to_string ( value ) ;
}
else if ( strcmp ( keyword , " detail " ) = = 0 )
detail = object_to_string ( value ) ;
else if ( strcmp ( keyword , " hint " ) = = 0 )
hint = object_to_string ( value ) ;
else if ( strcmp ( keyword , " sqlstate " ) = = 0 )
sqlstatestr = object_to_string ( value ) ;
else if ( strcmp ( keyword , " schema " ) = = 0 )
schema = object_to_string ( value ) ;
else if ( strcmp ( keyword , " table " ) = = 0 )
table = object_to_string ( value ) ;
else if ( strcmp ( keyword , " column " ) = = 0 )
column = object_to_string ( value ) ;
else if ( strcmp ( keyword , " datatype " ) = = 0 )
datatype = object_to_string ( value ) ;
else if ( strcmp ( keyword , " constraint " ) = = 0 )
constraint = object_to_string ( value ) ;
else
PLy_elog ( ERROR , " '%s' is an invalid keyword argument for this function " ,
keyword ) ;
}
}
if ( sqlstatestr ! = NULL )
{
if ( strlen ( sqlstatestr ) ! = 5 )
PLy_elog ( ERROR , " invalid SQLSTATE code " ) ;
if ( strspn ( sqlstatestr , " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ " ) ! = 5 )
PLy_elog ( ERROR , " invalid SQLSTATE code " ) ;
sqlstate = MAKE_SQLSTATE ( sqlstatestr [ 0 ] ,
sqlstatestr [ 1 ] ,
sqlstatestr [ 2 ] ,
sqlstatestr [ 3 ] ,
sqlstatestr [ 4 ] ) ;
}
oldcontext = CurrentMemoryContext ;
PG_TRY ( ) ;
{
pg_verifymbstr ( sv , strlen ( sv ) , false ) ;
elog ( level , " %s " , sv ) ;
if ( message ! = NULL )
pg_verifymbstr ( message , strlen ( message ) , false ) ;
if ( detail ! = NULL )
pg_verifymbstr ( detail , strlen ( detail ) , false ) ;
if ( hint ! = NULL )
pg_verifymbstr ( hint , strlen ( hint ) , false ) ;
if ( schema ! = NULL )
pg_verifymbstr ( schema , strlen ( schema ) , false ) ;
if ( table ! = NULL )
pg_verifymbstr ( table , strlen ( table ) , false ) ;
if ( column ! = NULL )
pg_verifymbstr ( column , strlen ( column ) , false ) ;
if ( datatype ! = NULL )
pg_verifymbstr ( datatype , strlen ( datatype ) , false ) ;
if ( constraint ! = NULL )
pg_verifymbstr ( constraint , strlen ( constraint ) , false ) ;
ereport ( level ,
( ( sqlstate ! = 0 ) ? errcode ( sqlstate ) : 0 ,
( message ! = NULL ) ? errmsg_internal ( " %s " , message ) : 0 ,
( detail ! = NULL ) ? errdetail_internal ( " %s " , detail ) : 0 ,
( hint ! = NULL ) ? errhint ( " %s " , hint ) : 0 ,
( column ! = NULL ) ?
err_generic_string ( PG_DIAG_COLUMN_NAME , column ) : 0 ,
( constraint ! = NULL ) ?
err_generic_string ( PG_DIAG_CONSTRAINT_NAME , constraint ) : 0 ,
( datatype ! = NULL ) ?
err_generic_string ( PG_DIAG_DATATYPE_NAME , datatype ) : 0 ,
( table ! = NULL ) ?
err_generic_string ( PG_DIAG_TABLE_NAME , table ) : 0 ,
( schema ! = NULL ) ?
err_generic_string ( PG_DIAG_SCHEMA_NAME , schema ) : 0 ) ) ;
}
PG_CATCH ( ) ;
{
ErrorData * edata ;
ErrorData * edata ;
MemoryContextSwitchTo ( oldcontext ) ;
edata = CopyErrorData ( ) ;
FlushErrorState ( ) ;
/*
* Note : If sv came from PyString_AsString ( ) , it points into storage
* owned by so . So free so after using sv .
*/
Py_XDECREF ( so ) ;
PLy_exception_set_with_details ( PLy_exc_error , edata ) ;
FreeErrorData ( edata ) ;
/* Make Python raise the exception */
PLy_exception_set ( PLy_exc_error , " %s " , edata - > message ) ;
return NULL ;
}
PG_END_TRY ( ) ;
Py_XDECREF ( so ) ;
/*
* return a legal object so the interpreter will continue on its merry way
*/