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

Commitbdc7dd6

Browse files
committed
Fix plpython to not get totally confused by OUT arguments. (It still doesn't
support multiple OUT arguments, though.)Hannu Krosing
1 parentd61eecb commitbdc7dd6

File tree

5 files changed

+114
-48
lines changed

5 files changed

+114
-48
lines changed

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,3 +436,14 @@ elif typ == 'obj':
436436
type_record.second = second
437437
return type_record
438438
$$ LANGUAGE plpythonu;
439+
CREATE FUNCTION test_in_out_params(first in text, second out text) AS $$
440+
return first + '_in_to_out';
441+
$$ LANGUAGE plpythonu;
442+
-- this doesn't work yet :-(
443+
CREATE FUNCTION test_in_out_params_multi(first in text,
444+
second out text, third out text) AS $$
445+
return first + '_record_in_to_out';
446+
$$ LANGUAGE plpythonu;
447+
CREATE FUNCTION test_inout_params(first inout text) AS $$
448+
return first + '_inout';
449+
$$ LANGUAGE plpythonu;

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,3 +539,18 @@ SELECT * FROM test_type_record_as('obj', null, null, true);
539539
|
540540
(1 row)
541541

542+
SELECT * FROM test_in_out_params('test_in');
543+
second
544+
-------------------
545+
test_in_in_to_out
546+
(1 row)
547+
548+
-- this doesn't work yet :-(
549+
SELECT * FROM test_in_out_params_multi('test_in');
550+
ERROR: plpython functions cannot return type record
551+
SELECT * FROM test_inout_params('test_in');
552+
first
553+
---------------
554+
test_in_inout
555+
(1 row)
556+

‎src/pl/plpython/plpython.c

Lines changed: 70 additions & 48 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.108 2008/03/28 00:21:56 tgl Exp $
4+
*$PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.109 2008/05/03 02:47:47 tgl Exp $
55
*
66
*********************************************************************
77
*/
@@ -1161,9 +1161,6 @@ PLy_procedure_create(HeapTuple procTup, Oid tgreloid, char *key)
11611161
boolisnull;
11621162
inti,
11631163
rv;
1164-
Datumargnames;
1165-
Datum*elems;
1166-
intnelems;
11671164

11681165
procStruct= (Form_pg_proc)GETSTRUCT(procTup);
11691166

@@ -1249,58 +1246,83 @@ PLy_procedure_create(HeapTuple procTup, Oid tgreloid, char *key)
12491246
}
12501247

12511248
/*
1252-
* now get information required for input conversion of the
1253-
* procedure's arguments.
1249+
* Now get information required for input conversion of the
1250+
* procedure's arguments. Note that we ignore output arguments
1251+
* here --- since we don't support returning record, and that was
1252+
* already checked above, there's no need to worry about multiple
1253+
* output arguments.
12541254
*/
1255-
proc->nargs=procStruct->pronargs;
1256-
if (proc->nargs)
1255+
if (procStruct->pronargs)
12571256
{
1258-
argnames=SysCacheGetAttr(PROCOID,procTup,Anum_pg_proc_proargnames,&isnull);
1259-
if (!isnull)
1257+
Oid*types;
1258+
char**names,
1259+
*modes;
1260+
inti,
1261+
pos,
1262+
total;
1263+
1264+
/* extract argument type info from the pg_proc tuple */
1265+
total=get_func_arg_info(procTup,&types,&names,&modes);
1266+
1267+
/* count number of in+inout args into proc->nargs */
1268+
if (modes==NULL)
1269+
proc->nargs=total;
1270+
else
12601271
{
1261-
/* XXX this code is WRONG if there are any output arguments */
1262-
deconstruct_array(DatumGetArrayTypeP(argnames),TEXTOID,-1, false,'i',
1263-
&elems,NULL,&nelems);
1264-
if (nelems!=proc->nargs)
1265-
elog(ERROR,
1266-
"proargnames must have the same number of elements "
1267-
"as the function has arguments");
1268-
proc->argnames= (char**)PLy_malloc(sizeof(char*)*proc->nargs);
1269-
memset(proc->argnames,0,sizeof(char*)*proc->nargs);
1272+
/* proc->nargs was initialized to 0 above */
1273+
for (i=0;i<total;i++)
1274+
{
1275+
if (modes[i]!='o')
1276+
(proc->nargs)++;
1277+
}
12701278
}
1271-
}
1272-
for (i=0;i<proc->nargs;i++)
1273-
{
1274-
HeapTupleargTypeTup;
1275-
Form_pg_typeargTypeStruct;
12761279

1277-
argTypeTup=SearchSysCache(TYPEOID,
1278-
ObjectIdGetDatum(procStruct->proargtypes.values[i]),
1279-
0,0,0);
1280-
if (!HeapTupleIsValid(argTypeTup))
1281-
elog(ERROR,"cache lookup failed for type %u",
1282-
procStruct->proargtypes.values[i]);
1283-
argTypeStruct= (Form_pg_type)GETSTRUCT(argTypeTup);
1280+
proc->argnames= (char**)PLy_malloc(sizeof(char*)*proc->nargs);
1281+
for (i=pos=0;i<total;i++)
1282+
{
1283+
HeapTupleargTypeTup;
1284+
Form_pg_typeargTypeStruct;
12841285

1285-
/* Disallow pseudotype argument */
1286-
if (argTypeStruct->typtype==TYPTYPE_PSEUDO)
1287-
ereport(ERROR,
1288-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1289-
errmsg("plpython functions cannot take type %s",
1290-
format_type_be(procStruct->proargtypes.values[i]))));
1291-
1292-
if (argTypeStruct->typtype!=TYPTYPE_COMPOSITE)
1293-
PLy_input_datum_func(&(proc->args[i]),
1294-
procStruct->proargtypes.values[i],
1295-
argTypeTup);
1296-
else
1297-
proc->args[i].is_rowtype=2;/* still need to set I/O funcs */
1286+
if (modes&&modes[i]=='o')/* skip OUT arguments */
1287+
continue;
1288+
1289+
Assert(types[i]==procStruct->proargtypes.values[pos]);
1290+
1291+
argTypeTup=SearchSysCache(TYPEOID,
1292+
ObjectIdGetDatum(types[i]),
1293+
0,0,0);
1294+
if (!HeapTupleIsValid(argTypeTup))
1295+
elog(ERROR,"cache lookup failed for type %u",types[i]);
1296+
argTypeStruct= (Form_pg_type)GETSTRUCT(argTypeTup);
1297+
1298+
/* check argument type is OK, set up I/O function info */
1299+
switch (argTypeStruct->typtype)
1300+
{
1301+
caseTYPTYPE_PSEUDO:
1302+
/* Disallow pseudotype argument */
1303+
ereport(ERROR,
1304+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1305+
errmsg("plpython functions cannot take type %s",
1306+
format_type_be(types[i]))));
1307+
break;
1308+
caseTYPTYPE_COMPOSITE:
1309+
/* we'll set IO funcs at first call */
1310+
proc->args[pos].is_rowtype=2;
1311+
break;
1312+
default:
1313+
PLy_input_datum_func(&(proc->args[pos]),
1314+
types[i],
1315+
argTypeTup);
1316+
break;
1317+
}
12981318

1299-
ReleaseSysCache(argTypeTup);
1319+
/* get argument name */
1320+
proc->argnames[pos]=names ?PLy_strdup(names[i]) :NULL;
13001321

1301-
/* Fetch argument name */
1302-
if (proc->argnames)
1303-
proc->argnames[i]=PLy_strdup(TextDatumGetCString(elems[i]));
1322+
ReleaseSysCache(argTypeTup);
1323+
1324+
pos++;
1325+
}
13041326
}
13051327

13061328
/*

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,3 +480,16 @@ elif typ == 'obj':
480480
return type_record
481481
$$ LANGUAGE plpythonu;
482482

483+
CREATEFUNCTIONtest_in_out_params(firstintext, second outtext)AS $$
484+
return first+'_in_to_out';
485+
$$ LANGUAGE plpythonu;
486+
487+
-- this doesn't work yet :-(
488+
CREATEFUNCTIONtest_in_out_params_multi(firstintext,
489+
second outtext, third outtext)AS $$
490+
return first+'_record_in_to_out';
491+
$$ LANGUAGE plpythonu;
492+
493+
CREATEFUNCTIONtest_inout_params(first inouttext)AS $$
494+
return first+'_inout';
495+
$$ LANGUAGE plpythonu;

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,8 @@ SELECT * FROM test_type_record_as('obj', 'one', null, false);
143143
SELECT*FROM test_type_record_as('obj',null,2, false);
144144
SELECT*FROM test_type_record_as('obj','three',3, false);
145145
SELECT*FROM test_type_record_as('obj',null,null, true);
146+
147+
SELECT*FROM test_in_out_params('test_in');
148+
-- this doesn't work yet :-(
149+
SELECT*FROM test_in_out_params_multi('test_in');
150+
SELECT*FROM test_inout_params('test_in');

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp