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

Commit203592d

Browse files
committed
Revert patch, causing plpython regression failues:
> >> >> > 1) named parameters additionally to args[]> >> >> > 2) return composite-types from plpython as dictionary> >> >> > 3) return result-set from plpython as list, iterator or generator
1 parent8f10768 commit203592d

File tree

1 file changed

+10
-231
lines changed

1 file changed

+10
-231
lines changed

‎src/pl/plpython/plpython.c

Lines changed: 10 additions & 231 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**********************************************************************
22
* plpython.c - python as a procedural language for PostgreSQL
33
*
4-
*$PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.78 2006/04/2701:05:05 momjian Exp $
4+
*$PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.79 2006/04/2714:18:07 momjian Exp $
55
*
66
*********************************************************************
77
*/
@@ -19,7 +19,6 @@
1919
#include"catalog/pg_type.h"
2020
#include"commands/trigger.h"
2121
#include"executor/spi.h"
22-
#include"funcapi.h"
2322
#include"fmgr.h"
2423
#include"nodes/makefuncs.h"
2524
#include"parser/parse_type.h"
@@ -109,11 +108,6 @@ typedef struct PLyProcedure
109108
boolfn_readonly;
110109
PLyTypeInforesult;/* also used to store info for trigger tuple
111110
* type */
112-
boolis_setof;/* true, if procedure returns result set */
113-
PyObject*setof;/* contents of result set. */
114-
intsetof_count;/* numbef of items to return in result set */
115-
intsetof_current;/* current item in result set */
116-
char**argnames;/* Argument names */
117111
PLyTypeInfoargs[FUNC_MAX_ARGS];
118112
intnargs;
119113
PyObject*code;/* compiled procedure code */
@@ -190,7 +184,6 @@ static Datum PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure *);
190184
staticHeapTuplePLy_trigger_handler(FunctionCallInfofcinfo,PLyProcedure*);
191185

192186
staticPyObject*PLy_function_build_args(FunctionCallInfofcinfo,PLyProcedure*);
193-
staticvoidPLy_function_delete_args(PLyProcedure*);
194187
staticPyObject*PLy_trigger_build_args(FunctionCallInfofcinfo,PLyProcedure*,
195188
HeapTuple*);
196189
staticHeapTuplePLy_modify_tuple(PLyProcedure*,PyObject*,
@@ -225,7 +218,6 @@ static PyObject *PLyFloat_FromString(const char *);
225218
staticPyObject*PLyInt_FromString(constchar*);
226219
staticPyObject*PLyLong_FromString(constchar*);
227220
staticPyObject*PLyString_FromString(constchar*);
228-
staticHeapTuplePLyDict_ToTuple(PLyTypeInfo*,PyObject*);
229221

230222

231223
/* global data */
@@ -734,17 +726,11 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure * proc)
734726

735727
PG_TRY();
736728
{
737-
if (!proc->is_setof||proc->setof_count==-1)
738-
{
739-
/* python function not called yet, do it */
740-
plargs=PLy_function_build_args(fcinfo,proc);
741-
plrv=PLy_procedure_call(proc,"args",plargs);
742-
if (!proc->is_setof)
743-
/* SETOF function parameters are deleted when called last row is returned */
744-
PLy_function_delete_args(proc);
745-
Assert(plrv!=NULL);
746-
Assert(!PLy_error_in_progress);
747-
}
729+
plargs=PLy_function_build_args(fcinfo,proc);
730+
plrv=PLy_procedure_call(proc,"args",plargs);
731+
732+
Assert(plrv!=NULL);
733+
Assert(!PLy_error_in_progress);
748734

749735
/*
750736
* Disconnect from SPI manager and then create the return values datum
@@ -755,76 +741,6 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure * proc)
755741
if (SPI_finish()!=SPI_OK_FINISH)
756742
elog(ERROR,"SPI_finish failed");
757743

758-
if (proc->is_setof)
759-
{
760-
boolis_done= false;
761-
ReturnSetInfo*rsi= (ReturnSetInfo*)fcinfo->resultinfo;
762-
763-
if (proc->setof_current==-1)
764-
{
765-
/* first time -- do checks and setup */
766-
if (!rsi|| !IsA(rsi,ReturnSetInfo)||
767-
(rsi->allowedModes&SFRM_ValuePerCall)==0)
768-
{
769-
ereport(ERROR,
770-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
771-
errmsg("only value per call is allowed")));
772-
}
773-
rsi->returnMode=SFRM_ValuePerCall;
774-
775-
/* fetch information about returned object */
776-
proc->setof=plrv;
777-
plrv=NULL;
778-
if (PyList_Check(proc->setof))
779-
/* SETOF as list */
780-
proc->setof_count=PyList_GET_SIZE(proc->setof);
781-
elseif (PyIter_Check(proc->setof))
782-
/* SETOF as iterator, unknown number of items */
783-
proc->setof_current=proc->setof_count=0;
784-
else
785-
{
786-
ereport(ERROR,
787-
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
788-
errmsg("SETOF must be returned as list or iterator")));
789-
}
790-
}
791-
792-
Assert(proc->setof!=NULL);
793-
794-
/* Fetch next of SETOF */
795-
if (PyList_Check(proc->setof))
796-
{
797-
is_done=++proc->setof_current==proc->setof_count;
798-
if (!is_done)
799-
plrv=PyList_GET_ITEM(proc->setof,proc->setof_current);
800-
}
801-
elseif (PyIter_Check(proc->setof))
802-
{
803-
plrv=PyIter_Next(proc->setof);
804-
is_done=plrv==NULL;
805-
}
806-
807-
if (!is_done)
808-
{
809-
rsi->isDone=ExprMultipleResult;
810-
}
811-
else
812-
{
813-
rsi->isDone=ExprEndResult;
814-
proc->setof_count=proc->setof_current=-1;
815-
Py_DECREF(proc->setof);
816-
proc->setof=NULL;
817-
818-
Py_XDECREF(plargs);
819-
Py_XDECREF(plrv);
820-
Py_XDECREF(plrv_so);
821-
822-
PLy_function_delete_args(proc);
823-
fcinfo->isnull= true;
824-
return (Datum)NULL;
825-
}
826-
}
827-
828744
/*
829745
* If the function is declared to return void, the Python
830746
* return value must be None. For void-returning functions, we
@@ -851,26 +767,6 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure * proc)
851767
proc->result.out.d.typioparam,
852768
-1);
853769
}
854-
elseif (proc->result.is_rowtype >=1)
855-
{
856-
HeapTupletuple;
857-
858-
/* returning composite type */
859-
if (!PyDict_Check(plrv))
860-
elog(ERROR,"tuple must be returned as dictionary");
861-
862-
tuple=PLyDict_ToTuple(&proc->result,plrv);
863-
if (tuple!=NULL)
864-
{
865-
fcinfo->isnull= false;
866-
rv=HeapTupleGetDatum(tuple);
867-
}
868-
else
869-
{
870-
fcinfo->isnull= true;
871-
rv= (Datum)NULL;
872-
}
873-
}
874770
else
875771
{
876772
fcinfo->isnull= false;
@@ -997,7 +893,6 @@ PLy_function_build_args(FunctionCallInfo fcinfo, PLyProcedure * proc)
997893
* FIXME -- error check this
998894
*/
999895
PyList_SetItem(args,i,arg);
1000-
PyDict_SetItemString(proc->globals,proc->argnames[i],arg);
1001896
arg=NULL;
1002897
}
1003898
}
@@ -1014,16 +909,6 @@ PLy_function_build_args(FunctionCallInfo fcinfo, PLyProcedure * proc)
1014909
}
1015910

1016911

1017-
staticvoid
1018-
PLy_function_delete_args(PLyProcedure*proc)
1019-
{
1020-
inti;
1021-
1022-
for (i=0;i<proc->nargs;i++)
1023-
PyDict_DelItemString(proc->globals,proc->argnames[i]);
1024-
}
1025-
1026-
1027912
/*
1028913
* PLyProcedure functions
1029914
*/
@@ -1094,9 +979,6 @@ PLy_procedure_create(FunctionCallInfo fcinfo, Oid tgreloid,
1094979
boolisnull;
1095980
inti,
1096981
rv;
1097-
Datumargnames;
1098-
Datum*elems;
1099-
intnelems;
1100982

1101983
procStruct= (Form_pg_proc)GETSTRUCT(procTup);
1102984

@@ -1128,10 +1010,6 @@ PLy_procedure_create(FunctionCallInfo fcinfo, Oid tgreloid,
11281010
proc->nargs=0;
11291011
proc->code=proc->statics=NULL;
11301012
proc->globals=proc->me=NULL;
1131-
proc->is_setof=procStruct->proretset;
1132-
proc->setof=NULL;
1133-
proc->setof_count=proc->setof_current=-1;
1134-
proc->argnames=NULL;
11351013

11361014
PG_TRY();
11371015
{
@@ -1168,11 +1046,9 @@ PLy_procedure_create(FunctionCallInfo fcinfo, Oid tgreloid,
11681046
}
11691047

11701048
if (rvTypeStruct->typtype=='c')
1171-
{
1172-
/* Tuple: set up later, during first call to PLy_function_handler */
1173-
proc->result.out.d.typoid=procStruct->prorettype;
1174-
proc->result.is_rowtype=2;
1175-
}
1049+
ereport(ERROR,
1050+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1051+
errmsg("plpython functions cannot return tuples yet")));
11761052
else
11771053
PLy_output_datum_func(&proc->result,rvTypeTup);
11781054

@@ -1195,21 +1071,6 @@ PLy_procedure_create(FunctionCallInfo fcinfo, Oid tgreloid,
11951071
* arguments.
11961072
*/
11971073
proc->nargs=fcinfo->nargs;
1198-
proc->argnames=NULL;
1199-
if (proc->nargs)
1200-
{
1201-
argnames=SysCacheGetAttr(PROCOID,procTup,Anum_pg_proc_proargnames,&isnull);
1202-
if (!isnull)
1203-
{
1204-
deconstruct_array(DatumGetArrayTypeP(argnames),TEXTOID,-1, false,'i',
1205-
&elems,NULL,&nelems);
1206-
if (nelems!=proc->nargs)
1207-
elog(ERROR,
1208-
"proargnames must have the same number of elements "
1209-
"as the function has arguments");
1210-
proc->argnames= (char**)PLy_malloc(sizeof(char*)*proc->nargs);
1211-
}
1212-
}
12131074
for (i=0;i<fcinfo->nargs;i++)
12141075
{
12151076
HeapTupleargTypeTup;
@@ -1238,12 +1099,9 @@ PLy_procedure_create(FunctionCallInfo fcinfo, Oid tgreloid,
12381099
proc->args[i].is_rowtype=2;/* still need to set I/O funcs */
12391100

12401101
ReleaseSysCache(argTypeTup);
1241-
1242-
/* Fetch argument name */
1243-
if (proc->argnames)
1244-
proc->argnames[i]=PLy_strdup(DatumGetCString(DirectFunctionCall1(textout,elems[i])));
12451102
}
12461103

1104+
12471105
/*
12481106
* get the text of the function.
12491107
*/
@@ -1378,19 +1236,13 @@ PLy_procedure_delete(PLyProcedure * proc)
13781236
if (proc->pyname)
13791237
PLy_free(proc->pyname);
13801238
for (i=0;i<proc->nargs;i++)
1381-
{
13821239
if (proc->args[i].is_rowtype==1)
13831240
{
13841241
if (proc->args[i].in.r.atts)
13851242
PLy_free(proc->args[i].in.r.atts);
13861243
if (proc->args[i].out.r.atts)
13871244
PLy_free(proc->args[i].out.r.atts);
13881245
}
1389-
if (proc->argnames&&proc->argnames[i])
1390-
PLy_free(proc->argnames[i]);
1391-
}
1392-
if (proc->argnames)
1393-
PLy_free(proc->argnames);
13941246
}
13951247

13961248
/* conversion functions. remember output from python is
@@ -1649,78 +1501,6 @@ PLyDict_FromTuple(PLyTypeInfo * info, HeapTuple tuple, TupleDesc desc)
16491501
returndict;
16501502
}
16511503

1652-
1653-
staticHeapTuple
1654-
PLyDict_ToTuple(PLyTypeInfo*info,PyObject*dict)
1655-
{
1656-
TupleDescdesc;
1657-
HeapTupletuple;
1658-
Datum*values;
1659-
char*nulls;
1660-
inti;
1661-
1662-
desc=CreateTupleDescCopy(lookup_rowtype_tupdesc(info->out.d.typoid,-1));
1663-
1664-
/* Set up tuple type, if neccessary */
1665-
if (info->is_rowtype==2)
1666-
{
1667-
PLy_output_tuple_funcs(info,desc);
1668-
info->is_rowtype=1;
1669-
}
1670-
Assert(info->is_rowtype==1);
1671-
1672-
/* Build tuple */
1673-
values=palloc(sizeof(Datum)*desc->natts);
1674-
nulls=palloc(sizeof(char)*desc->natts);
1675-
for (i=0;i<desc->natts;++i)
1676-
{
1677-
char*key;
1678-
PyObject*value,
1679-
*so;
1680-
1681-
key=NameStr(desc->attrs[i]->attname);
1682-
value=so=NULL;
1683-
PG_TRY();
1684-
{
1685-
value=PyDict_GetItemString(dict,key);
1686-
if (value!=Py_None&&value!=NULL)
1687-
{
1688-
char*valuestr;
1689-
1690-
so=PyObject_Str(value);
1691-
valuestr=PyString_AsString(so);
1692-
values[i]=InputFunctionCall(&info->out.r.atts[i].typfunc
1693-
,valuestr
1694-
,info->out.r.atts[i].typioparam
1695-
,-1);
1696-
Py_DECREF(so);
1697-
value=so=NULL;
1698-
nulls[i]=' ';
1699-
}
1700-
else
1701-
{
1702-
value=NULL;
1703-
values[i]= (Datum)NULL;
1704-
nulls[i]='n';
1705-
}
1706-
}
1707-
PG_CATCH();
1708-
{
1709-
Py_XDECREF(value);
1710-
Py_XDECREF(so);
1711-
PG_RE_THROW();
1712-
}
1713-
PG_END_TRY();
1714-
}
1715-
1716-
tuple=heap_formtuple(desc,values,nulls);
1717-
FreeTupleDesc(desc);
1718-
pfree(values);
1719-
pfree(nulls);
1720-
1721-
returntuple;
1722-
}
1723-
17241504
/* initialization, some python variables function declared here */
17251505

17261506
/* interface to postgresql elog */
@@ -2864,4 +2644,3 @@ PLy_free(void *ptr)
28642644
{
28652645
free(ptr);
28662646
}
2867-
/* vim: set noexpandtab nosmarttab shiftwidth=8 cinoptions=l1j1: */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp