Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
f8c8386a
Commit
f8c8386a
authored
Jan 15, 2009
by
Peter Eisentraut
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Cleanup pass over PL/Python NLS. Add translation support to PLy_elog and
PLy_exception_set, and clarify some error messages.
parent
d0fe3df7
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
106 additions
and
99 deletions
+106
-99
src/pl/plpython/Makefile
src/pl/plpython/Makefile
+2
-2
src/pl/plpython/expected/plpython_error.out
src/pl/plpython/expected/plpython_error.out
+16
-16
src/pl/plpython/expected/plpython_test.out
src/pl/plpython/expected/plpython_test.out
+2
-3
src/pl/plpython/nls.mk
src/pl/plpython/nls.mk
+2
-2
src/pl/plpython/plpython.c
src/pl/plpython/plpython.c
+84
-76
No files found.
src/pl/plpython/Makefile
View file @
f8c8386a
# $PostgreSQL: pgsql/src/pl/plpython/Makefile,v 1.3
1 2008/10/02 08:11:11
petere Exp $
# $PostgreSQL: pgsql/src/pl/plpython/Makefile,v 1.3
2 2009/01/15 13:49:56
petere Exp $
subdir
=
src/pl/plpython
subdir
=
src/pl/plpython
top_builddir
=
../../..
top_builddir
=
../../..
...
@@ -54,7 +54,7 @@ python${pytverstr}.def: $(WD)/system32/python${pytverstr}.dll
...
@@ -54,7 +54,7 @@ python${pytverstr}.def: $(WD)/system32/python${pytverstr}.dll
endif
endif
SHLIB_LINK
=
$(python_libspec)
$(python_additional_libs)
SHLIB_LINK
=
$(python_libspec)
$(python_additional_libs)
$(
filter
-lintl
,
$(LIBS)
)
REGRESS_OPTS
=
--dbname
=
$(PL_TESTDB)
--load-language
=
plpythonu
REGRESS_OPTS
=
--dbname
=
$(PL_TESTDB)
--load-language
=
plpythonu
REGRESS
=
plpython_schema plpython_populate plpython_function plpython_test plpython_error plpython_drop
REGRESS
=
plpython_schema plpython_populate plpython_function plpython_test plpython_error plpython_drop
...
...
src/pl/plpython/expected/plpython_error.out
View file @
f8c8386a
...
@@ -2,16 +2,16 @@
...
@@ -2,16 +2,16 @@
-- the trigger handler once. the errors and subsequent core dump were
-- the trigger handler once. the errors and subsequent core dump were
-- interesting.
-- interesting.
SELECT invalid_type_uncaught('rick');
SELECT invalid_type_uncaught('rick');
WARNING:
plpython: in function invalid_type_uncaught:
WARNING:
PL/Python: in PL/Python function "invalid_type_uncaught"
DETAIL:
plpy.SPIError: Unknown
error in PLy_spi_prepare
DETAIL:
<class 'plpy.SPIError'>: unrecognized
error in PLy_spi_prepare
ERROR: type "test" does not exist
ERROR: type "test" does not exist
SELECT invalid_type_caught('rick');
SELECT invalid_type_caught('rick');
WARNING:
plpython: in function invalid_type_caught:
WARNING:
PL/Python: in PL/Python function "invalid_type_caught"
DETAIL:
plpy.SPIError: Unknown
error in PLy_spi_prepare
DETAIL:
<class 'plpy.SPIError'>: unrecognized
error in PLy_spi_prepare
ERROR: type "test" does not exist
ERROR: type "test" does not exist
SELECT invalid_type_reraised('rick');
SELECT invalid_type_reraised('rick');
WARNING:
plpython: in function invalid_type_reraised:
WARNING:
PL/Python: in PL/Python function "invalid_type_reraised"
DETAIL:
plpy.SPIError: Unknown
error in PLy_spi_prepare
DETAIL:
<class 'plpy.SPIError'>: unrecognized
error in PLy_spi_prepare
ERROR: type "test" does not exist
ERROR: type "test" does not exist
SELECT valid_type('rick');
SELECT valid_type('rick');
valid_type
valid_type
...
@@ -23,16 +23,16 @@ SELECT valid_type('rick');
...
@@ -23,16 +23,16 @@ SELECT valid_type('rick');
-- Test Unicode error handling.
-- Test Unicode error handling.
--
--
SELECT unicode_return_error();
SELECT unicode_return_error();
ERROR:
plpython: function "unicode_return_error" could not create
return value
ERROR:
PL/Python: could not create string representation of Python object in PL/Python function "unicode_return_error" while creating
return value
DETAIL:
exceptions.UnicodeEncodeError
: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
DETAIL:
<type 'exceptions.UnicodeEncodeError'>
: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
INSERT INTO unicode_test (testvalue) VALUES ('test');
INSERT INTO unicode_test (testvalue) VALUES ('test');
ERROR:
plpython: function "unicode_trigger_error" could not modify tuple
ERROR:
PL/Python: could not compute string representation of Python object in PL/Python function "unicode_trigger_error" while modifying trigger row
DETAIL:
exceptions.UnicodeEncodeError
: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
DETAIL:
<type 'exceptions.UnicodeEncodeError'>
: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
SELECT unicode_plan_error1();
SELECT unicode_plan_error1();
WARNING:
plpython: in function unicode_plan_error1:
WARNING:
PL/Python: in PL/Python function "unicode_plan_error1"
DETAIL:
plpy.Error: Unknown
error in PLy_spi_execute_plan
DETAIL:
<class 'plpy.Error'>: unrecognized
error in PLy_spi_execute_plan
ERROR:
plpython:
function "unicode_plan_error1" could not execute plan
ERROR:
PL/Python: PL/Python
function "unicode_plan_error1" could not execute plan
DETAIL:
exceptions.UnicodeEncodeError
: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
DETAIL:
<type 'exceptions.UnicodeEncodeError'>
: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
SELECT unicode_plan_error2();
SELECT unicode_plan_error2();
ERROR:
plpython:
function "unicode_plan_error2" could not execute plan
ERROR:
PL/Python: PL/Python
function "unicode_plan_error2" could not execute plan
DETAIL:
exceptions.UnicodeEncodeError
: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
DETAIL:
<type 'exceptions.UnicodeEncodeError'>
: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
src/pl/plpython/expected/plpython_test.out
View file @
f8c8386a
...
@@ -190,8 +190,7 @@ SELECT test_void_func1(), test_void_func1() IS NULL AS "is null";
...
@@ -190,8 +190,7 @@ SELECT test_void_func1(), test_void_func1() IS NULL AS "is null";
(1 row)
(1 row)
SELECT test_void_func2(); -- should fail
SELECT test_void_func2(); -- should fail
ERROR: invalid return value from plpython function
ERROR: PL/Python function with return type "void" did not return None
DETAIL: Functions returning type "void" must return None.
SELECT test_return_none(), test_return_none() IS NULL AS "is null";
SELECT test_return_none(), test_return_none() IS NULL AS "is null";
test_return_none | is null
test_return_none | is null
------------------+---------
------------------+---------
...
@@ -547,7 +546,7 @@ SELECT * FROM test_in_out_params('test_in');
...
@@ -547,7 +546,7 @@ SELECT * FROM test_in_out_params('test_in');
-- this doesn't work yet :-(
-- this doesn't work yet :-(
SELECT * FROM test_in_out_params_multi('test_in');
SELECT * FROM test_in_out_params_multi('test_in');
ERROR:
plp
ython functions cannot return type record
ERROR:
PL/P
ython functions cannot return type record
SELECT * FROM test_inout_params('test_in');
SELECT * FROM test_inout_params('test_in');
first
first
---------------
---------------
...
...
src/pl/plpython/nls.mk
View file @
f8c8386a
# $PostgreSQL: pgsql/src/pl/plpython/nls.mk,v 1.
1 2008/10/09 17:24:05 alvher
re Exp $
# $PostgreSQL: pgsql/src/pl/plpython/nls.mk,v 1.
2 2009/01/15 13:49:56 pete
re Exp $
CATALOG_NAME
:=
plpython
CATALOG_NAME
:=
plpython
AVAIL_LANGUAGES
:=
AVAIL_LANGUAGES
:=
GETTEXT_FILES
:=
plpython.c
GETTEXT_FILES
:=
plpython.c
GETTEXT_TRIGGERS
:=
_ errmsg errdetail errdetail_log errhint errcontext write_stderr yyerror
GETTEXT_TRIGGERS
:=
errmsg errdetail errdetail_log errhint errcontext PLy_elog:2 PLy_exception_set:2
src/pl/plpython/plpython.c
View file @
f8c8386a
/**********************************************************************
/**********************************************************************
* plpython.c - python as a procedural language for PostgreSQL
* plpython.c - python as a procedural language for PostgreSQL
*
*
* $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.11
7 2008/12/11 07:34:09
petere Exp $
* $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.11
8 2009/01/15 13:49:56
petere Exp $
*
*
*********************************************************************
*********************************************************************
*/
*/
...
@@ -204,7 +204,7 @@ PG_FUNCTION_INFO_V1(plpython_call_handler);
...
@@ -204,7 +204,7 @@ PG_FUNCTION_INFO_V1(plpython_call_handler);
static
void
PLy_init_interp
(
void
);
static
void
PLy_init_interp
(
void
);
static
void
PLy_init_plpy
(
void
);
static
void
PLy_init_plpy
(
void
);
/* call PyErr_SetString with a vprint interface */
/* call PyErr_SetString with a vprint interface
and translation support
*/
static
void
static
void
PLy_exception_set
(
PyObject
*
,
const
char
*
,...)
PLy_exception_set
(
PyObject
*
,
const
char
*
,...)
__attribute__
((
format
(
printf
,
2
,
3
)));
__attribute__
((
format
(
printf
,
2
,
3
)));
...
@@ -213,7 +213,8 @@ __attribute__((format(printf, 2, 3)));
...
@@ -213,7 +213,8 @@ __attribute__((format(printf, 2, 3)));
static
char
*
PLy_procedure_name
(
PLyProcedure
*
);
static
char
*
PLy_procedure_name
(
PLyProcedure
*
);
/* some utility functions */
/* some utility functions */
static
void
PLy_elog
(
int
,
const
char
*
,...);
static
void
PLy_elog
(
int
,
const
char
*
,...)
__attribute__
((
format
(
printf
,
2
,
3
)));
static
char
*
PLy_traceback
(
int
*
);
static
char
*
PLy_traceback
(
int
*
);
static
void
*
PLy_malloc
(
size_t
);
static
void
*
PLy_malloc
(
size_t
);
...
@@ -331,7 +332,7 @@ plpython_call_handler(PG_FUNCTION_ARGS)
...
@@ -331,7 +332,7 @@ plpython_call_handler(PG_FUNCTION_ARGS)
PLyProcedure
*
volatile
proc
=
NULL
;
PLyProcedure
*
volatile
proc
=
NULL
;
if
(
SPI_connect
()
!=
SPI_OK_CONNECT
)
if
(
SPI_connect
()
!=
SPI_OK_CONNECT
)
elog
(
ERROR
,
"
could not connect to SPI manager
"
);
elog
(
ERROR
,
"
SPI_connect failed
"
);
save_curr_proc
=
PLy_curr_procedure
;
save_curr_proc
=
PLy_curr_procedure
;
...
@@ -417,7 +418,7 @@ PLy_trigger_handler(FunctionCallInfo fcinfo, PLyProcedure * proc)
...
@@ -417,7 +418,7 @@ PLy_trigger_handler(FunctionCallInfo fcinfo, PLyProcedure * proc)
ereport
(
ERROR
,
ereport
(
ERROR
,
(
errcode
(
ERRCODE_DATA_EXCEPTION
),
(
errcode
(
ERRCODE_DATA_EXCEPTION
),
errmsg
(
"unexpected return value from trigger procedure"
),
errmsg
(
"unexpected return value from trigger procedure"
),
errdetail
(
"Expected None or a
S
tring."
)));
errdetail
(
"Expected None or a
s
tring."
)));
srv
=
PyString_AsString
(
plrv
);
srv
=
PyString_AsString
(
plrv
);
if
(
pg_strcasecmp
(
srv
,
"SKIP"
)
==
0
)
if
(
pg_strcasecmp
(
srv
,
"SKIP"
)
==
0
)
...
@@ -430,7 +431,8 @@ PLy_trigger_handler(FunctionCallInfo fcinfo, PLyProcedure * proc)
...
@@ -430,7 +431,8 @@ PLy_trigger_handler(FunctionCallInfo fcinfo, PLyProcedure * proc)
TRIGGER_FIRED_BY_UPDATE
(
tdata
->
tg_event
))
TRIGGER_FIRED_BY_UPDATE
(
tdata
->
tg_event
))
rv
=
PLy_modify_tuple
(
proc
,
plargs
,
tdata
,
rv
);
rv
=
PLy_modify_tuple
(
proc
,
plargs
,
tdata
,
rv
);
else
else
elog
(
WARNING
,
"ignoring modified tuple in DELETE trigger"
);
ereport
(
WARNING
,
(
errmsg
(
"PL/Python trigger function returned
\"
MODIFY
\"
in a DELETE trigger -- ignored"
)));
}
}
else
if
(
pg_strcasecmp
(
srv
,
"OK"
)
!=
0
)
else
if
(
pg_strcasecmp
(
srv
,
"OK"
)
!=
0
)
{
{
...
@@ -487,9 +489,11 @@ PLy_modify_tuple(PLyProcedure * proc, PyObject * pltd, TriggerData *tdata,
...
@@ -487,9 +489,11 @@ PLy_modify_tuple(PLyProcedure * proc, PyObject * pltd, TriggerData *tdata,
PG_TRY
();
PG_TRY
();
{
{
if
((
plntup
=
PyDict_GetItemString
(
pltd
,
"new"
))
==
NULL
)
if
((
plntup
=
PyDict_GetItemString
(
pltd
,
"new"
))
==
NULL
)
elog
(
ERROR
,
"TD[
\"
new
\"
] deleted, cannot modify tuple"
);
ereport
(
ERROR
,
(
errmsg
(
"TD[
\"
new
\"
] deleted, cannot modify row"
)));
if
(
!
PyDict_Check
(
plntup
))
if
(
!
PyDict_Check
(
plntup
))
elog
(
ERROR
,
"TD[
\"
new
\"
] is not a dictionary object"
);
ereport
(
ERROR
,
(
errmsg
(
"TD[
\"
new
\"
] is not a dictionary"
)));
Py_INCREF
(
plntup
);
Py_INCREF
(
plntup
);
plkeys
=
PyDict_Keys
(
plntup
);
plkeys
=
PyDict_Keys
(
plntup
);
...
@@ -507,16 +511,18 @@ PLy_modify_tuple(PLyProcedure * proc, PyObject * pltd, TriggerData *tdata,
...
@@ -507,16 +511,18 @@ PLy_modify_tuple(PLyProcedure * proc, PyObject * pltd, TriggerData *tdata,
platt
=
PyList_GetItem
(
plkeys
,
i
);
platt
=
PyList_GetItem
(
plkeys
,
i
);
if
(
!
PyString_Check
(
platt
))
if
(
!
PyString_Check
(
platt
))
elog
(
ERROR
,
"attribute name is not a string"
);
ereport
(
ERROR
,
(
errmsg
(
"name of TD[
\"
new
\"
] attribute at ordinal position %d is not a string"
,
i
)));
attn
=
SPI_fnumber
(
tupdesc
,
PyString_AsString
(
platt
));
attn
=
SPI_fnumber
(
tupdesc
,
PyString_AsString
(
platt
));
if
(
attn
==
SPI_ERROR_NOATTRIBUTE
)
if
(
attn
==
SPI_ERROR_NOATTRIBUTE
)
elog
(
ERROR
,
"invalid attribute
\"
%s
\"
in tuple"
,
ereport
(
ERROR
,
PyString_AsString
(
platt
));
(
errmsg
(
"key
\"
%s
\"
found in TD[
\"
new
\"
] does not exist as a column in the triggering row"
,
PyString_AsString
(
platt
))));
atti
=
attn
-
1
;
atti
=
attn
-
1
;
plval
=
PyDict_GetItem
(
plntup
,
platt
);
plval
=
PyDict_GetItem
(
plntup
,
platt
);
if
(
plval
==
NULL
)
if
(
plval
==
NULL
)
elog
(
FATAL
,
"
p
ython interpreter is probably corrupted"
);
elog
(
FATAL
,
"
P
ython interpreter is probably corrupted"
);
Py_INCREF
(
plval
);
Py_INCREF
(
plval
);
...
@@ -531,7 +537,7 @@ PLy_modify_tuple(PLyProcedure * proc, PyObject * pltd, TriggerData *tdata,
...
@@ -531,7 +537,7 @@ PLy_modify_tuple(PLyProcedure * proc, PyObject * pltd, TriggerData *tdata,
{
{
plstr
=
PyObject_Str
(
plval
);
plstr
=
PyObject_Str
(
plval
);
if
(
!
plstr
)
if
(
!
plstr
)
PLy_elog
(
ERROR
,
"
function
\"
%s
\"
could not modify tuple
"
,
PLy_elog
(
ERROR
,
"
could not compute string representation of Python object in PL/Python function
\"
%s
\"
while modifying trigger row
"
,
proc
->
proname
);
proc
->
proname
);
src
=
PyString_AsString
(
plstr
);
src
=
PyString_AsString
(
plstr
);
...
@@ -562,7 +568,7 @@ PLy_modify_tuple(PLyProcedure * proc, PyObject * pltd, TriggerData *tdata,
...
@@ -562,7 +568,7 @@ PLy_modify_tuple(PLyProcedure * proc, PyObject * pltd, TriggerData *tdata,
rtup
=
SPI_modifytuple
(
tdata
->
tg_relation
,
otup
,
natts
,
rtup
=
SPI_modifytuple
(
tdata
->
tg_relation
,
otup
,
natts
,
modattrs
,
modvalues
,
modnulls
);
modattrs
,
modvalues
,
modnulls
);
if
(
rtup
==
NULL
)
if
(
rtup
==
NULL
)
elog
(
ERROR
,
"SPI_modifytuple failed
--
error %d"
,
SPI_result
);
elog
(
ERROR
,
"SPI_modifytuple failed
:
error %d"
,
SPI_result
);
}
}
PG_CATCH
();
PG_CATCH
();
{
{
...
@@ -613,7 +619,7 @@ PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure * proc, HeapTuple *
...
@@ -613,7 +619,7 @@ PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure * proc, HeapTuple *
{
{
pltdata
=
PyDict_New
();
pltdata
=
PyDict_New
();
if
(
!
pltdata
)
if
(
!
pltdata
)
PLy_elog
(
ERROR
,
"could not
build arguments for trigger procedure
"
);
PLy_elog
(
ERROR
,
"could not
create new dictionary while building trigger arguments
"
);
pltname
=
PyString_FromString
(
tdata
->
tg_trigger
->
tgname
);
pltname
=
PyString_FromString
(
tdata
->
tg_trigger
->
tgname
);
PyDict_SetItemString
(
pltdata
,
"name"
,
pltname
);
PyDict_SetItemString
(
pltdata
,
"name"
,
pltname
);
...
@@ -821,7 +827,8 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure * proc)
...
@@ -821,7 +827,8 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure * proc)
{
{
ereport
(
ERROR
,
ereport
(
ERROR
,
(
errcode
(
ERRCODE_FEATURE_NOT_SUPPORTED
),
(
errcode
(
ERRCODE_FEATURE_NOT_SUPPORTED
),
errmsg
(
"only value per call is allowed"
)));
errmsg
(
"unsupported set function return mode"
),
errdetail
(
"PL/Python set-returning functions only support returning only value per call."
)));
}
}
rsi
->
returnMode
=
SFRM_ValuePerCall
;
rsi
->
returnMode
=
SFRM_ValuePerCall
;
...
@@ -834,7 +841,7 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure * proc)
...
@@ -834,7 +841,7 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure * proc)
ereport
(
ERROR
,
ereport
(
ERROR
,
(
errcode
(
ERRCODE_DATATYPE_MISMATCH
),
(
errcode
(
ERRCODE_DATATYPE_MISMATCH
),
errmsg
(
"returned object cannot be iterated"
),
errmsg
(
"returned object cannot be iterated"
),
errdetail
(
"
SETOF must be returned as iterable object
"
)));
errdetail
(
"
PL/Python set-returning functions must return an iterable object.
"
)));
}
}
/* Fetch next from iterator */
/* Fetch next from iterator */
...
@@ -880,8 +887,7 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure * proc)
...
@@ -880,8 +887,7 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure * proc)
if
(
plrv
!=
Py_None
)
if
(
plrv
!=
Py_None
)
ereport
(
ERROR
,
ereport
(
ERROR
,
(
errcode
(
ERRCODE_DATATYPE_MISMATCH
),
(
errcode
(
ERRCODE_DATATYPE_MISMATCH
),
errmsg
(
"invalid return value from plpython function"
),
errmsg
(
"PL/Python function with return type
\"
void
\"
did not return None"
)));
errdetail
(
"Functions returning type
\"
void
\"
must return None."
)));
fcinfo
->
isnull
=
false
;
fcinfo
->
isnull
=
false
;
rv
=
(
Datum
)
0
;
rv
=
(
Datum
)
0
;
...
@@ -928,7 +934,7 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure * proc)
...
@@ -928,7 +934,7 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure * proc)
fcinfo
->
isnull
=
false
;
fcinfo
->
isnull
=
false
;
plrv_so
=
PyObject_Str
(
plrv
);
plrv_so
=
PyObject_Str
(
plrv
);
if
(
!
plrv_so
)
if
(
!
plrv_so
)
PLy_elog
(
ERROR
,
"
function
\"
%s
\"
could not create
return value"
,
proc
->
proname
);
PLy_elog
(
ERROR
,
"
could not create string representation of Python object in PL/Python function
\"
%s
\"
while creating
return value"
,
proc
->
proname
);
plrv_sc
=
PyString_AsString
(
plrv_so
);
plrv_sc
=
PyString_AsString
(
plrv_so
);
rv
=
InputFunctionCall
(
&
proc
->
result
.
out
.
d
.
typfunc
,
rv
=
InputFunctionCall
(
&
proc
->
result
.
out
.
d
.
typfunc
,
plrv_sc
,
plrv_sc
,
...
@@ -977,7 +983,7 @@ PLy_procedure_call(PLyProcedure * proc, char *kargs, PyObject * vargs)
...
@@ -977,7 +983,7 @@ PLy_procedure_call(PLyProcedure * proc, char *kargs, PyObject * vargs)
if
(
rv
==
NULL
||
PyErr_Occurred
())
if
(
rv
==
NULL
||
PyErr_Occurred
())
{
{
Py_XDECREF
(
rv
);
Py_XDECREF
(
rv
);
PLy_elog
(
ERROR
,
"function
\"
%s
\"
failed"
,
proc
->
proname
);
PLy_elog
(
ERROR
,
"
PL/Python
function
\"
%s
\"
failed"
,
proc
->
proname
);
}
}
return
rv
;
return
rv
;
...
@@ -1049,7 +1055,7 @@ PLy_function_build_args(FunctionCallInfo fcinfo, PLyProcedure * proc)
...
@@ -1049,7 +1055,7 @@ PLy_function_build_args(FunctionCallInfo fcinfo, PLyProcedure * proc)
if
(
PyList_SetItem
(
args
,
i
,
arg
)
==
-
1
||
if
(
PyList_SetItem
(
args
,
i
,
arg
)
==
-
1
||
(
proc
->
argnames
&&
(
proc
->
argnames
&&
PyDict_SetItemString
(
proc
->
globals
,
proc
->
argnames
[
i
],
arg
)
==
-
1
))
PyDict_SetItemString
(
proc
->
globals
,
proc
->
argnames
[
i
],
arg
)
==
-
1
))
PLy_elog
(
ERROR
,
"
problem setting up arguments for
\"
%s
\"
"
,
proc
->
proname
);
PLy_elog
(
ERROR
,
"
PyDict_SetItemString() failed for PL/Python function
\"
%s
\"
while setting up arguments
"
,
proc
->
proname
);
arg
=
NULL
;
arg
=
NULL
;
}
}
}
}
...
@@ -1230,7 +1236,7 @@ PLy_procedure_create(HeapTuple procTup, Oid tgreloid, char *key)
...
@@ -1230,7 +1236,7 @@ PLy_procedure_create(HeapTuple procTup, Oid tgreloid, char *key)
else
else
ereport
(
ERROR
,
ereport
(
ERROR
,
(
errcode
(
ERRCODE_FEATURE_NOT_SUPPORTED
),
(
errcode
(
ERRCODE_FEATURE_NOT_SUPPORTED
),
errmsg
(
"
plp
ython functions cannot return type %s"
,
errmsg
(
"
PL/P
ython functions cannot return type %s"
,
format_type_be
(
procStruct
->
prorettype
))));
format_type_be
(
procStruct
->
prorettype
))));
}
}
...
@@ -1309,7 +1315,7 @@ PLy_procedure_create(HeapTuple procTup, Oid tgreloid, char *key)
...
@@ -1309,7 +1315,7 @@ PLy_procedure_create(HeapTuple procTup, Oid tgreloid, char *key)
/* Disallow pseudotype argument */
/* Disallow pseudotype argument */
ereport
(
ERROR
,
ereport
(
ERROR
,
(
errcode
(
ERRCODE_FEATURE_NOT_SUPPORTED
),
(
errcode
(
ERRCODE_FEATURE_NOT_SUPPORTED
),
errmsg
(
"
plpython functions cannot take
type %s"
,
errmsg
(
"
PL/Python functions cannot accept
type %s"
,
format_type_be
(
types
[
i
]))));
format_type_be
(
types
[
i
]))));
break
;
break
;
case
TYPTYPE_COMPOSITE
:
case
TYPTYPE_COMPOSITE
:
...
@@ -1403,7 +1409,7 @@ PLy_procedure_compile(PLyProcedure * proc, const char *src)
...
@@ -1403,7 +1409,7 @@ PLy_procedure_compile(PLyProcedure * proc, const char *src)
else
else
Py_XDECREF
(
crv
);
Py_XDECREF
(
crv
);
PLy_elog
(
ERROR
,
"could not compile function
\"
%s
\"
"
,
proc
->
proname
);
PLy_elog
(
ERROR
,
"could not compile
PL/Python
function
\"
%s
\"
"
,
proc
->
proname
);
}
}
static
char
*
static
char
*
...
@@ -1480,8 +1486,9 @@ PLy_procedure_delete(PLyProcedure * proc)
...
@@ -1480,8 +1486,9 @@ PLy_procedure_delete(PLyProcedure * proc)
PLy_free
(
proc
->
argnames
);
PLy_free
(
proc
->
argnames
);
}
}
/* conversion functions. remember output from python is
/*
* input to postgresql, and vis versa.
* Conversion functions. Remember output from Python is input to
* PostgreSQL, and vice versa.
*/
*/
static
void
static
void
PLy_input_tuple_funcs
(
PLyTypeInfo
*
arg
,
TupleDesc
desc
)
PLy_input_tuple_funcs
(
PLyTypeInfo
*
arg
,
TupleDesc
desc
)
...
@@ -1714,7 +1721,7 @@ PLyDict_FromTuple(PLyTypeInfo * info, HeapTuple tuple, TupleDesc desc)
...
@@ -1714,7 +1721,7 @@ PLyDict_FromTuple(PLyTypeInfo * info, HeapTuple tuple, TupleDesc desc)
dict
=
PyDict_New
();
dict
=
PyDict_New
();
if
(
dict
==
NULL
)
if
(
dict
==
NULL
)
PLy_elog
(
ERROR
,
"could not create
tuple
dictionary"
);
PLy_elog
(
ERROR
,
"could not create
new
dictionary"
);
PG_TRY
();
PG_TRY
();
{
{
...
@@ -1801,7 +1808,7 @@ PLyMapping_ToTuple(PLyTypeInfo * info, PyObject * mapping)
...
@@ -1801,7 +1808,7 @@ PLyMapping_ToTuple(PLyTypeInfo * info, PyObject * mapping)
so
=
PyObject_Str
(
value
);
so
=
PyObject_Str
(
value
);
if
(
so
==
NULL
)
if
(
so
==
NULL
)
PLy_elog
(
ERROR
,
"c
annot convert mapping type
"
);
PLy_elog
(
ERROR
,
"c
ould not compute string representation of Python object
"
);
valuestr
=
PyString_AsString
(
so
);
valuestr
=
PyString_AsString
(
so
);
values
[
i
]
=
InputFunctionCall
(
&
info
->
out
.
r
.
atts
[
i
].
typfunc
values
[
i
]
=
InputFunctionCall
(
&
info
->
out
.
r
.
atts
[
i
].
typfunc
...
@@ -1815,9 +1822,9 @@ PLyMapping_ToTuple(PLyTypeInfo * info, PyObject * mapping)
...
@@ -1815,9 +1822,9 @@ PLyMapping_ToTuple(PLyTypeInfo * info, PyObject * mapping)
else
else
ereport
(
ERROR
,
ereport
(
ERROR
,
(
errcode
(
ERRCODE_UNDEFINED_COLUMN
),
(
errcode
(
ERRCODE_UNDEFINED_COLUMN
),
errmsg
(
"
no mapping found with key
\"
%s
\"
"
,
key
),
errmsg
(
"
key
\"
%s
\"
not found in mapping
"
,
key
),
errhint
(
"
to return null in specific
column, "
errhint
(
"
To return null in a
column, "
"add
value None to map with key named after column
"
)));
"add
the value None to the mapping with the key named after the column.
"
)));
Py_XDECREF
(
value
);
Py_XDECREF
(
value
);
value
=
NULL
;
value
=
NULL
;
...
@@ -1860,7 +1867,7 @@ PLySequence_ToTuple(PLyTypeInfo * info, PyObject * sequence)
...
@@ -1860,7 +1867,7 @@ PLySequence_ToTuple(PLyTypeInfo * info, PyObject * sequence)
if
(
PySequence_Length
(
sequence
)
!=
desc
->
natts
)
if
(
PySequence_Length
(
sequence
)
!=
desc
->
natts
)
ereport
(
ERROR
,
ereport
(
ERROR
,
(
errcode
(
ERRCODE_DATATYPE_MISMATCH
),
(
errcode
(
ERRCODE_DATATYPE_MISMATCH
),
errmsg
(
"
returned sequence's length must be same as tuple's length
"
)));
errmsg
(
"
length of returned sequence did not match number of columns in row
"
)));
if
(
info
->
is_rowtype
==
2
)
if
(
info
->
is_rowtype
==
2
)
PLy_output_tuple_funcs
(
info
,
desc
);
PLy_output_tuple_funcs
(
info
,
desc
);
...
@@ -1890,7 +1897,7 @@ PLySequence_ToTuple(PLyTypeInfo * info, PyObject * sequence)
...
@@ -1890,7 +1897,7 @@ PLySequence_ToTuple(PLyTypeInfo * info, PyObject * sequence)
so
=
PyObject_Str
(
value
);
so
=
PyObject_Str
(
value
);
if
(
so
==
NULL
)
if
(
so
==
NULL
)
PLy_elog
(
ERROR
,
"c
annot convert sequence type
"
);
PLy_elog
(
ERROR
,
"c
ould not compute string representation of Python object
"
);
valuestr
=
PyString_AsString
(
so
);
valuestr
=
PyString_AsString
(
so
);
values
[
i
]
=
InputFunctionCall
(
&
info
->
out
.
r
.
atts
[
i
].
typfunc
values
[
i
]
=
InputFunctionCall
(
&
info
->
out
.
r
.
atts
[
i
].
typfunc
,
valuestr
,
valuestr
...
@@ -1961,7 +1968,7 @@ PLyObject_ToTuple(PLyTypeInfo * info, PyObject * object)
...
@@ -1961,7 +1968,7 @@ PLyObject_ToTuple(PLyTypeInfo * info, PyObject * object)
so
=
PyObject_Str
(
value
);
so
=
PyObject_Str
(
value
);
if
(
so
==
NULL
)
if
(
so
==
NULL
)
PLy_elog
(
ERROR
,
"c
annot convert object type
"
);
PLy_elog
(
ERROR
,
"c
ould not compute string representation of Python object
"
);
valuestr
=
PyString_AsString
(
so
);
valuestr
=
PyString_AsString
(
so
);
values
[
i
]
=
InputFunctionCall
(
&
info
->
out
.
r
.
atts
[
i
].
typfunc
values
[
i
]
=
InputFunctionCall
(
&
info
->
out
.
r
.
atts
[
i
].
typfunc
,
valuestr
,
valuestr
...
@@ -1974,10 +1981,10 @@ PLyObject_ToTuple(PLyTypeInfo * info, PyObject * object)
...
@@ -1974,10 +1981,10 @@ PLyObject_ToTuple(PLyTypeInfo * info, PyObject * object)
else
else
ereport
(
ERROR
,
ereport
(
ERROR
,
(
errcode
(
ERRCODE_UNDEFINED_COLUMN
),
(
errcode
(
ERRCODE_UNDEFINED_COLUMN
),
errmsg
(
"
no attribute named
\"
%s
\"
"
,
key
),
errmsg
(
"
attribute
\"
%s
\"
does not exist in Python object
"
,
key
),
errhint
(
"
to return null in specific
column, "
errhint
(
"
To return null in a
column, "
"let returned object to have
attribute named "
"let the returned object have an
attribute named "
"after column with value None"
)));
"after column with value None
.
"
)));
Py_XDECREF
(
value
);
Py_XDECREF
(
value
);
value
=
NULL
;
value
=
NULL
;
...
@@ -2197,7 +2204,7 @@ PLy_plan_status(PyObject * self, PyObject * args)
...
@@ -2197,7 +2204,7 @@ PLy_plan_status(PyObject * self, PyObject * args)
return
Py_True
;
return
Py_True
;
/* return PyInt_FromLong(self->status); */
/* return PyInt_FromLong(self->status); */
}
}
P
yErr_SetString
(
PLy_exc_error
,
"plan.status()
takes no arguments"
);
P
Ly_exception_set
(
PLy_exc_error
,
"plan.status
takes no arguments"
);
return
NULL
;
return
NULL
;
}
}
...
@@ -2327,21 +2334,21 @@ PLy_spi_prepare(PyObject * self, PyObject * args)
...
@@ -2327,21 +2334,21 @@ PLy_spi_prepare(PyObject * self, PyObject * args)
/* Can't execute more if we have an unhandled error */
/* Can't execute more if we have an unhandled error */
if
(
PLy_error_in_progress
)
if
(
PLy_error_in_progress
)
{
{
P
yErr_SetString
(
PLy_exc_error
,
"Transaction aborted.
"
);
P
Ly_exception_set
(
PLy_exc_error
,
"transaction aborted
"
);
return
NULL
;
return
NULL
;
}
}
if
(
!
PyArg_ParseTuple
(
args
,
"s|O"
,
&
query
,
&
list
))
if
(
!
PyArg_ParseTuple
(
args
,
"s|O"
,
&
query
,
&
list
))
{
{
P
yErr_SetString
(
PLy_exc_spi_error
,
P
Ly_exception_set
(
PLy_exc_spi_error
,
"Invalid arguments for plpy.prepare()
"
);
"invalid arguments for plpy.prepare
"
);
return
NULL
;
return
NULL
;
}
}
if
(
list
&&
(
!
PySequence_Check
(
list
)))
if
(
list
&&
(
!
PySequence_Check
(
list
)))
{
{
P
yErr_SetString
(
PLy_exc_spi_error
,
P
Ly_exception_set
(
PLy_exc_spi_error
,
"Second argument in plpy.prepare()
must be a sequence"
);
"second argument of plpy.prepare
must be a sequence"
);
return
NULL
;
return
NULL
;
}
}
...
@@ -2385,7 +2392,8 @@ PLy_spi_prepare(PyObject * self, PyObject * args)
...
@@ -2385,7 +2392,8 @@ PLy_spi_prepare(PyObject * self, PyObject * args)
optr
=
PySequence_GetItem
(
list
,
i
);
optr
=
PySequence_GetItem
(
list
,
i
);
if
(
!
PyString_Check
(
optr
))
if
(
!
PyString_Check
(
optr
))
elog
(
ERROR
,
"Type names must be strings."
);
ereport
(
ERROR
,
(
errmsg
(
"plpy.prepare: type name at ordinal position %d is not a string"
,
i
)));
sptr
=
PyString_AsString
(
optr
);
sptr
=
PyString_AsString
(
optr
);
/********************************************************
/********************************************************
...
@@ -2410,7 +2418,9 @@ PLy_spi_prepare(PyObject * self, PyObject * args)
...
@@ -2410,7 +2418,9 @@ PLy_spi_prepare(PyObject * self, PyObject * args)
if
(
typeStruct
->
typtype
!=
TYPTYPE_COMPOSITE
)
if
(
typeStruct
->
typtype
!=
TYPTYPE_COMPOSITE
)
PLy_output_datum_func
(
&
plan
->
args
[
i
],
typeTup
);
PLy_output_datum_func
(
&
plan
->
args
[
i
],
typeTup
);
else
else
elog
(
ERROR
,
"tuples not handled in plpy.prepare, yet."
);
ereport
(
ERROR
,
(
errcode
(
ERRCODE_FEATURE_NOT_SUPPORTED
),
errmsg
(
"plpy.prepare does not support composite types"
)));
ReleaseSysCache
(
typeTup
);
ReleaseSysCache
(
typeTup
);
}
}
}
}
...
@@ -2437,10 +2447,10 @@ PLy_spi_prepare(PyObject * self, PyObject * args)
...
@@ -2437,10 +2447,10 @@ PLy_spi_prepare(PyObject * self, PyObject * args)
Py_DECREF
(
plan
);
Py_DECREF
(
plan
);
Py_XDECREF
(
optr
);
Py_XDECREF
(
optr
);
if
(
!
PyErr_Occurred
())
if
(
!
PyErr_Occurred
())
P
yErr_SetString
(
PLy_exc_spi_error
,
P
Ly_exception_set
(
PLy_exc_spi_error
,
"Unknown
error in PLy_spi_prepare"
);
"unrecognized
error in PLy_spi_prepare"
);
/* XXX this oughta be replaced with errcontext mechanism */
/* XXX this oughta be replaced with errcontext mechanism */
PLy_elog
(
WARNING
,
"in
function %s:
"
,
PLy_elog
(
WARNING
,
"in
PL/Python function
\"
%s
\"
"
,
PLy_procedure_name
(
PLy_curr_procedure
));
PLy_procedure_name
(
PLy_curr_procedure
));
return
NULL
;
return
NULL
;
}
}
...
@@ -2463,7 +2473,7 @@ PLy_spi_execute(PyObject * self, PyObject * args)
...
@@ -2463,7 +2473,7 @@ PLy_spi_execute(PyObject * self, PyObject * args)
/* Can't execute more if we have an unhandled error */
/* Can't execute more if we have an unhandled error */
if
(
PLy_error_in_progress
)
if
(
PLy_error_in_progress
)
{
{
P
yErr_SetString
(
PLy_exc_error
,
"Transaction aborted.
"
);
P
Ly_exception_set
(
PLy_exc_error
,
"transaction aborted
"
);
return
NULL
;
return
NULL
;
}
}
...
@@ -2476,7 +2486,7 @@ PLy_spi_execute(PyObject * self, PyObject * args)
...
@@ -2476,7 +2486,7 @@ PLy_spi_execute(PyObject * self, PyObject * args)
is_PLyPlanObject
(
plan
))
is_PLyPlanObject
(
plan
))
return
PLy_spi_execute_plan
(
plan
,
list
,
limit
);
return
PLy_spi_execute_plan
(
plan
,
list
,
limit
);
P
yErr_SetString
(
PLy_exc_error
,
"Expected a query or plan.
"
);
P
Ly_exception_set
(
PLy_exc_error
,
"plpy.execute expected a query or a plan
"
);
return
NULL
;
return
NULL
;
}
}
...
@@ -2493,9 +2503,7 @@ PLy_spi_execute_plan(PyObject * ob, PyObject * list, long limit)
...
@@ -2493,9 +2503,7 @@ PLy_spi_execute_plan(PyObject * ob, PyObject * list, long limit)
{
{
if
(
!
PySequence_Check
(
list
)
||
PyString_Check
(
list
))
if
(
!
PySequence_Check
(
list
)
||
PyString_Check
(
list
))
{
{
char
*
msg
=
"plpy.execute() takes a sequence as its second argument"
;
PLy_exception_set
(
PLy_exc_spi_error
,
"plpy.execute takes a sequence as its second argument"
);
PyErr_SetString
(
PLy_exc_spi_error
,
msg
);
return
NULL
;
return
NULL
;
}
}
nargs
=
PySequence_Length
(
list
);
nargs
=
PySequence_Length
(
list
);
...
@@ -2511,11 +2519,11 @@ PLy_spi_execute_plan(PyObject * ob, PyObject * list, long limit)
...
@@ -2511,11 +2519,11 @@ PLy_spi_execute_plan(PyObject * ob, PyObject * list, long limit)
PyObject
*
so
=
PyObject_Str
(
list
);
PyObject
*
so
=
PyObject_Str
(
list
);
if
(
!
so
)
if
(
!
so
)
PLy_elog
(
ERROR
,
"function
\"
%s
\"
could not execute plan"
,
PLy_elog
(
ERROR
,
"
PL/Python
function
\"
%s
\"
could not execute plan"
,
PLy_procedure_name
(
PLy_curr_procedure
));
PLy_procedure_name
(
PLy_curr_procedure
));
sv
=
PyString_AsString
(
so
);
sv
=
PyString_AsString
(
so
);
PLy_exception_set
(
PLy_exc_spi_error
,
PLy_exception_set
(
PLy_exc_spi_error
,
"Expected sequence of %d arguments, got %d
.
%s"
,
"Expected sequence of %d arguments, got %d
:
%s"
,
plan
->
nargs
,
nargs
,
sv
);
plan
->
nargs
,
nargs
,
sv
);
Py_DECREF
(
so
);
Py_DECREF
(
so
);
...
@@ -2538,7 +2546,7 @@ PLy_spi_execute_plan(PyObject * ob, PyObject * list, long limit)
...
@@ -2538,7 +2546,7 @@ PLy_spi_execute_plan(PyObject * ob, PyObject * list, long limit)
{
{
so
=
PyObject_Str
(
elem
);
so
=
PyObject_Str
(
elem
);
if
(
!
so
)
if
(
!
so
)
PLy_elog
(
ERROR
,
"function
\"
%s
\"
could not execute plan"
,
PLy_elog
(
ERROR
,
"
PL/Python
function
\"
%s
\"
could not execute plan"
,
PLy_procedure_name
(
PLy_curr_procedure
));
PLy_procedure_name
(
PLy_curr_procedure
));
Py_DECREF
(
elem
);
Py_DECREF
(
elem
);
...
@@ -2601,10 +2609,10 @@ PLy_spi_execute_plan(PyObject * ob, PyObject * list, long limit)
...
@@ -2601,10 +2609,10 @@ PLy_spi_execute_plan(PyObject * ob, PyObject * list, long limit)
}
}
if
(
!
PyErr_Occurred
())
if
(
!
PyErr_Occurred
())
P
yErr_SetString
(
PLy_exc_error
,
P
Ly_exception_set
(
PLy_exc_error
,
"Unknown
error in PLy_spi_execute_plan"
);
"unrecognized
error in PLy_spi_execute_plan"
);
/* XXX this oughta be replaced with errcontext mechanism */
/* XXX this oughta be replaced with errcontext mechanism */
PLy_elog
(
WARNING
,
"in
function %s:
"
,
PLy_elog
(
WARNING
,
"in
PL/Python function
\"
%s
\"
"
,
PLy_procedure_name
(
PLy_curr_procedure
));
PLy_procedure_name
(
PLy_curr_procedure
));
return
NULL
;
return
NULL
;
}
}
...
@@ -2648,10 +2656,10 @@ PLy_spi_execute_query(char *query, long limit)
...
@@ -2648,10 +2656,10 @@ PLy_spi_execute_query(char *query, long limit)
PLy_error_in_progress
=
CopyErrorData
();
PLy_error_in_progress
=
CopyErrorData
();
FlushErrorState
();
FlushErrorState
();
if
(
!
PyErr_Occurred
())
if
(
!
PyErr_Occurred
())
P
yErr_SetString
(
PLy_exc_spi_error
,
P
Ly_exception_set
(
PLy_exc_spi_error
,
"Unknown
error in PLy_spi_execute_query"
);
"unrecognized
error in PLy_spi_execute_query"
);
/* XXX this oughta be replaced with errcontext mechanism */
/* XXX this oughta be replaced with errcontext mechanism */
PLy_elog
(
WARNING
,
"in
function %s:
"
,
PLy_elog
(
WARNING
,
"in
PL/Python function
\"
%s
\"
"
,
PLy_procedure_name
(
PLy_curr_procedure
));
PLy_procedure_name
(
PLy_curr_procedure
));
return
NULL
;
return
NULL
;
}
}
...
@@ -2719,8 +2727,8 @@ PLy_spi_execute_fetch_result(SPITupleTable *tuptable, int rows, int status)
...
@@ -2719,8 +2727,8 @@ PLy_spi_execute_fetch_result(SPITupleTable *tuptable, int rows, int status)
PLy_error_in_progress
=
CopyErrorData
();
PLy_error_in_progress
=
CopyErrorData
();
FlushErrorState
();
FlushErrorState
();
if
(
!
PyErr_Occurred
())
if
(
!
PyErr_Occurred
())
P
yErr_SetString
(
PLy_exc_error
,
P
Ly_exception_set
(
PLy_exc_error
,
"Unknown
error in PLy_spi_execute_fetch_result"
);
"unrecognized
error in PLy_spi_execute_fetch_result"
);
Py_DECREF
(
result
);
Py_DECREF
(
result
);
PLy_typeinfo_dealloc
(
&
args
);
PLy_typeinfo_dealloc
(
&
args
);
return
NULL
;
return
NULL
;
...
@@ -2771,7 +2779,7 @@ PLy_init_interp(void)
...
@@ -2771,7 +2779,7 @@ PLy_init_interp(void)
mainmod
=
PyImport_AddModule
(
"__main__"
);
mainmod
=
PyImport_AddModule
(
"__main__"
);
if
(
mainmod
==
NULL
||
PyErr_Occurred
())
if
(
mainmod
==
NULL
||
PyErr_Occurred
())
PLy_elog
(
ERROR
,
"could not import
\"
__main__
\"
module
.
"
);
PLy_elog
(
ERROR
,
"could not import
\"
__main__
\"
module"
);
Py_INCREF
(
mainmod
);
Py_INCREF
(
mainmod
);
PLy_interp_globals
=
PyModule_GetDict
(
mainmod
);
PLy_interp_globals
=
PyModule_GetDict
(
mainmod
);
PLy_interp_safe_globals
=
PyDict_New
();
PLy_interp_safe_globals
=
PyDict_New
();
...
@@ -2794,9 +2802,9 @@ PLy_init_plpy(void)
...
@@ -2794,9 +2802,9 @@ PLy_init_plpy(void)
* initialize plpy module
* initialize plpy module
*/
*/
if
(
PyType_Ready
(
&
PLy_PlanType
)
<
0
)
if
(
PyType_Ready
(
&
PLy_PlanType
)
<
0
)
elog
(
ERROR
,
"could not init PLy_PlanType"
);
elog
(
ERROR
,
"could not init
ialize
PLy_PlanType"
);
if
(
PyType_Ready
(
&
PLy_ResultType
)
<
0
)
if
(
PyType_Ready
(
&
PLy_ResultType
)
<
0
)
elog
(
ERROR
,
"could not init PLy_ResultType"
);
elog
(
ERROR
,
"could not init
ialize
PLy_ResultType"
);
plpy
=
Py_InitModule
(
"plpy"
,
PLy_methods
);
plpy
=
Py_InitModule
(
"plpy"
,
PLy_methods
);
plpy_dict
=
PyModule_GetDict
(
plpy
);
plpy_dict
=
PyModule_GetDict
(
plpy
);
...
@@ -2818,7 +2826,7 @@ PLy_init_plpy(void)
...
@@ -2818,7 +2826,7 @@ PLy_init_plpy(void)
plpy_mod
=
PyImport_AddModule
(
"plpy"
);
plpy_mod
=
PyImport_AddModule
(
"plpy"
);
PyDict_SetItemString
(
main_dict
,
"plpy"
,
plpy_mod
);
PyDict_SetItemString
(
main_dict
,
"plpy"
,
plpy_mod
);
if
(
PyErr_Occurred
())
if
(
PyErr_Occurred
())
elog
(
ERROR
,
"could not init plpy"
);
elog
(
ERROR
,
"could not init
ialize
plpy"
);
}
}
/* the python interface to the elog function
/* the python interface to the elog function
...
@@ -2880,7 +2888,7 @@ PLy_output(volatile int level, PyObject * self, PyObject * args)
...
@@ -2880,7 +2888,7 @@ PLy_output(volatile int level, PyObject * self, PyObject * args)
if
(
so
==
NULL
||
((
sv
=
PyString_AsString
(
so
))
==
NULL
))
if
(
so
==
NULL
||
((
sv
=
PyString_AsString
(
so
))
==
NULL
))
{
{
level
=
ERROR
;
level
=
ERROR
;
sv
=
"could not parse error message in `plpy.elog'"
;
sv
=
dgettext
(
TEXTDOMAIN
,
"could not parse error message in plpy.elog"
)
;
}
}
oldcontext
=
CurrentMemoryContext
;
oldcontext
=
CurrentMemoryContext
;
...
@@ -2940,7 +2948,7 @@ PLy_exception_set(PyObject * exc, const char *fmt,...)
...
@@ -2940,7 +2948,7 @@ PLy_exception_set(PyObject * exc, const char *fmt,...)
va_list
ap
;
va_list
ap
;
va_start
(
ap
,
fmt
);
va_start
(
ap
,
fmt
);
vsnprintf
(
buf
,
sizeof
(
buf
),
fmt
,
ap
);
vsnprintf
(
buf
,
sizeof
(
buf
),
dgettext
(
TEXTDOMAIN
,
fmt
)
,
ap
);
va_end
(
ap
);
va_end
(
ap
);
PyErr_SetString
(
exc
,
buf
);
PyErr_SetString
(
exc
,
buf
);
...
@@ -2966,7 +2974,7 @@ PLy_elog(int elevel, const char *fmt,...)
...
@@ -2966,7 +2974,7 @@ PLy_elog(int elevel, const char *fmt,...)
bool
success
;
bool
success
;
va_start
(
ap
,
fmt
);
va_start
(
ap
,
fmt
);
success
=
appendStringInfoVA
(
&
emsg
,
fmt
,
ap
);
success
=
appendStringInfoVA
(
&
emsg
,
dgettext
(
TEXTDOMAIN
,
fmt
)
,
ap
);
va_end
(
ap
);
va_end
(
ap
);
if
(
success
)
if
(
success
)
break
;
break
;
...
@@ -2976,7 +2984,7 @@ PLy_elog(int elevel, const char *fmt,...)
...
@@ -2976,7 +2984,7 @@ PLy_elog(int elevel, const char *fmt,...)
PG_TRY
();
PG_TRY
();
{
{
ereport
(
elevel
,
ereport
(
elevel
,
(
errmsg
(
"
plp
ython: %s"
,
emsg
.
data
),
(
errmsg
(
"
PL/P
ython: %s"
,
emsg
.
data
),
(
xmsg
)
?
errdetail
(
"%s"
,
xmsg
)
:
0
));
(
xmsg
)
?
errdetail
(
"%s"
,
xmsg
)
:
0
));
}
}
PG_CATCH
();
PG_CATCH
();
...
@@ -3026,7 +3034,7 @@ PLy_traceback(int *xlevel)
...
@@ -3026,7 +3034,7 @@ PLy_traceback(int *xlevel)
if
(
v
&&
((
vob
=
PyObject_Str
(
v
))
!=
NULL
))
if
(
v
&&
((
vob
=
PyObject_Str
(
v
))
!=
NULL
))
vstr
=
PyString_AsString
(
vob
);
vstr
=
PyString_AsString
(
vob
);
else
else
vstr
=
"
U
nknown"
;
vstr
=
"
u
nknown"
;
/*
/*
* I'm not sure what to do if eob is NULL here -- we can't call PLy_elog
* I'm not sure what to do if eob is NULL here -- we can't call PLy_elog
...
@@ -3034,7 +3042,7 @@ PLy_traceback(int *xlevel)
...
@@ -3034,7 +3042,7 @@ PLy_traceback(int *xlevel)
* recursion. I'm not even sure if eob could be NULL here -- would an
* recursion. I'm not even sure if eob could be NULL here -- would an
* Assert() be more appropriate?
* Assert() be more appropriate?
*/
*/
estr
=
eob
?
PyString_AsString
(
eob
)
:
"
Unknown E
xception"
;
estr
=
eob
?
PyString_AsString
(
eob
)
:
"
unrecognized e
xception"
;
initStringInfo
(
&
xstr
);
initStringInfo
(
&
xstr
);
appendStringInfo
(
&
xstr
,
"%s: %s"
,
estr
,
vstr
);
appendStringInfo
(
&
xstr
,
"%s: %s"
,
estr
,
vstr
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment