Обсуждение: OUT parameters in PL/Java

Поиск
Список
Период
Сортировка

OUT parameters in PL/Java

От
Thomas Hallgren
Дата:
I've read about changes in CVS head needed to accomodate OUT parameters. 
I tried to compile PL/Java and it fails (of course). Is there any brief 
text somewhere that highligts the changes that where made and explains 
how the new stuff works? It's hard and somewhat time consuming to try to 
deduct everything just by looking at the code in pl/pgsql.

Regards,
Thomas Hallgren



Re: OUT parameters in PL/Java

От
Tom Lane
Дата:
Thomas Hallgren <thhal@mailblocks.com> writes:
> I've read about changes in CVS head needed to accomodate OUT parameters. 
> I tried to compile PL/Java and it fails (of course). Is there any brief 
> text somewhere that highligts the changes that where made and explains 
> how the new stuff works? It's hard and somewhat time consuming to try to 
> deduct everything just by looking at the code in pl/pgsql.

Could you give more details about what problem you are having?  Simply
recompiling an existing PL shouldn't fail (of course, it wouldn't know
about OUT parameters either).
        regards, tom lane


Re: OUT parameters in PL/Java

От
Thomas Hallgren
Дата:
Tom Lane wrote:
> Thomas Hallgren <thhal@mailblocks.com> writes:
> 
>>I've read about changes in CVS head needed to accomodate OUT parameters. 
>>I tried to compile PL/Java and it fails (of course). Is there any brief 
>>text somewhere that highligts the changes that where made and explains 
>>how the new stuff works? It's hard and somewhat time consuming to try to 
>>deduct everything just by looking at the code in pl/pgsql.
> 
> 
> Could you give more details about what problem you are having?  Simply
> recompiling an existing PL shouldn't fail (of course, it wouldn't know
> about OUT parameters either).
> 
My compile failure was due to the change of proargtypes from Oid* to an 
oidvector. I initially thought that had something to do with OUT parameters.

Some diffs on plperl helped me a bit. I found the new 
get_call_result_type() function. I've made some assumptions that I would 
like to verify the correctness of:

- I assume that by using the get_call_result_type() PL/Java will not 
need any specific handling of functions returning OUT parameters since 
they are similar to functions returning a complex type.

- The TupleDesc returned by the get_call_result_type() is not always
reachable using an Oid. I.e. I cannot use TypeGetTupleDesc(oid, NIL) 
with the Form_pg_proc.prorettype of my function as the first argument.

- The Form_pg_proc.pronargs denotes the number of IN parameters, i.e. 
its safe to access proargtypes.values[idx] with an idx ranging from 0 to 
pronargs - 1.

Regards,
Thomas Hallgren



Re: OUT parameters in PL/Java

От
Tom Lane
Дата:
Thomas Hallgren <thhal@mailblocks.com> writes:
> My compile failure was due to the change of proargtypes from Oid* to an 
> oidvector. I initially thought that had something to do with OUT parameters.

No, not directly.  The diffs needed for that are pretty simple though.

> - I assume that by using the get_call_result_type() PL/Java will not 
> need any specific handling of functions returning OUT parameters since 
> they are similar to functions returning a complex type.

If you use that, it will look just the same as the existing situation 
where you are declared to return RECORD and someone calls you with
a column name/type list in FROM.  Whether you want any additional
smarts is up to you.

> - The TupleDesc returned by the get_call_result_type() is not always
> reachable using an Oid. I.e. I cannot use TypeGetTupleDesc(oid, NIL) 
> with the Form_pg_proc.prorettype of my function as the first argument.

That was true before for the RECORD case.

> - The Form_pg_proc.pronargs denotes the number of IN parameters, i.e. 
> its safe to access proargtypes.values[idx] with an idx ranging from 0 to 
> pronargs - 1.

Right, pronargs/proargtypes still denote the call signature and thus
only count IN (and INOUT) parameters.

One thing to be a bit wary of is that when OUT arguments are present,
subscripts in proargnames line up with proallargtypes not proargtypes.
I dunno if you are using proargnames at all, but if you are, the code
is likely to misbehave if it doesn't know that.
        regards, tom lane


Re: OUT parameters in PL/Java

От
Thomas Hallgren
Дата:
Tom Lane wrote:
> If you use that, it will look just the same as the existing situation 
> where you are declared to return RECORD and someone calls you with
> a column name/type list in FROM.  Whether you want any additional
> smarts is up to you.
> 
> 
>>- The TupleDesc returned by the get_call_result_type() is not always
>>reachable using an Oid. I.e. I cannot use TypeGetTupleDesc(oid, NIL) 
>>with the Form_pg_proc.prorettype of my function as the first argument.
> 
> 
> That was true before for the RECORD case.
> 
PL/Java will not handle the RECORD case gracefully at present I'm 
afraid. The 8.0 compatible version will need some improvements. How is 
the TupleDesc obtained in case of RECORD in 8.0.x? Is it the same in 7.4?

> 
>>- The Form_pg_proc.pronargs denotes the number of IN parameters, i.e. 
>>its safe to access proargtypes.values[idx] with an idx ranging from 0 to 
>>pronargs - 1.
> 
> 
> Right, pronargs/proargtypes still denote the call signature and thus
> only count IN (and INOUT) parameters.
> 
> One thing to be a bit wary of is that when OUT arguments are present,
> subscripts in proargnames line up with proallargtypes not proargtypes.
> I dunno if you are using proargnames at all, but if you are, the code
> is likely to misbehave if it doesn't know that.
> 
Thanks a lot. Now I know how to go about this. Seems pretty stright 
forward. Nice work!

Regards,
Thomas Hallgren


Re: OUT parameters in PL/Java

От
Tom Lane
Дата:
Thomas Hallgren <thhal@mailblocks.com> writes:
> PL/Java will not handle the RECORD case gracefully at present I'm 
> afraid. The 8.0 compatible version will need some improvements. How is 
> the TupleDesc obtained in case of RECORD in 8.0.x? Is it the same in 7.4?

In 8.0 and before I think you have to look in fcinfo->resultinfo to see
if an expectedDesc is supplied via a ReturnSetInfo.  get_call_result_type()
handles that case along with the OUT-parameters case and the returns-a-
named-composite-type case, so it makes things a little easier and more
consistent.

You could do worse than to back-port get_call_result_type() into your
older branches and just leave out the code for the OUT parameter case.
        regards, tom lane


Re: OUT parameters in PL/Java

От
Thomas Hallgren
Дата:
Tom Lane wrote:

>You could do worse than to back-port get_call_result_type() into your
>older branches and just leave out the code for the OUT parameter case.
>  
>
Great advice! I went ahead and did just that. Now PL/Java handles 
IN/INOUT/OUT parameters correctly with 8.1 and it handles functions 
returning SETOF RECORD in all versions. The only thing that doesn't work 
right now is a function that returns RECORD (not SETOF) since the rsinfo 
in this case is NULL. Can you shed some light on that?

Regards,
Thomas Hallgren



Re: OUT parameters in PL/Java

От
Tom Lane
Дата:
Thomas Hallgren <thhal@mailblocks.com> writes:
> ... The only thing that doesn't work 
> right now is a function that returns RECORD (not SETOF) since the rsinfo 
> in this case is NULL. Can you shed some light on that?

What's the test case exactly?
        regards, tom lane


Re: OUT parameters in PL/Java

От
Thomas Hallgren
Дата:
Tom Lane wrote:

>Thomas Hallgren <thhal@mailblocks.com> writes:
>  
>
>>... The only thing that doesn't work 
>>right now is a function that returns RECORD (not SETOF) since the rsinfo 
>>in this case is NULL. Can you shed some light on that?
>>    
>>
>
>What's the test case exactly?
>
>  
>
thhal=# create function javatest.recordExample(int, int) returns record 
as 'org.postgresql.pljava.example.ComplexReturn.complexReturn' immutable 
language java;
CREATE FUNCTION
thhal=# select * from javatest.recordExample(3, 4) as (foo int, bar int, 
baz timestamptz);
ERROR:  could not determine row description for function returning record

(the error occurs since I make an attempt to fetch by Oid when the 
TupleDesc is NULL. Oid in this case is RECORDOID).

Regards,
Thomas Hallgren



Re: OUT parameters in PL/Java

От
Tom Lane
Дата:
Thomas Hallgren <thhal@mailblocks.com> writes:
> thhal=# create function javatest.recordExample(int, int) returns record 
> as 'org.postgresql.pljava.example.ComplexReturn.complexReturn' immutable 
> language java;
> CREATE FUNCTION
> thhal=# select * from javatest.recordExample(3, 4) as (foo int, bar int, 
> baz timestamptz);
> ERROR:  could not determine row description for function returning record

Hmm.  I think this is not your bug.  Is the call coming from
evaluate_function in clauses.c?  We need to either prevent that from
pre-evaluating a function returning RECORD, or fix it so it can pass
the expected tuple descriptor ... probably the former :-(
        regards, tom lane


Re: OUT parameters in PL/Java

От
Thomas Hallgren
Дата:
Tom Lane wrote:

>Thomas Hallgren <thhal@mailblocks.com> writes:
>  
>
>>thhal=# create function javatest.recordExample(int, int) returns record 
>>as 'org.postgresql.pljava.example.ComplexReturn.complexReturn' immutable 
>>language java;
>>CREATE FUNCTION
>>thhal=# select * from javatest.recordExample(3, 4) as (foo int, bar int, 
>>baz timestamptz);
>>ERROR:  could not determine row description for function returning record
>>    
>>
>
>Hmm.  I think this is not your bug.  Is the call coming from
>evaluate_function in clauses.c?  We need to either prevent that from
>pre-evaluating a function returning RECORD, or fix it so it can pass
>the expected tuple descriptor ... probably the former :-(
>  
>
Here's the stack backtrace when this happens.
#6  0xf5a104c3 in java_call_handler (fcinfo=0xfef8aba0)   at
/home/thhal/work/org.postgresql.pljava/src/C/pljava/Backend.c:907
#7  0x08120358 in ExecMakeFunctionResult (fcache=0xa2623a8,   econtext=0xa262830, isNull=0xfef8ae1b "þ", isDone=0x0) at

execQual.c:1026
#8  0x0812261c in ExecEvalExprSwitchContext (expression=0x40,   econtext=0xa1ff75c, isNull=0xfef8ae1b "þ", isDone=0x0)
at
 
execQual.c:2752
#9  0x0815fecf in evaluate_expr (expr=0xa2623a8, result_type=2249)   at clauses.c:2544
#10 0x08161a84 in simplify_function (funcid=17158, result_type=2249,   args=0xa25566c, allow_inline=1 '\001',
context=0xfef8af30)  at clauses.c:2158
 
#11 0x08161f4f in eval_const_expressions_mutator (node=0xa254cfc,   context=0xfef8af30) at clauses.c:1301
#12 0x081629c0 in eval_const_expressions (node=0xa254cfc) at clauses.c:1207
#13 0x08158add in preprocess_expression (parse=0xa25420c, expr=0xa1ff75c,   kind=2) at planner.c:405
#14 0x0815a0c0 in subquery_planner (parse=0xa25420c, tuple_fraction=0)   at planner.c:275
#15 0x0815a23e in planner (parse=0xa25420c, isCursor=0 '\0', 
cursorOptions=0,   boundParams=0x0) at planner.c:133
#16 0x0818e5fa in pg_plan_query (querytree=0xa25420c, boundParams=0x0)   at postgres.c:648
#17 0x0818e680 in pg_plan_queries (querytrees=0xa1ff75c, boundParams=0x0,   needSnapshot=0 '\0') at postgres.c:716
#18 0x081902ce in PostgresMain (argc=4, argv=0xa1ee71c,   username=0xa1ee6f4 "thhal") at postgres.c:875
#19 0x0816bc0a in ServerLoop () at postmaster.c:2784
#20 0x0816cfd7 in PostmasterMain (argc=3, argv=0xa1ed9e8) at 
postmaster.c:917
#21 0x08138f1f in main (argc=3, argv=0xa1ed9e8) at main.c:268

Regards,
Thomas Hallgren




Re: OUT parameters in PL/Java

От
Tom Lane
Дата:
Thomas Hallgren <thhal@mailblocks.com> writes:
> Tom Lane wrote:
>> Hmm.  I think this is not your bug.  Is the call coming from
>> evaluate_function in clauses.c?  We need to either prevent that from
>> pre-evaluating a function returning RECORD, or fix it so it can pass
>> the expected tuple descriptor ... probably the former :-(

I committed a patch to prevent that problem.

> I've found another problem that might be related. The same example as 
> above but this time I use "returns setof record". Using the CVS head I 
> now get:

> thhal=# select * from javatest.recordExample(3, 4) as (foo int, bar int, 
> baz timestamptz);
> ERROR:  record type has not been registered

> this happens before the java_call_handler is called. Here's the stacktrace:

> #0  lookup_rowtype_tupdesc_noerror (type_id=2249, typmod=-1, noError=0 '\0')
>     at typcache.c:425
> #1  0x081f435b in lookup_rowtype_tupdesc (type_id=2249, typmod=-1)
>     at typcache.c:390
> #2  0x0812081a in ExecMakeTableFunctionResult (funcexpr=0x9c4e288,
>     econtext=0x9c4ded0, expectedDesc=0x9c4e068, returnDesc=0x9c52200)
>     at execQual.c:1298

Looking at the code, it appears that the java call handler *has* been
called once, and what it returned was a tuple that didn't carry any
type identification.  This is probably because you didn't call
BlessTupleDesc.  nodeFunctionscan.c formerly did that, and I suppose
it should keep doing it for backwards compatibility.  I put back the
call...
        regards, tom lane


Re: OUT parameters in PL/Java

От
Thomas Hallgren
Дата:
Tom Lane wrote:
> Looking at the code, it appears that the java call handler *has* been
> called once,
indeed. Obviously I didn't pay too much attention to the trace.

> and what it returned was a tuple that didn't carry any
> type identification.  This is probably because you didn't call
> BlessTupleDesc.  nodeFunctionscan.c formerly did that, and I suppose
> it should keep doing it for backwards compatibility.  I put back the
> call...
> 
I hope that doesn't have a negative performance impact in general. If 
so, I'd be happy to add the missing BlessTupleDesc at my end instead.

Regards,
Thomas Hallgren