[svn:dbd-oracle] r15192 - in dbd-oracle/trunk: . lib/DBD t

[email protected] Thu, 1 Mar 2012 07:23:44 -0800 (PST)
Newsgroups perl.dbd.oracle.changes
Message-ID <[email protected]>
Author: mjevans
Date: Thu Mar  1 07:23:43 2012
New Revision: 15192

Modified:
   dbd-oracle/trunk/Changes
   dbd-oracle/trunk/lib/DBD/Oracle.pm
   dbd-oracle/trunk/t/70meta.t

Log:
Some pod changes for StrictlyTyped/DiscardString
Clarify LongReadLen on long types
default LongReadLen to 1Mb when calling column_info if the default has not been changed


Modified: dbd-oracle/trunk/Changes
==============================================================================
--- dbd-oracle/trunk/Changes	(original)
+++ dbd-oracle/trunk/Changes	Thu Mar  1 07:23:43 2012
@@ -1,14 +1,20 @@
 Revision history for DBD::Oracle
 
-NEXT      
+NEXT
 
  [BUG FIXES]
  - TAF supports now conditional to presence of OCI_ATTR_TAF_ENABLED
     [RT73798]
  - detect broken Win32::TieRegistry (patch by Rafael Kitover (Caelum))
     [RT74544]
- - PL/SQL out values were not utf8 encoded [RT74753] 
+ - PL/SQL out values were not utf8 encoded [RT74753]
      (Steve Baldwin + Martin J. Evans)
+ - Applied patch from Rafael Kitover (Caelum) to column_info to handle
+   DEFAULT columns greater in length than the DBI default of 80. The
+   DEFAULT column is a long and it is a PITA to have to set
+   LongReadLen which you can only do on a connection handle in
+   DBD::Oracle. The default maximum size is now 1Mb; above that you
+   will still have to set LongReadLen (Martin J. Evans)
 
  [DOCUMENTATION]
  - Mention the release of Oracle Instant Client 64 bit which does not work
@@ -16,6 +22,8 @@
  - fix DBD::Oracle::GetInfo blurb (patch by Julián Moreno Patiño) [rt74000]
  - fix typos. (patch by Julián Moreno Patiño) [rt73999]
  - add troubleshoot doc and diag for error with bequeather. [rt75263]
+ - clarification of when StrictlyTyped/DiscardString can be used and
+   LongReadLen (Martin J. Evans)
 
  [OTHERS]
  - change the shebang line of examples to the more modern '/usr/bin/env perl'
@@ -32,7 +40,7 @@
 1.37_00   2011-12-30
 
  [ENHANCEMENTS]
-  - added SYSASM session mode. [RT651211] (patch from 
+  - added SYSASM session mode. [RT651211] (patch from
   Anthony DeRobertis, reported by Julián Moreno Patiño)
 
  [BUG FIXES]
@@ -50,7 +58,7 @@
  - Fix documentation for 'ora_fetch_scroll()'
 
 Changes in DBD-Oracle 1.36 (6-12-2011)
-    
+
  - promote 1.35_00 to official release
 
 Changes in DBD-Oracle 1.35_00 (18-11-2011)
@@ -110,7 +118,7 @@
  - don't gag diag() on the tests by default
  - SKIP condition in 10general.t was reversed (reported by Alois) [RT#46761]
  - Check for LD_LIBRARY_PATH_(32|64) as well for solaris [RT#46761]
- - convert a symbolically linked ORACLE_HOME to an absolute path 
+ - convert a symbolically linked ORACLE_HOME to an absolute path
     (patch by H.Merijn Brand, applied by Martin J. Evans) [rt70785]
 
  [DOCUMENTATION]

Modified: dbd-oracle/trunk/lib/DBD/Oracle.pm
==============================================================================
--- dbd-oracle/trunk/lib/DBD/Oracle.pm	(original)
+++ dbd-oracle/trunk/lib/DBD/Oracle.pm	Thu Mar  1 07:23:43 2012
@@ -753,7 +753,38 @@
 	    }
 	}
 	$SQL .= " ORDER BY TABLE_SCHEM, TABLE_NAME, ORDINAL_POSITION\n";
-	my $sth = $dbh->prepare( $SQL ) or return undef;
+        
+
+        # Since DATA_DEFAULT is a LONG, DEFAULT values longer than 80 chars will
+        # throw an ORA-24345 by default; so we check if LongReadLen is set at
+        # the default value, and if so, set it to something less likely to fail
+        # in common usage.
+        #
+        # We do not set LongTruncOk however as that would make COLUMN_DEF
+        # incorrect, in those (extreme!) cases it would be better if the user
+        # sets LongReadLen herself.
+
+        my $long_read_len = $dbh->FETCH('LongReadLen');
+
+        my ($sth, $exc);
+
+        {
+            local $@;
+            eval {
+                $dbh->STORE(LongReadLen => 1024*1024) if $long_read_len == 80;
+                $sth = $dbh->prepare( $SQL );
+            };
+            $exc = $@;
+        }
+        if ($exc) {
+            $dbh->STORE(LongReadLen => 80) if $long_read_len == 80;
+            die $exc;
+        }
+
+        $dbh->STORE(LongReadLen => 80) if $long_read_len == 80;
+
+        return undef if not $sth;
+
 	$sth->execute( @BindVals ) or return undef;
 	$sth;
     }
@@ -2098,7 +2129,12 @@
 
 =head2 B<LongReadLen>
 
-Implemented by DBI, no driver-specific impact.
+The maximum size of long or longraw columns to retrieve. If one of
+these columns is longer than LongReadLen then either a data truncation
+error will be raised (LongTrunkOk is false) or the column will be
+silently truncated (LongTruncOk is true).
+
+DBI currently defaults this to 80.
 
 =head2 B<LongTruncOk>
 
@@ -2458,7 +2494,11 @@
 
 Datatype codes for non-standard types are subject to change.
 
-Attention! The DATA_DEFAULT (COLUMN_DEF) column is of type LONG.
+Attention! The DATA_DEFAULT (COLUMN_DEF) column is of type LONG so you
+may have to set LongReadLen on the connection handle before calling
+column_info if you have a large default column. After DBD::Oracle 1.40
+LongReadLen is set automatically to 1Mb when calling column_info and
+reset aftwerwards.
 
 The result set is ordered by TABLE_SCHEM, TABLE_NAME, ORDINAL_POSITION.
 
@@ -3239,9 +3279,9 @@
 
 NOTE: DBD::Oracle does not use the C<$bind_type> to determine how to
 bind the column; it uses what Oracle says the data type is. You can
-however set a numeric bind type with the bind attributes
-StrictlyTyped/DiscardString as these attributes are applied after the
-column is retrieved.
+however set the StrictlyTyped/DiscardString attributes and these will
+take effect as these attributes are applied after the column is
+retrieved.
 
 See the DBI documentation for a discussion of the optional parameters C<\%attr> and C<$bind_type>
 

Modified: dbd-oracle/trunk/t/70meta.t
==============================================================================
--- dbd-oracle/trunk/t/70meta.t	(original)
+++ dbd-oracle/trunk/t/70meta.t	Thu Mar  1 07:23:43 2012
@@ -12,10 +12,10 @@
 
 my $dsn = oracle_test_dsn();
 my $dbuser = $ENV{ORACLE_USERID} || 'scott/tiger';
-my $dbh = DBI->connect($dsn, $dbuser, '', { PrintError => 0 });
+my $dbh = DBI->connect($dsn, $dbuser, '', { RaiseError => 1, PrintError => 0 });
 
 if ($dbh) {
-    plan tests=>13;
+    plan tests=>21;
 } else {
     plan skip_all => "Unable to connect to Oracle";
 }
@@ -53,6 +53,34 @@
 note "sql_dbms_version=$sql_dbms_version";
 like($sql_dbms_version, qr/^\d+\.\d+\.\d+$/, 'matched');
 
+# test long DEFAULT from column_info
+SKIP: {
+    my $table = "dbd_ora__drop_me" . ($ENV{DBD_ORACLE_SEQ}||'');
+
+    eval { $dbh->do("DROP TABLE $table") };
+
+    my $created = eval { $dbh->do("CREATE TABLE $table (testcol NUMBER(15) DEFAULT to_number(decode(substrb(userenv('CLIENT_INFO'),1,1),' ', null,substrb(userenv('CLIENT_INFO'),1,10))))") };
+
+    skip 'could not create test table', 8 unless $created;
+
+    is $dbh->{LongReadLen}, 80, 'LongReadLen is at default';
+
+    ok((my $sth = $dbh->column_info(undef, '%', uc($table), '%')), 'column_info sth');
+
+    is $dbh->{LongReadLen}, 80, 'LongReadLen still at default';
+
+    ok((my $info = eval { $sth->fetchrow_hashref }), 'sth->fetchrow_hashref lived')
+        or diag $@;
+
+    is $info->{COLUMN_DEF}, "to_number(decode(substrb(userenv('CLIENT_INFO'),1,1),' ', null,substrb(userenv('CLIENT_INFO'),1,10)))", 'long DEFAULT matched';
+
+    ok($sth->finish, 'sth->finish');
+
+    is $dbh->{LongReadLen}, 80, 'LongReadLen still at default';
+
+    ok($dbh->do("DROP TABLE $table"), 'drop table');
+}
+
 $dbh->disconnect;
 
 exit 0;