Tim Bunce wrote:
> On Thu, Nov 26, 2009 at 07:47:45PM +0000, Martin J. Evans wrote:
>> Martin Evans wrote:
>>> Tim,
>>>
>>> I'm not sure if you are bothered by this but there appears to be a small
>>> inconsistency between SQL_INTEGER/SQL_NUMERIC and SQL_DOUBLE handling in
>>> sql_type_cast:
>>>
>>> sql_type_cast("aa", SQL_INTEGER, 0)
>>>   returns 1 (no cast not strict)
>>> sql_type_casr("aa", SQL_INTEGER, DBIstcf_STRICT)
>>>   returns 0 (no cast, strict)
>>> SQL_NUMERIC works as above (with a fix to the grok stuff)
>>>
>>> but
>>>
>>> sql_type_cast("aa", SQL_DOUBLE, 0)
>>>   returns 2 (cast ok) I expected 1
>>> sql_type_cast("aa", SQL_DOUBLE, DBIstcf_STRICT)
>>>   returns 2 (cast ok) I expected 0
>>>
>>> As you point out in the code if warnings are enabled you get a warning
>>> but you don't get the expected return.
>> Would you have any objections to me changing:
>>
>>     case SQL_DOUBLE:
>>         sv_2nv(sv);
>>         /* SvNOK should be set but won't if sv is not numeric (in which
>>          * case perl would have warn'd already if -w or warnings are in
>> effect)
>>          */
>>         cast_ok = SvNOK(sv);
>>         break;
>>
>> to
>>
>>     case SQL_DOUBLE:
>>       if (looks_like_number(sv)) {
>>         sv_2nv(sv);
>>         /* SvNOK should be set but won't if sv is not numeric (in which
>>          * case perl would have warn'd already if -w or warnings are in
>> effect)
>>          */
>>         cast_ok = SvNOK(sv);
>>       } else {
>>           cast_ok = 0;
>>       }
>>         break;
>>
>> as this fixes the inconsistency I mentioned above i.e., sv's cast to
>> doubles which are not numbers return 0 or 1 (depending on STRICT)
>> instead of always returning 2 (cast ok). I worried a little about this
>> as you end up with 0 in the NV for a non-numeric and a return of 2 which
>> looked like the cast worked.
> 
> What does 
>     perl -V:.*|grep nv_preserves_uv
> say for you?

$ perl -V:.*|grep nv_preserves_uv
d_nv_preserves_uv='define';
nv_preserves_uv_bits='32';

> My reading of Perl_sv_2nv() in sv.c is that ifdef NV_PRESERVES_UV
> then SvNOK is not set (but SvNOKp is) if grok_number() returns 0
> into numtype.  The else NV_PRESERVES_UV branch ends with
>         if (!numtype)
>             SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK);
> So either way, if grok_number() returns 0 then SvNOK() should be false.
> 
> And since looks_like_number is just a wrapper around grok_number I'm not
> sure what's going on.
> 
> Perhaps check it in without the change above (so with a failing test)
> and I might get a change to dig into it.

ok, I'll check it in as you described later this afternoon and if you
get a chance to look at it that will be good but in the mean time I'll
let you know if I get any further with it.

>>> Also, there are a couple of bugs in sql_type_cast which I will fix when
>>> the dbi repository is available again - it is locked by some problem at
>>> svn.perl.org. I mailed s...@perl.org but no response or resolution as yet.
>> I fixed these.
> 
> Thanks.

checked in now.

>>> My test code so far which demonstrates the above attached in just in
>>> case (not tested on a system without JSON::XS or Data::Peek as yet and
>>> not using DBI::neat because it is too clever at recognising numbers -
>>> SvNIOK).
> 
> The "/* already has string version of the value, so use it */" block?

yes indeed.

>> I have now tested this on a system without JSON::XS and Data::Peek and
>> fixed the problems and added more tests.
>>
>> If you are ok with this I'll commit the change to DBI.xs, add the test
>> and document sql_type_cast_svpv in DBI::DBD then move on to making this
>> work in DBD::Oracle again.
> 
> That would be great. Many thanks Martin.

DBI::DBD pod changes checked in now although I may come back to it once
I've re-implemented this in DBD::Oracle.

>> BTW, not sure whether you prefer a mail to you or to continue this type
>> of discussion on the dbi-dev list - let me know and I'll do so in the
>> future.
> 
> dbi-dev is best - CC'd - as it keeps other driver developers in the loop
> and more eyeballs can help spot/fix problems more quickly.
> 
> Tim.
> 
> 

Martin
-- 
Martin J. Evans
Easysoft Limited
http://www.easysoft.com

Reply via email to