I see a big difference in what $sth->{TYPE} returns (and the name) and
what column_info () - if implemented - is returning.

From the DBI docs:

   Handle attributes:

       "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").

   column_info:

       DATA_TYPE: The concise data type code.

       TYPE_NAME: A data source dependent data type name.

DATA_TYPE has no specification of what type of code that is. It can be
either the code the type is internally known by with the database, or
it can be the ODBC equivalent.

TYPE_NAME has no guarantee whatsoever to be like what type_info ()
returns with code like:
--8<---
{   my %types;  # Cache for types

    # Convert numeric to readable
    sub _type_name
    {
        my $type = shift;

        unless (exists $types{$dbh}{$type}) {
            my $tpi = $type =~ m/^-?[0-9]+$/ ? $dbh->type_info ($type) : undef;
            $types{$dbh}{$type} = $tpi ? $tpi->{TYPE_NAME} : $type // "?";
            }
        return $types{$dbh}{$type};
        } # type_name
    }
-->8---

The keys in the hashref returned from column_info () often do not honor
the {FetchHashKeyName} dbh attribute, which makes it quite a bit harder
to write database-independent code. I think either document that the
sth returned from column_info () doesn't have to follow this attribute,
or make the authors alter the code so it does.


Extra fun comes from databases that store type names instead of type
codes in their data-dictionary (like Unify and SQLite), and reversing
that process to make column_info () return both TYPE_NAME and DATA_TYPE
makes it a different pair than TYPE and the derived counterpart from
type_info ().


My real question is, should the docs be enhanced to

• make clear that these two return different things
• column_info () is not always available (sth is undef then)

Here's my findings so far ...

PostgreSQL
  Create as               sth attributes              column_info ()
  ----------------------- --------------------------  
-----------------------------------
  bigint                  ?                       -5  bigint                    
       -5
  bigserial               ?                       -5  bigint                    
       -5
  bit                     unknown                  0  bit                       
        0
  bit (9)                 unknown                  0  bit                       
        0
  bit varying             unknown                  0  bit varying               
        0
  bit varying (35)        unknown                  0  bit varying               
        0
  bool                    bool                    16  boolean                   
       16
  boolean                 bool                    16  boolean                   
       16
  box                     unknown                  0  box                       
        0
  bytea                   bytea                   -3  bytea                     
       -3
  character               bpchar                   1  character                 
        1
  character (5)           bpchar                   1  character                 
        1
  character varying       text                    12  character varying         
       12
  character varying (21)  text                    12  character varying         
       12
  cidr                    unknown                  0  cidr                      
        0
  circle                  unknown                  0  circle                    
        0
  date                    date                    91  date                      
       91
  decimal                 numeric                  3  numeric                   
        3
  decimal (15, 2)         numeric                  3  numeric                   
        3
  decimal (8)             numeric                  3  numeric                   
        3
  double precision        float4                   6  double precision          
        6
  float4                  unknown                  0  real                      
        0
  float8                  float4                   6  double precision          
        6
  inet                    unknown                  0  inet                      
        0
  int                     int4                     4  integer                   
        4
  int2                    int2                     5  smallint                  
        5
  int4                    int4                     4  integer                   
        4
  int8                    ?                       -5  bigint                    
       -5
  integer                 int4                     4  integer                   
        4
  interval                unknown                  0  interval                  
        0
  interval (3)            unknown                  0  interval                  
        0
  line                    unknown                  0  line                      
        0
  lseg                    unknown                  0  lseg                      
        0
  macaddr                 unknown                  0  macaddr                   
        0
  money                   unknown                  0  money                     
        0
  numeric                 numeric                  3  numeric                   
        3
  numeric (15, 2)         numeric                  3  numeric                   
        3
  numeric (8)             numeric                  3  numeric                   
        3
  path                    unknown                  0  path                      
        0
  point                   unknown                  0  point                     
        0
  polygon                 unknown                  0  polygon                   
        0
  real                    unknown                  0  real                      
        0
  serial                  int4                     4  integer                   
        4
  serial4                 int4                     4  integer                   
        4
  smallint                int2                     5  smallint                  
        5
  text                    ?                       -1  text                      
       -1
  time                    time                    92  time without time zone    
       92
  time (3)                time                    92  time without time zone    
       92
  timestamp               timestamp               11  timestamp without time 
zone      11
  timestamp (3)           timestamp               11  timestamp without time 
zone      11
  timestamptz             timestamptz             95  timestamp with time zone  
       95
  timestamptz (3)         timestamptz             95  timestamp with time zone  
       95
  timetz                  unknown                  0  time with time zone       
        0
  timetz (3)              unknown                  0  time with time zone       
        0
  tsquery                 unknown                  0  tsquery                   
        0
  tsvector                unknown                  0  tsvector                  
        0
  txid_snapshot           unknown                  0  txid_snapshot             
        0
  uuid                    unknown                  0  uuid                      
        0
  varchar                 text                    12  character varying         
       12
  varchar (21)            text                    12  character varying         
       12
  xml                     unknown                  0  xml                       
        0


DBD::Oracle does not support column_info ()

Oracle
  Create as               sth attributes              column_info ()
  ----------------------- --------------------------  -------------------------
  bfile                   ?                    -9114  -
  blob                    ?                       30  -
  char                    CHAR                     1  -
  char (19)               CHAR                     1  -
  clob                    ?                       40  -
  date                    DATE                    93  -
  float                   DOUBLE PRECISION         8  -
  float (12)              DOUBLE PRECISION         8  -
  integer                 DECIMAL                  3  -
  interval day to second  INTERVAL DAY TO SECOND   110  -
  interval day (3) to second (2)  INTERVAL DAY TO SECOND   110  -
  long                    LONG                    -1  -
  long raw                LONG RAW                -4  -
Field 1 has an Oracle type (106) which is not explicitly supported at 
/pro/lib/perl5/site_perl/5.10.1/x86_64-linux/DBD/Oracle.pm line 284, <DATA> 
line 122.
DBD::Oracle::st execute failed: ORA-00932: inconsistent datatypes: expected 
NUMBER got LABEL (DBD ERROR: error possibly near <*> indicator at char 7 in 
'select <*>* from xbb where 0 = 1') [for Statement "select * from xbb where 0 = 
1"] at /pro/lib/perl5/site_perl/5.10.1/x86_64-linux/PROCURA/DBD.pm line 421, 
<DATA> line 122.
  mlslabel                ?                    -9106  -
  nchar                   CHAR                     1  -
  nchar (13)              CHAR                     1  -
  nclob                   ?                       40  -
  number                  DOUBLE PRECISION         8  -
  number (8)              DECIMAL                  3  -
  number (15, 2)          DECIMAL                  3  -
  number (9, -2)          DECIMAL                  3  -
  nvarchar2 (3)           VARCHAR2                12  -
  raw (58)                ?                       -2  -
  rowid                   ?                    -9104  -
  timestamp               DATE                    93  -
  timestamp (3)           DATE                    93  -
  urowid                  ?                    -9104  -
  varchar (46)            VARCHAR2                12  -
  varchar2 (46)           VARCHAR2                12  -
  xmltype                 ?                    -9108  -


DBD::Unify will have column_info () in the next release. I'm all open
for changes.

Unify
  Create as               sth attributes              column_info ()
  ----------------------- --------------------------  
-----------------------------------
  amount                  FLOAT                    6  AMOUNT                    
     -206
  amount (5, 2)           FLOAT                    6  AMOUNT                    
     -206
  huge amount             REAL                     7  HUGE AMOUNT               
     -207
  huge amount (5, 2)      REAL                     7  HUGE AMOUNT               
     -207
  huge amount (15, 2)     REAL                     7  HUGE AMOUNT               
     -207
  byte                    BYTE                    -2  BYTE                      
       -2
  byte (512)              BYTE                    -2  BYTE                      
       -2
  char                    CHAR                     1  CHARACTER                 
        1
  char (12)               CHAR                     1  CHARACTER                 
        1
  currency                HUGE AMOUNT              0  -
  currency (9)            HUGE AMOUNT              0  -
  currency (7,2)          HUGE AMOUNT              0  -
  date                    DATE                     9  DATE                      
        9
  huge date               HUGE DATE               11  HUGE DATE                 
       11
  decimal                 NUMERIC                  2  NUMERIC                   
        2
  decimal (2)             NUMERIC                  2  NUMERIC                   
        2
  decimal (8)             NUMERIC                  2  NUMERIC                   
        2
  double precision        DOUBLE PRECISION         8  DOUBLE                    
        8
  float                   DOUBLE PRECISION         8  FLOAT                     
        6
  huge integer            HUGE INTEGER            -5  -
  integer                 NUMERIC                  2  NUMERIC                   
        2
  numeric                 NUMERIC                  2  NUMERIC                   
        2
  numeric (2)             SMALLINT                 5  NUMERIC                   
        2
  numeric (6)             NUMERIC                  2  NUMERIC                   
        2
  real                    REAL                     7  REAL                      
        7
  smallint                SMALLINT                 5  NUMERIC                   
        2
  text                    TEXT                    -1  TEXT                      
       -1
  time                    TIME                    10  TIME                      
       10

MySQL
  Create as               sth attributes              column_info ()
  ----------------------- --------------------------  
-----------------------------------
  serial                  bigint                  -5  BIGINT                    
        4
  tinyint                 tinyint                 -6  TINYINT                   
        4
  tinyint unsigned        tinyint                 -6  TINYINT                   
        4
  tinyint (2)             tinyint                 -6  TINYINT                   
        4
  tinyint (2) unsigned    tinyint                 -6  TINYINT                   
        4
  bool                    tinyint                 -6  TINYINT                   
        4
  boolean                 tinyint                 -6  TINYINT                   
        4
  smallint                smallint                 5  SMALLINT                  
        4
  smallint unsigned       smallint                 5  SMALLINT                  
        4
  smallint (2)            smallint                 5  SMALLINT                  
        4
  smallint (2) unsigned   smallint                 5  SMALLINT                  
        4
  mediumint               integer                  4  MEDIUMINT                 
        4
  mediumint unsigned      integer                  4  MEDIUMINT                 
        4
  mediumint (2)           integer                  4  MEDIUMINT                 
        4
  mediumint (2) unsigned  integer                  4  MEDIUMINT                 
        4
  int                     integer                  4  INT                       
        4
  int unsigned            integer                  4  INT                       
        4
  int (2)                 integer                  4  INT                       
        4
  int (2) unsigned        integer                  4  INT                       
        4
  integer                 integer                  4  INT                       
        4
  integer unsigned        integer                  4  INT                       
        4
  integer (2)             integer                  4  INT                       
        4
  integer (2) unsigned    integer                  4  INT                       
        4
  bigint                  bigint                  -5  BIGINT                    
        4
  bigint unsigned         bigint                  -5  BIGINT                    
        4
  bigint (2)              bigint                  -5  BIGINT                    
        4
  bigint (2) unsigned     bigint                  -5  BIGINT                    
        4
  float                   float                    7  FLOAT                     
        6
  float unsigned          float                    7  FLOAT                     
        6
  float (15)              float                    7  FLOAT                     
        6
  float (15) unsigned     float                    7  FLOAT                     
        6
  float (15, 2)           float                    7  FLOAT                     
        6
  float (15, 2) unsigned  float                    7  FLOAT                     
        6
  double                  double                   8  DOUBLE                    
        8
  double unsigned         double                   8  DOUBLE                    
        8
  double (15, 2)          double                   8  DOUBLE                    
        8
  double (15, 2) unsigned  double                   8  DOUBLE                   
         8
  double precision        double                   8  DOUBLE                    
        8
  double precision unsigned  double                   8  DOUBLE                 
           8
  double precision (15, 2)  double                   8  DOUBLE                  
          8
  double precision (15, 2) unsigned  double                   8  DOUBLE         
                   8
  decimal                 decimal                  3  DECIMAL                   
        3
  decimal unsigned        decimal                  3  DECIMAL                   
        3
  decimal (15)            decimal                  3  DECIMAL                   
        3
  decimal (15) unsigned   decimal                  3  DECIMAL                   
        3
  decimal (15, 2)         decimal                  3  DECIMAL                   
        3
  decimal (15, 2) unsigned  decimal                  3  DECIMAL                 
          3
  date                    date                     9  DATE                      
        9
  datetime                timestamp               11  DATETIME                  
       11
  timestamp               timestamp               11  TIMESTAMP                 
       11
  time                    time                    10  TIME                      
       10
  year                    smallint                 5  YEAR                      
        4
  year (2)                smallint                 5  YEAR                      
        4
  year (4)                smallint                 5  YEAR                      
        4
  char                    char                     1  CHAR                      
        1
  char (3)                char                     1  CHAR                      
        1
  nchar                   char                     1  CHAR                      
        1
  nchar (3)               char                     1  CHAR                      
        1
  national char           char                     1  CHAR                      
        1
  national char (3)       char                     1  CHAR                      
        1
  char character set utf8  char                     1  CHAR                     
         1
  varchar (3)             varchar                 12  VARCHAR                   
       12
  nvarchar (3)            varchar                 12  VARCHAR                   
       12
  national varchar (3)    varchar                 12  VARCHAR                   
       12
  varchar (3) character set utf8  varchar                 12  VARCHAR           
               12
  binary (35)             char                     1  BINARY                    
        1
  varbinary (17)          varchar                 12  VARBINARY                 
       12
  tinyblob                blob                    -4  TINYBLOB                  
       12
  tinytext                blob                    -4  TINYTEXT                  
       12
  tinytext character set utf8  blob                    -4  TINYTEXT             
            12
  blob                    blob                    -4  BLOB                      
       12
  blob (123)              blob                    -4  TINYBLOB                  
       12
  text                    blob                    -4  TEXT                      
       12
  text (123)              blob                    -4  TINYTEXT                  
       12
  text character set utf8  blob                    -4  TEXT                     
        12
  text (123) character set utf8  blob                    -4  TEXT               
              12
  mediumblob              blob                    -4  MEDIUMBLOB                
       12
  mediumtext              blob                    -4  MEDIUMTEXT                
       12
  mediumtext character set utf8  blob                    -4  MEDIUMTEXT         
              12
  longblob                blob                    -4  LONGBLOB                  
       12
  longtext                blob                    -4  LONGTEXT                  
       12
  longtext character set utf8  blob                    -4  LONGTEXT             
            12
  enum ('a','b')          char                     1  ENUM                      
       12
  enum ('a','b') character set utf8  char                     1  ENUM           
                  12
  set ('a','b')           char                     1  SET                       
       12
  set ('a','b') character set utf8  char                     1  SET             
                 12


SQLite does not return handle TYPE attribute attributes :(

SQLite
  Create as               sth attributes              column_info ()
  ----------------------- --------------------------  
-----------------------------------
  int                     ?                        0  int                       
        ?
  integer                 ?                        0  integer                   
        ?
  integer (3)             ?                        0  integer                   
        ?
  tinyint                 ?                        0  tinyint                   
        ?
  smallint                ?                        0  smallint                  
        ?
  mediumint               ?                        0  mediumint                 
        ?
  bigint                  ?                        0  bigint                    
        ?
  unsigned big int        ?                        0  unsigned big int          
        ?
  int2                    ?                        0  int2                      
        ?
  int8                    ?                        0  int8                      
        ?
  character (2)           ?                        0  character                 
        ?
  varchar (20)            ?                        0  varchar                   
        ?
  varying character (3)   ?                        0  varying character         
        ?
  nchar (13)              ?                        0  nchar                     
        ?
  native character (7)    ?                        0  native character          
        ?
  nvarchar (11)           ?                        0  nvarchar                  
        ?
  text                    ?                        0  text                      
        ?
  clob                    ?                        0  clob                      
        ?
  blob                    ?                        0  blob                      
        ?
  real                    ?                        0  real                      
        ?
  double                  ?                        0  double                    
        ?
  double precision        ?                        0  double precision          
        ?
  float                   ?                        0  float                     
        ?
  numeric                 ?                        0  numeric                   
        ?
  numeric (3)             ?                        0  numeric                   
        ?
  decimal (10, 5)         ?                        0  decimal (10, 5)           
        ?
  boolean                 ?                        0  boolean                   
        ?
  date                    ?                        0  date                      
        ?
  datetime                ?                        0  datetime                  
        ?


-- 
H.Merijn Brand  http://tux.nl      Perl Monger  http://amsterdam.pm.org/
using & porting perl 5.6.2, 5.8.x, 5.10.x, 5.11.x on HP-UX 10.20, 11.00,
11.11, 11.23, and 11.31, OpenSuSE 10.3, 11.0, and 11.1, AIX 5.2 and 5.3.
http://mirrors.develooper.com/hpux/           http://www.test-smoke.org/
http://qa.perl.org      http://www.goldmark.org/jeff/stupid-disclaimers/

Reply via email to