A final note on this.

 

Seems there was a very very long unknown bug in DBI which was only fix a few 
days ago wiht DB 1.6.31

 

http://blogs.perl.org/mt/mt.fcgi?__mode=view&_type=entry&id=5570&blog_id=2165

 

The end result of this bug was that when callbacks are used on the statement 
handle some attributes will not be there

so you programmer who did this

 

$sth->FETCH( 'ParamValues' ), # WTF? - returns a reference to an array of hashes

 

was most likely complaing that the 

 

$sth->{ParamValues}, 

 

should return a ref but was just returning undef.

 

So he 'Kludged' the code to get the value directly with the FETCH which works 
sort of, but it does bleed memory every so slighly.

 

The latest version of DBI with the 

 

$sth->{ParamValues}, 

 

Should solve all you problems

 

As a bonus I have another topic for me blog

 

Cheers

John



Date: Wed, 29 Jan 2014 14:21:28 +0000
Subject: Re: Issues with DBI Oracle Input Array Binds (ORA_VARCHAR2_TABLE)
From: hhferre...@gmail.com
To: boh...@ntlworld.com
CC: byter...@hotmail.com


You are right Martin.. Shame on me :( 


At the time you suggested that we did not know about the callbacks, sorry for 
that, our fault :(á


Now that we know the root of the problem I'm sure we will be able to implement 
a solution.á
Thanks a lot for your time, tips and patience :)


I would be more than pleased to offer you a ginginha, porto /portuguese wine 
accompanied by a special local cheese or a "portuguese egg tart" case you pass 
by here!


Best Regards,
HÚlder Hugo Ferreira





On Wed, Jan 29, 2014 at 12:04 PM, Martin J. Evans <boh...@ntlworld.com> wrote:


On 29/01/14 11:02, hhferreira wrote:

Hey Guys!

John, your tip about the callbacks revealed to be very accurate!!

I seem to remember saying a long time back in this thread: 


"Have you got some sort of execute callback? I ask because of the following in 
the trace:


á á {{ execute callback CODE(0xb832be8) being invoked


and it is only present before the error."

hmmm.
á


We managed to isolate the issue into this statement:

á debug( "Executing SQL on OptiDb database:",
á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á 
ásql_executer á á á á => sprintf( "%s line %s (%s)", (caller(0))[1,2], 
$sth->{private_keep_alive_seconds} ? 'active: keeping connection open' : 
'maintenance' ),
á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á 
ástatement á á á á á á=> $sth->{Statement},
*params á á á á á á á => $sth->FETCH( 'ParamValues' ), # WTF? - returns a 
reference to an array of hashes* 

á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á 
áconnected_since á á á=> sprintf( "%s (%.3f seconds)",
á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á 
á á á á á á á á á á á á ástrftime( "%H:%M:%S", localtime( 
$dbh->{private_connected_at_timestamp}[0] ) ),
á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á 
á á á á á á á á á á á á átv_interval( $dbh->{private_connected_at_timestamp} ),
á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á 
á á á á á á á á á á á á á),
á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á 
ákeep_alive_timestamp => $dbh->{private_keep_alive_until_timestamp}
á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á 
á á á á á á á á á á á? sprintf( "%s (%s seconds to live)",
á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á 
á á á á á á á á á á á á á á á á ástrftime( "%H:%M:%S", localtime( 
$dbh->{private_keep_alive_until_timestamp} ) ),
á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á 
á á á á á á á á á á á á á á á á á( $dbh->{private_keep_alive_until_timestamp} - 
time() ),
á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á 
á á á á á á á á á á á á á á á á á)
á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á 
á á á á á á á á á á á: '<not set>',
á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á á);

I guess the former developer added that suggestive comment for a reason :)

Now we don't really now how to resolve this issue here because this debug 
function cannot simply be removed as it logs into a file very important data 
required in case we need to track down business issues. I suppose the problem 
here is that the ora_varchar2_table parameters are themselves arrays and when 
they reach a certain size it crashes.

Any tip to replace this $sth->FETCH('ParamValues') statement into a workable 
one? Maybe reduce the number of items in each of the inner arrays to 100 or so 
could be a solution... We will try to investigate in this direction. If you 
have some sort of magic that could share we would be very appreciated :)

P.S. If you ever come to Portugal let us know and we will be very pleased to go 
out with you for a beer or two!

Best Regards,
HÚlder Hugo Ferreira

<snipped a load of old stuff>

All the FETCH does it return a long list of your parameters. I also recollect 
asking you to output them some time ago. However ParamValues returns a hashref 
with keys based on the parameter name/number. The code in DBD::Oracle for 
ParamValues creates a brand new hash and copies each parameter into it:

á á á á else if (kl==11 && strEQ(key, "ParamValues")) {
á á á á á á á á HV *pvhv = newHV();
á á á á á á á á if (imp_sth->all_params_hv) {
á á á á á á á á á á á á SV *sv;
á á á á á á á á á á á á char *key;
á á á á á á á á á á á á I32 keylen;
á á á á á á á á á á á á hv_iterinit(imp_sth->all_params_hv);
á á á á á á á á á á á á while ( (sv = hv_iternextsv(imp_sth->all_params_hv, 
&key, &keylen)) ) {
á á á á á á á á á á á á á á á á phs_t *phs = (phs_t*)(void*)SvPVX(sv); á á /* 
placeholder struct á */
á á á á á á á á á á á á á á á á (void)hv_store(pvhv, key, keylen, 
newSVsv(phs->sv), 0);
á á á á á á á á á á á á }
á á á á á á á á }
á á á á á á á á retsv = newRV_noinc((SV*)pvhv);
á á á á á á á á cacheit = FALSE;

á á á á }

You had thousands of parameters and I'd imagine this will slow your code a lot. 
The return hashref should go out scope in your code and the hash will get 
thrown away. Are you sure you are really using 1000s of parameters in your 
debug?

I know of no way to limit what ParamValues returns other than change the C code 
above.

I still don't see how this is responsible for your problem however.

Martin

                                          

Reply via email to