Tim Bunce wrote:
> On Tue, Dec 08, 2009 at 12:04:25PM +0000, Martin Evans wrote:
>>>> 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.
>> I've looked in to this a little more now and it appears this fails for
>> Perl < 5.10.1 and works for 5.10.1 so I'm guessing something in svc.c
>> has changed between those releases. Probably the code you looked at was
>> the latest source?
> 
> Quite possibly.
> 
>> Perhaps it was something to do with:
>>
>>   ยท   The public IV and NV flags are now not set if the string value has
>>       trailing "garbage". This behaviour is consistent with not setting
>>       the public IV or NV flags if the value is out of range for the type.
>>
>> That raises the questions of whether and how to fix this in perl <
>> 5.10.1. The looks_like_number call I originally posted (above) does work
>> around the issue. I could of course skip the those tests for Perl < 5.10.1.
> 
> Let's just skip for perl < 5.10.1.
> 
> Tim.
> 
> 

Done and one last (I'm hoping) thing. The PurePerl version that was
added does not match the XS version as the success of the cast (or not)
is not reflected in the return value. The following change fixes it but
I'd rather see some comment on it before committing:


Index: lib/DBI/PurePerl.pm
===================================================================
--- lib/DBI/PurePerl.pm (revision 13653)
+++ lib/DBI/PurePerl.pm (working copy)
@@ -682,21 +682,30 @@

     return -1 unless defined $_[0];

-    my $cast_ok = 0;
+    my $cast_ok = 1;

-    if ($sql_type == SQL_INTEGER) {
-        my $dummy = $_[0] + 0;
-    }
-    elsif ($sql_type == SQL_DOUBLE) {
-        my $dummy = $_[0] + 0.0;
-    }
-    elsif ($sql_type == SQL_NUMERIC) {
-        my $dummy = $_[0] + 0.0;
-    }
-    else {
-        return -2;
-    }
+    my $evalret = eval {
+        use warnings FATAL => qw(numeric);
+        if ($sql_type == SQL_INTEGER) {
+            my $dummy = $_[0] + 0;
+            return 1;
+        }
+        elsif ($sql_type == SQL_DOUBLE) {
+            my $dummy = $_[0] + 0.0;
+            return 1;
+        }
+        elsif ($sql_type == SQL_NUMERIC) {
+            my $dummy = $_[0] + 0.0;
+            return 1;
+        }
+        else {
+            return -2;
+        }
+    } or warn $@;

+    return $evalret if defined($evalret) && ($evalret == -2);
+    $cast_ok = 0 unless $evalret;
+
     # DBIstcf_DISCARD_STRING not supported for PurePerl currently

     return 2 if $cast_ok;

With this in place all the tests pass on 5.10.1 and 5.10.0.

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

Reply via email to