work around ORA-24345 from $dbh->column_info
authorRafael Kitover <rkitover@cpan.org>
Fri, 30 Dec 2011 19:48:08 +0000 (14:48 -0500)
committerRafael Kitover <rkitover@cpan.org>
Mon, 27 Feb 2012 01:34:51 +0000 (20:34 -0500)
commit1af21646d6a7fa3947796c3204697879efc3c618
tree28746f9f70b156e44ca48f93d1860da78e6ec8f5
parenta82f1dd456e802874a36f012a10c5a7cfc8d2024
work around ORA-24345 from $dbh->column_info

jhannah reported getting ORA-24345: A Truncation or null fetch error
occurred (DBD ERROR: ORA-01406 error on field 13 of 18, ora_type 8,
 LongReadLen too small and/or LongTruncOk not set)

on running the loader on a table with a very long DEFAULT of
"to_number(decode(substrb(userenv('CLIENT_INFO'),1,1),' ',
null,substrb(userenv('CLIENT_INFO'),1,10)))"

The fix is simply setting $dbh->{LongReadLen} in the _dbh_column_info
override for ::DBI::Oracle, but also make it work without the setting by
making the code involved much more robust.

Change Loader/DBI to fall back to the non-column_info code (that does a
 SELECT ... WHERE 1=0 and examines the $sth) when $dbh->column_info
fails in _columns_info_for, and wrap the fetchrow_hashref in a try {}
catch { +{} }; then skip columns where fetchrow_hashref fails and fill
them in from the WHERE 1=0 type_info code.

Also use this method instead of $dbh->column_info in Loader/DBI/Oracle
_table_columns by removing the overloaded method and using the
Loader/DBI implementation.

While there, clean up the _table_columns implementation in Loader/DBI to
use $self->_lc insetad of $sth->{NAME_lc} for consistency and
overridability.

Make the ::DBI::Oracle _columns_info_for pass all tests with both the
$dbh->column_info output and the type_info output from the parent ::DBI.
Changes
lib/DBIx/Class/Schema/Loader/DBI.pm
lib/DBIx/Class/Schema/Loader/DBI/Oracle.pm
t/10_05ora_common.t