Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit87daae1

Browse files
author
Neil Conway
committed
Allow PL/Python functions to return void, per gripe from James Robinson
(I didn't use his patch, however). A void-returning PL/Python functionmust return None (from Python), which is translated into a void datum(and *not* NULL) for Postgres. I also added some regression tests forthis functionality.
1 parentc6b6f7a commit87daae1

File tree

5 files changed

+72
-7
lines changed

5 files changed

+72
-7
lines changed

‎src/pl/plpython/expected/plpython_function.out

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,3 +289,14 @@ plan = plpy.prepare("SELECT $1 AS testvalue1, $2 AS testvalue2", ["text", "text"
289289
rv = plpy.execute(plan, u"\\x80", 1)
290290
return rv[0]["testvalue1"]
291291
' LANGUAGE plpythonu;
292+
-- Tests for functions that return void
293+
CREATE FUNCTION test_void_func1() RETURNS void AS $$
294+
x = 10
295+
$$ LANGUAGE plpythonu;
296+
-- illegal: can't return non-None value in void-returning func
297+
CREATE FUNCTION test_void_func2() RETURNS void AS $$
298+
return 10
299+
$$ LANGUAGE plpythonu;
300+
CREATE FUNCTION test_return_none() RETURNS int AS $$
301+
None
302+
$$ LANGUAGE plpythonu;

‎src/pl/plpython/expected/plpython_test.out

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,3 +182,19 @@ SELECT newline_crlf();
182182
123
183183
(1 row)
184184

185+
-- Tests for functions returning void
186+
SELECT test_void_func1(), test_void_func1() IS NULL AS "is null";
187+
test_void_func1 | is null
188+
-----------------+---------
189+
| f
190+
(1 row)
191+
192+
SELECT test_void_func2(); -- should fail
193+
ERROR: unexpected return value from plpython procedure
194+
DETAIL: void-returning functions must return "None"
195+
SELECT test_return_none(), test_return_none() IS NULL AS "is null";
196+
test_return_none | is null
197+
------------------+---------
198+
| t
199+
(1 row)
200+

‎src/pl/plpython/plpython.c

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
3030
*
3131
* IDENTIFICATION
32-
*$PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.71 2006/02/20 20:10:37 neilc Exp $
32+
*$PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.72 2006/02/28 20:03:52 neilc Exp $
3333
*
3434
*********************************************************************
3535
*/
@@ -91,7 +91,8 @@ typedef union PLyTypeInput
9191
*/
9292
typedefstructPLyObToDatum
9393
{
94-
FmgrInfotypfunc;
94+
FmgrInfotypfunc;/* The type's input function */
95+
Oidtypoid;/* The OID of the type */
9596
Oidtypioparam;
9697
booltypbyval;
9798
}PLyObToDatum;
@@ -138,7 +139,7 @@ typedef struct PLyProcedure
138139
intnargs;
139140
PyObject*code;/* compiled procedure code */
140141
PyObject*statics;/* data saved across calls, local scope */
141-
PyObject*globals;/* data saved across calls, globalscore */
142+
PyObject*globals;/* data saved across calls, globalscope */
142143
PyObject*me;/* PyCObject containing pointer to this
143144
* PLyProcedure */
144145
}PLyProcedure;
@@ -757,9 +758,24 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure * proc)
757758
elog(ERROR,"SPI_finish failed");
758759

759760
/*
760-
* convert the python PyObject to a postgresql Datum
761+
* If the function is declared to return void, the Python
762+
* return value must be None. For void-returning functions, we
763+
* also treat a None return value as a special "void datum"
764+
* rather than NULL (as is the case for non-void-returning
765+
* functions).
761766
*/
762-
if (plrv==Py_None)
767+
if (proc->result.out.d.typoid==VOIDOID)
768+
{
769+
if (plrv!=Py_None)
770+
ereport(ERROR,
771+
(errcode(ERRCODE_DATATYPE_MISMATCH),
772+
errmsg("unexpected return value from plpython procedure"),
773+
errdetail("void-returning functions must return \"None\"")));
774+
775+
fcinfo->isnull= false;
776+
rv= (Datum)0;
777+
}
778+
elseif (plrv==Py_None)
763779
{
764780
fcinfo->isnull= true;
765781
rv=PointerGetDatum(NULL);
@@ -1031,8 +1047,9 @@ PLy_procedure_create(FunctionCallInfo fcinfo, Oid tgreloid,
10311047
procStruct->prorettype);
10321048
rvTypeStruct= (Form_pg_type)GETSTRUCT(rvTypeTup);
10331049

1034-
/* Disallow pseudotype result */
1035-
if (rvTypeStruct->typtype=='p')
1050+
/* Disallow pseudotype result, except for void */
1051+
if (rvTypeStruct->typtype=='p'&&
1052+
procStruct->prorettype!=VOIDOID)
10361053
{
10371054
if (procStruct->prorettype==TRIGGEROID)
10381055
ereport(ERROR,
@@ -1329,6 +1346,7 @@ PLy_output_datum_func2(PLyObToDatum * arg, HeapTuple typeTup)
13291346
Form_pg_typetypeStruct= (Form_pg_type)GETSTRUCT(typeTup);
13301347

13311348
perm_fmgr_info(typeStruct->typinput,&arg->typfunc);
1349+
arg->typoid=HeapTupleGetOid(typeTup);
13321350
arg->typioparam=getTypeIOParam(typeTup);
13331351
arg->typbyval=typeStruct->typbyval;
13341352
}

‎src/pl/plpython/sql/plpython_function.sql

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,3 +341,18 @@ plan = plpy.prepare("SELECT $1 AS testvalue1, $2 AS testvalue2", ["text", "text"
341341
rv = plpy.execute(plan, u"\\x80", 1)
342342
return rv[0]["testvalue1"]
343343
' LANGUAGE plpythonu;
344+
345+
-- Tests for functions that return void
346+
347+
CREATEFUNCTIONtest_void_func1() RETURNS voidAS $$
348+
x=10
349+
$$ LANGUAGE plpythonu;
350+
351+
-- illegal: can't return non-None value in void-returning func
352+
CREATEFUNCTIONtest_void_func2() RETURNS voidAS $$
353+
return10
354+
$$ LANGUAGE plpythonu;
355+
356+
CREATEFUNCTIONtest_return_none() RETURNSintAS $$
357+
None
358+
$$ LANGUAGE plpythonu;

‎src/pl/plpython/sql/plpython_test.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,8 @@ SELECT join_sequences(sequences) FROM sequences
6868
SELECT newline_lf();
6969
SELECT newline_cr();
7070
SELECT newline_crlf();
71+
72+
-- Tests for functions returning void
73+
SELECT test_void_func1(), test_void_func1() ISNULLAS"is null";
74+
SELECT test_void_func2();-- should fail
75+
SELECT test_return_none(), test_return_none() ISNULLAS"is null";

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp