https://rt.cpan.org/Ticket/Display.html?id=100188

DBD::File has an issue that might cause backward compat:

sub FETCH
{
:
    $attr eq "TYPE"      and
        return [ map { $sth->{f_overall_defs}{$_}{data_type}   || "CHAR" }
                    @colnames ];

at which point, f_overall_defs is something like

{   c_test           => {
        data_length      => undef,
        data_type        => 'INTEGER'
        },
    test             => {
        data_length      => 10,
        data_type        => 'CHAR'
        }
    }

so $sth->{TYPE}[0] will return "INTEGER" instead of 4
TYPE is defined in DBI:
--8<---
       "TYPE"

       Type: array-ref, read-only

       Returns a reference to an array of integer values for each column. The
                                          ^^^^^^^^^^^^^^
       value indicates the data type of the corresponding column.

       The values correspond to the international standards (ANSI X3.135 and
       ISO/IEC 9075) which, in general terms, means ODBC. Driver-specific
       types that don't exactly match standard types should generally return
       the same values as an ODBC driver supplied by the makers of the
       database. That might include private type numbers in ranges the vendor
       has officially registered with the ISO working group:

         ftp://sqlstandards.org/SC32/SQL_Registry/

       Where there's no vendor-supplied ODBC driver to be compatible with, the
       DBI driver can use type numbers in the range that is now officially
       reserved for use by the DBI: -9999 to -9000.

       All possible values for "TYPE" should have at least one entry in the
       output of the "type_info_all" method (see "type_info_all").
-->8---

The solution would be a code change to this:
--8<---
            # fill overall_defs unless we know
            unless (exists $sth->{f_overall_defs} && ref 
$sth->{f_overall_defs}) {
                my $types = $sth->{Database}{Types};
                unless ($types) { # Feth types only once per database
                    if (my $t = $sth->{Database}->type_info_all ()) {
                        foreach my $i (1 .. $#$t) {
                            $types->{uc $t->[$i][0]}   = $t->[$i][1];
                            $types->{$t->[$i][1]} ||= uc $t->[$i][0];
                            }
                        }
                    $types->{""} = 0;
                    $types->{0} = "";
                    $sth->{Database}{Types} = $types;
                    }
                my $all_meta =
                    $sth->{Database}->func ("*", "table_defs", 
"get_sql_engine_meta");
                while (my ($tbl, $meta) = each %$all_meta) {
                    exists $meta->{table_defs} && ref $meta->{table_defs} or 
next;
                    foreach (keys %{$meta->{table_defs}{columns}}) {
                        my $field_info = $meta->{table_defs}{columns}{$_};
                        if (defined $field_info->{data_type} &&
                                    $field_info->{data_type} !~ m/^[0-9]+$/) {
                            $field_info->{type_name} = uc 
$field_info->{data_type};
                            $field_info->{data_type} = 
$types->{$field_info->{type_name}} || 0;
                            }
                        $field_info->{type_name} ||= 
$types->{$field_info->{data_type}} || "CHAR";
                        $sth->{f_overall_defs}{$_} = $field_info;
                        }
                    }
                }

            my @colnames = $sth->sql_get_colnames ();

            $attr eq "TYPE"      and
                return [ map { $sth->{f_overall_defs}{$_}{data_type}   || 12 }
                            @colnames ];

            $attr eq "TYPE_NAME" and
                return [ map { $sth->{f_overall_defs}{$_}{type_name}   || 
"CHAR" }
                            @colnames ];
-->8---

Now we have both a numeric TYPE attribute and a matching TYPE_NAME
attribute, but how much DBD::File uses might this break?

MY opinion is that we should meet the DBI docs: return NUMERIC for the
TYPE attribute. All DBD::File consumers that ever depended on STRING
behavior depended on implementation (error) instead of docs


-- 
H.Merijn Brand  http://tux.nl   Perl Monger  http://amsterdam.pm.org/
using perl5.00307 .. 5.21   porting perl5 on HP-UX, AIX, and openSUSE
http://mirrors.develooper.com/hpux/        http://www.test-smoke.org/
http://qa.perl.org   http://www.goldmark.org/jeff/stupid-disclaimers/

Attachment: pgp7kUh3jR5Ij.pgp
Description: OpenPGP digital signature

Reply via email to