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 (pgsql-patches@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-patches