On Fri, Jul 28, 2006 at 10:42:49AM +0200, Pavel Stehule wrote:
Hello,
I miss better support OUT arguments in plerlu:
create or replace function foo(out p varchar[]) as $$ return { p = [pavel,
jana] }; $$ language plperlu;
postgres=# select foo();
ERROR: array value must start with { or dimension information
postgres=#
I starting work on it. I hope It will be done before current feature freeze.
Regards
Pavel Stehule
It seems Pavel missed sending the preliminary patch, so here it is :)
Cheers,
D
--
David Fetter [EMAIL PROTECTED] http://fetter.org/
phone: +1 415 235 3778AIM: dfetter666
Skype: davidfetter
Remember to vote!
*** ./plperl.c.orig 2006-07-29 21:07:09.0 +0200
--- ./plperl.c 2006-07-30 22:50:56.0 +0200
***
*** 52,57
--- 52,58
FmgrInforesult_in_func; /* I/O function and arg for result type
*/
Oid result_typioparam;
int nargs;
+ int num_out_args; /* number of out arguments */
FmgrInfoarg_out_func[FUNC_MAX_ARGS];
boolarg_is_rowtype[FUNC_MAX_ARGS];
SV *reference;
***
*** 117,122
--- 118,126
static void plperl_init_shared_libs(pTHX);
static HV *plperl_spi_execute_fetch_result(SPITupleTable *, int, int);
+ static SV *plperl_convert_to_pg_array(SV *src);
+
+
/*
* This routine is a crock, and so is everyplace that calls it. The problem
* is that the cached form of plperl functions/queries is allocated
permanently
***
*** 412,418
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg(Perl hash contains nonexistent
column \%s\,
key)));
! if (SvOK(val) SvTYPE(val) != SVt_NULL)
values[attn - 1] = SvPV(val, PL_na);
}
hv_iterinit(perlhash);
--- 416,427
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg(Perl hash contains nonexistent
column \%s\,
key)));
!
! /* if value is ref on array do to pg string array conversion */
! if (SvTYPE(val) == SVt_RV
! SvTYPE(SvRV(val)) == SVt_PVAV)
! values[attn - 1] =
SvPV(plperl_convert_to_pg_array(val), PL_na);
! else if (SvOK(val) SvTYPE(val) != SVt_NULL)
values[attn - 1] = SvPV(val, PL_na);
}
hv_iterinit(perlhash);
***
*** 691,702
HeapTuple tuple;
Form_pg_proc proc;
charfunctyptype;
- int numargs;
- Oid*argtypes;
- char **argnames;
- char *argmodes;
boolistrigger = false;
- int i;
/* Get the new function's pg_proc entry */
tuple = SearchSysCache(PROCOID,
--- 700,706
***
*** 724,740
format_type_be(proc-prorettype;
}
- /* Disallow pseudotypes in arguments (either IN or OUT) */
- numargs = get_func_arg_info(tuple,
- argtypes,
argnames, argmodes);
- for (i = 0; i numargs; i++)
- {
- if (get_typtype(argtypes[i]) == 'p')
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-errmsg(plperl functions cannot take
type %s,
-
format_type_be(argtypes[i];
- }
ReleaseSysCache(tuple);
--- 728,733
***
*** 1014,1019
--- 1007,1065
return retval;
}
+ /*
+ * Verify type of result if proc has out params and transform it
+ * to scalar if proc has only one out parameter
+ */
+
+ static SV *
+ plperl_transform_result(plperl_proc_desc *prodesc, SV *result)
+ {
+ boolexactly_one_field = false;
+ HV *hvr;
+ SV *val;
+ char *key;
+ I32 klen;
+
+
+ if (prodesc-num_out_args 0)
+ {
+ if (!SvOK(result) || SvTYPE(result) != SVt_RV ||
+ SvTYPE(SvRV(result)) != SVt_PVHV)
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_DATATYPE_MISMATCH),
+errmsg(Perl function with OUT
arguments
+must return reference
to hash)));
+ }
+
+ if (prodesc-num_out_args