Before this patch, pl/python will not do the right thing if OUT
parameters are present
----------------
Hannu
Index: plpython/plpython.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/pl/plpython/plpython.c,v
retrieving revision 1.106
diff -c -r1.106 plpython.c
*** plpython/plpython.c 2 Jan 2008 03:10:27 -0000 1.106
--- plpython/plpython.c 29 Apr 2008 20:40:53 -0000
***************
*** 1159,1167 ****
bool isnull;
int i,
rv;
- Datum argnames;
- Datum *elems;
- int nelems;
procStruct = (Form_pg_proc) GETSTRUCT(procTup);
--- 1159,1164 ----
***************
*** 1250,1304 ****
* now get information required for input conversion of the
* procedure's arguments.
*/
! proc->nargs = procStruct->pronargs;
! if (proc->nargs)
! {
! argnames = SysCacheGetAttr(PROCOID, procTup, Anum_pg_proc_proargnames, &isnull);
! if (!isnull)
! {
! /* XXX this code is WRONG if there are any output arguments */
! deconstruct_array(DatumGetArrayTypeP(argnames), TEXTOID, -1, false, 'i',
! &elems, NULL, &nelems);
! if (nelems != proc->nargs)
! elog(ERROR,
! "proargnames must have the same number of elements "
! "as the function has arguments");
! proc->argnames = (char **) PLy_malloc(sizeof(char *) * proc->nargs);
! memset(proc->argnames, 0, sizeof(char *) * proc->nargs);
! }
! }
! for (i = 0; i < proc->nargs; i++)
! {
HeapTuple argTypeTup;
Form_pg_type argTypeStruct;
! argTypeTup = SearchSysCache(TYPEOID,
! ObjectIdGetDatum(procStruct->proargtypes.values[i]),
! 0, 0, 0);
! if (!HeapTupleIsValid(argTypeTup))
! elog(ERROR, "cache lookup failed for type %u",
! procStruct->proargtypes.values[i]);
! argTypeStruct = (Form_pg_type) GETSTRUCT(argTypeTup);
! /* Disallow pseudotype argument */
! if (argTypeStruct->typtype == TYPTYPE_PSEUDO)
! ereport(ERROR,
! (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
! errmsg("plpython functions cannot take type %s",
! format_type_be(procStruct->proargtypes.values[i]))));
!
! if (argTypeStruct->typtype != TYPTYPE_COMPOSITE)
! PLy_input_datum_func(&(proc->args[i]),
! procStruct->proargtypes.values[i],
! argTypeTup);
! else
! proc->args[i].is_rowtype = 2; /* still need to set I/O funcs */
! ReleaseSysCache(argTypeTup);
! /* Fetch argument name */
! if (proc->argnames)
! proc->argnames[i] = PLy_strdup(DatumGetCString(DirectFunctionCall1(textout, elems[i])));
}
/*
--- 1247,1309 ----
* now get information required for input conversion of the
* procedure's arguments.
*/
!
! if (procStruct->pronargs) {
HeapTuple argTypeTup;
Form_pg_type argTypeStruct;
! Oid *types;
! char **names,
! *modes;
! int i,
! pos,
! total;
!
! total = get_func_arg_info(procTup, &types, &names, &modes);
! if (modes == NULL)
! proc->nargs = procStruct->pronargs;
! else
! /* count number of 'i?' args into proc->nargs*/
! for (i = 0;i < total;i++) {
! if (modes[i] != 'o') (proc->nargs)++;
! }
! proc->argnames = (char **) PLy_malloc(sizeof(char *) * proc->nargs);
! for (i = pos = 0;i < total;i++) {
! if (modes && modes[i] == 'o') /* skip OUT arguments */
! continue;
!
! Assert(types[i] == procStruct->proargtypes.values[i]);
!
! argTypeTup = SearchSysCache(TYPEOID,ObjectIdGetDatum(types[i]), 0, 0, 0);
! if (!HeapTupleIsValid(argTypeTup))
! elog(ERROR, "cache lookup failed for type %u",
! procStruct->proargtypes.values[i]);
! argTypeStruct = (Form_pg_type) GETSTRUCT(argTypeTup);
!
! switch (argTypeStruct->typtype) {
! case TYPTYPE_PSEUDO:
! ereport(ERROR,
! (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
! errmsg("plpython functions cannot take type %s",
! format_type_be(types[i]))));
! case TYPTYPE_COMPOSITE:
! proc->args[pos].is_rowtype = 2; /* set IO funcs at first call*/
! break;
! default:
! PLy_input_datum_func(&(proc->args[pos]),
! types[i],
! argTypeTup);
! }
! ReleaseSysCache(argTypeTup);
! /* get argument name */
! proc->argnames[pos] = names ? PLy_strdup(names[i]) : NULL;
!
! pos++;
!
! }
}
/*
Index: plpython/expected/plpython_function.out
===================================================================
RCS file: /projects/cvsroot/pgsql/src/pl/plpython/expected/plpython_function.out,v
retrieving revision 1.10
diff -c -r1.10 plpython_function.out
*** plpython/expected/plpython_function.out 16 Oct 2006 21:13:57 -0000 1.10
--- plpython/expected/plpython_function.out 29 Apr 2008 20:40:59 -0000
***************
*** 436,438 ****
--- 436,447 ----
type_record.second = second
return type_record
$$ LANGUAGE plpythonu;
+ CREATE FUNCTION test_in_out_params(first in text, second out text) AS $$
+ return first + '_in_to_out';
+ $$ LANGUAGE plpythonu;
+ CREATE FUNCTION test_in_out_params_record(first in text, second out text) RETURNS text AS $$
+ return first + '_record_in_to_out';
+ $$ LANGUAGE plpythonu;
+ CREATE FUNCTION test_inout_params(first inout text) AS $$
+ return first + '_inout';
+ $$ LANGUAGE plpythonu;
Index: plpython/expected/plpython_test.out
===================================================================
RCS file: /projects/cvsroot/pgsql/src/pl/plpython/expected/plpython_test.out,v
retrieving revision 1.5
diff -c -r1.5 plpython_test.out
*** plpython/expected/plpython_test.out 2 Sep 2006 12:30:01 -0000 1.5
--- plpython/expected/plpython_test.out 29 Apr 2008 20:41:00 -0000
***************
*** 539,541 ****
--- 539,559 ----
|
(1 row)
+ SELECT * FROM test_in_out_params('test_in');
+ second
+ -------------------
+ test_in_in_to_out
+ (1 row)
+
+ SELECT * FROM test_in_out_params_record('test_in');
+ second
+ --------------------------
+ test_in_record_in_to_out
+ (1 row)
+
+ SELECT * FROM test_inout_params('test_in');
+ first
+ ---------------
+ test_in_inout
+ (1 row)
+
Index: plpython/sql/plpython_function.sql
===================================================================
RCS file: /projects/cvsroot/pgsql/src/pl/plpython/sql/plpython_function.sql,v
retrieving revision 1.10
diff -c -r1.10 plpython_function.sql
*** plpython/sql/plpython_function.sql 16 Oct 2006 21:13:57 -0000 1.10
--- plpython/sql/plpython_function.sql 29 Apr 2008 20:41:02 -0000
***************
*** 480,482 ****
--- 480,494 ----
return type_record
$$ LANGUAGE plpythonu;
+ CREATE FUNCTION test_in_out_params(first in text, second out text) AS $$
+ return first + '_in_to_out';
+ $$ LANGUAGE plpythonu;
+
+ CREATE FUNCTION test_in_out_params_record(first in text, second out text) RETURNS text AS $$
+ return first + '_record_in_to_out';
+ $$ LANGUAGE plpythonu;
+
+ CREATE FUNCTION test_inout_params(first inout text) AS $$
+ return first + '_inout';
+ $$ LANGUAGE plpythonu;
+
Index: plpython/sql/plpython_test.sql
===================================================================
RCS file: /projects/cvsroot/pgsql/src/pl/plpython/sql/plpython_test.sql,v
retrieving revision 1.3
diff -c -r1.3 plpython_test.sql
*** plpython/sql/plpython_test.sql 2 Sep 2006 12:30:01 -0000 1.3
--- plpython/sql/plpython_test.sql 29 Apr 2008 20:41:02 -0000
***************
*** 143,145 ****
--- 143,152 ----
SELECT * FROM test_type_record_as('obj', null, 2, false);
SELECT * FROM test_type_record_as('obj', 'three', 3, false);
SELECT * FROM test_type_record_as('obj', null, null, true);
+
+ SELECT * FROM test_in_out_params('test_in');
+ SELECT * FROM test_in_out_params_record('test_in');
+ SELECT * FROM test_inout_params('test_in');
+
+
+
--
Sent via pgsql-patches mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-patches