Author: byterock
Date: Wed Dec 23 14:51:20 2009
New Revision: 13705
Modified:
dbd-oracle/trunk/Changes
dbd-oracle/trunk/Oracle.h
dbd-oracle/trunk/Oracle.pm
dbd-oracle/trunk/Oracle.xs
dbd-oracle/trunk/dbdimp.c
dbd-oracle/trunk/dbdimp.h
dbd-oracle/trunk/oci8.c
dbd-oracle/trunk/ocitrace.h
Log:
Well back to fully working Trunk. Just one more patch and I can do the
Release Candidate in the morning Have to update the pod as well tomorrow
Modified: dbd-oracle/trunk/Changes
==============================================================================
--- dbd-oracle/trunk/Changes (original)
+++ dbd-oracle/trunk/Changes Wed Dec 23 14:51:20 2009
@@ -1,4 +1,6 @@
=head1 Changes in DBD-Oracle 1.24(svn rev???)
+ Added ora_ncs_buff_mtpl and enviornment var ORA_DBD_NCS_BUFFER so we can
control the size of the buffer when doing nclob reads
+ Fix for bug in for changes to row fetch buffer mostly lobs and object
fetches
Fix for rt.cpan.org Ticket #=49741 Oracle.h has commented out params in
OCIXMLTypeCreateFromSrc from Kartik Thakore
Added from rt.cpan.org Ticket #=49436 Patch to add support for a few Oracle
data types to type_info_all from David Hull
Added from rt.cpan.org Ticket #=49435 Patch to add support for a few Oracle
data types to dbd_describe from David Hull
Modified: dbd-oracle/trunk/Oracle.h
==============================================================================
--- dbd-oracle/trunk/Oracle.h (original)
+++ dbd-oracle/trunk/Oracle.h Wed Dec 23 14:51:20 2009
@@ -109,12 +109,15 @@
#define ORA_MLSLABEL 105
#define ORA_CLOB 112
#define ORA_BLOB 113
+#define ORA_BFILE 114
#define ORA_RSET 116
#define ORA_VARCHAR2_TABLE 201
#define ORA_NUMBER_TABLE 202
#define ORA_XMLTYPE 108
+
+
/* other Oracle not in noraml API defines
most of these are largly undocumented XML functions that are in the API but
not defined
Modified: dbd-oracle/trunk/Oracle.pm
==============================================================================
--- dbd-oracle/trunk/Oracle.pm (original)
+++ dbd-oracle/trunk/Oracle.pm Wed Dec 23 14:51:20 2009
@@ -34,7 +34,7 @@
ora_exe_modes => [ qw(OCI_STMT_SCROLLABLE_READONLY)],
);
@EXPORT_OK = qw(OCI_FETCH_NEXT OCI_FETCH_CURRENT OCI_FETCH_FIRST
OCI_FETCH_LAST OCI_FETCH_PRIOR
- OCI_FETCH_ABSOLUTE OCI_FETCH_RELATIVE ORA_OCI
SQLCS_IMPLICIT SQLCS_NCHAR ora_env_var ora_cygwin_set_env);
+ OCI_FETCH_ABSOLUTE OCI_FETCH_RELATIVE ORA_OCI
SQLCS_IMPLICIT SQLCS_NCHAR ora_env_var ora_cygwin_set_env );
#unshift @EXPORT_OK, 'ora_cygwin_set_env' if $^O eq 'cygwin';
Exporter::export_ok_tags(qw(ora_types ora_session_modes ora_fetch_orient
ora_exe_modes));
@@ -68,7 +68,6 @@
});
DBD::Oracle::dr::init_oci($drh) ;
$drh->STORE('ShowErrorStatement', 1);
-
DBD::Oracle::db->install_method("ora_lob_read");
DBD::Oracle::db->install_method("ora_lob_write");
DBD::Oracle::db->install_method("ora_lob_append");
@@ -82,8 +81,8 @@
DBD::Oracle::st->install_method("ora_ping");
DBD::Oracle::st->install_method("ora_stmt_type_name");
DBD::Oracle::st->install_method("ora_stmt_type");
-
$drh;
+
}
@@ -177,6 +176,8 @@
sub connect {
my ($drh, $dbname, $user, $auth, $attr)= @_;
+
+
if ($dbname =~ /;/) {
my ($n,$v);
$dbname =~ s/^\s+//;
@@ -250,8 +251,11 @@
# these two are just for backwards compatibility
$dbh_inner->{USER} = $dbh_inner->{CURRENT_USER} = uc $user_only;
}
-
+ if ($ENV{ORA_DBD_NCS_BUFFER}){
+ $dbh->{'ora_ncs_buff_mtpl'}= $ENV{ORA_DBD_NCS_BUFFER};
+ }
$dbh;
+
}
sub private_attribute_info {
@@ -264,7 +268,7 @@
{ package DBD::Oracle::db; # ====== DATABASE ======
use strict;
use DBI qw(:sql_types);
-
+
sub prepare {
my($dbh, $statement, @attribs)= @_;
@@ -284,6 +288,10 @@
}
#Ah! I see you have the machine that goes PING!!
+#Yes!! We leased it from the company that made it
+#then the cost came out of the operating budget
+#not the capital ...
+
sub ping {
my($dbh) = @_;
my $ok = 0;
Modified: dbd-oracle/trunk/Oracle.xs
==============================================================================
--- dbd-oracle/trunk/Oracle.xs (original)
+++ dbd-oracle/trunk/Oracle.xs Wed Dec 23 14:51:20 2009
@@ -96,6 +96,7 @@
MODULE = DBD::Oracle PACKAGE = DBD::Oracle::st
+
void ora_stmt_type(sth)
SV * sth
PREINIT:
Modified: dbd-oracle/trunk/dbdimp.c
==============================================================================
--- dbd-oracle/trunk/dbdimp.c (original)
+++ dbd-oracle/trunk/dbdimp.c Wed Dec 23 14:51:20 2009
@@ -40,10 +40,11 @@
DBISTATE_DECLARE;
int ora_fetchtest; /* intrnal test only, not thread safe */
-int is_extproc = 0;
-int dbd_verbose = 0; /* DBD only debugging*/
-int oci_warn = 0; /* show oci warnings */
-int ora_objects = 0; /* get oracle embedded objects as instance of
DBD::Oracle::Object */
+int is_extproc = 0;
+int dbd_verbose = 0; /* DBD only debugging*/
+int oci_warn = 0; /* show oci warnings */
+int ora_objects = 0; /* get oracle embedded objects as
instance of DBD::Oracle::Object */
+int ora_ncs_buff_mtpl = 1; /* a mulitplyer for ncs clob buffers */
/* bitflag constants for figuring out how to handle utf8 for array binds */
#define ARRAY_BIND_NATIVE 0x01
@@ -58,6 +59,7 @@
ub2 al32utf8_csid = 873;
ub2 al16utf16_csid = 2000;
+
typedef struct sql_fbh_st sql_fbh_t;
struct sql_fbh_st {
int dbtype;
@@ -194,6 +196,7 @@
}
#endif /* __CYGWIN32__ */
+
void
dbd_init(dbistate_t *dbistate)
{
@@ -951,9 +954,10 @@
int on = SvTRUE(valuesv);
int cacheit = 1;
-
-
- if (kl==20 && strEQ(key, "ora_oci_success_warn") ) {
+ if (kl==17 && strEQ(key, "ora_ncs_buff_mtpl") ) {
+ ora_ncs_buff_mtpl = SvIV (valuesv);
+ }
+ else if (kl==20 && strEQ(key, "ora_oci_success_warn") ) {
oci_warn = SvIV (valuesv);
}
else if (kl==11 && strEQ(key, "ora_objects")) {
@@ -1011,7 +1015,10 @@
/* AutoCommit FETCH via DBI */
- if (kl==20 && strEQ(key, "ora_oci_success_warn")) {
+ if (kl==18 && strEQ(key, "ora_ncs_buff_mtpl") ) {
+ retsv = newSViv (ora_ncs_buff_mtpl);
+ }
+ else if (kl==20 && strEQ(key, "ora_oci_success_warn")) {
retsv = newSViv (oci_warn);
}
else if (kl==11 && strEQ(key, "ora_objects")) {
Modified: dbd-oracle/trunk/dbdimp.h
==============================================================================
--- dbd-oracle/trunk/dbdimp.h (original)
+++ dbd-oracle/trunk/dbdimp.h Wed Dec 23 14:51:20 2009
@@ -256,6 +256,7 @@
extern int dbd_verbose;
extern int oci_warn;
extern int ora_objects;
+extern int ora_ncs_buff_mtpl;
extern ub2 charsetid;
extern ub2 ncharsetid;
@@ -333,6 +334,7 @@
#ifdef __CYGWIN32__
void ora_cygwin_set_env(char *name, char *value);
+
#endif /* __CYGWIN32__ */
sb4 dbd_phs_in _((dvoid *octxp, OCIBind *bindp, ub4 iter, ub4 index,
Modified: dbd-oracle/trunk/oci8.c
==============================================================================
--- dbd-oracle/trunk/oci8.c (original)
+++ dbd-oracle/trunk/oci8.c Wed Dec 23 14:51:20 2009
@@ -943,6 +943,7 @@
DBD_ATTRIB_GET_IV( attribs, "ora_verbose", 11, svp,
dbd_verbose);
DBD_ATTRIB_GET_IV( attribs, "ora_oci_success_warn", 20, svp,
oci_warn);
DBD_ATTRIB_GET_IV( attribs, "ora_objects", 11, svp,
ora_objects);
+ DBD_ATTRIB_GET_IV( attribs, "ora_ncs_buff_mtpl", 17,
svp,ora_ncs_buff_mtpl);
if (!dbd_verbose)
DBD_ATTRIB_GET_IV( attribs, "dbd_verbose", 11, svp,
dbd_verbose);
@@ -1574,7 +1575,7 @@
sv_set_undef(dest_sv); /* signal error */
return 0;
}
- if (ftype != 112) {
+ if (ftype != ORA_CLOB) {
oci_error(sth, imp_sth->errhp, OCI_ERROR,
"blob_read not currently supported for non-CLOB types
with OCI 8 "
"(but with OCI 8 you can set $dbh->{LongReadLen} to the
length you need,"
@@ -1644,7 +1645,7 @@
SvCUR_set(dest_sv, byte_destoffset+amtp);
*SvEND(dest_sv) = '\0'; /* consistent with perl sv_setpvn etc */
SvPOK_on(dest_sv);
- if (ftype == 112 && CSFORM_IMPLIES_UTF8(csform))
+ if (ftype == ORA_CLOB && CSFORM_IMPLIES_UTF8(csform))
SvUTF8_on(dest_sv);
return 1;
@@ -1665,11 +1666,11 @@
sword status;
char *type_name;
- if (ftype == 112)
+ if (ftype == ORA_CLOB)
type_name = "CLOB";
- else if (ftype == 113)
+ else if (ftype == ORA_BLOB)
type_name = "BLOB";
- else if (ftype == 114)
+ else if (ftype == ORA_BFILE)
type_name = "BFILE";
else {
oci_error(sth, imp_sth->errhp, OCI_ERROR,
@@ -1693,7 +1694,7 @@
sv_set_undef(dest_sv); /* signal error */
return 0;
}
- if (ftype == 112 && csform == SQLCS_NCHAR)
+ if (ftype == ORA_CLOB && csform == SQLCS_NCHAR)
type_name = "NCLOB";
/*
@@ -1708,12 +1709,14 @@
Output FW bytes characters (FW=Fixed Width charset,
VW=Variable)
Output VW bytes characters(in), bytes returned (afterwards)
*/
+
amtp = (loblen > len) ? len : loblen;
/* buflen: length of buffer in bytes */
/* so for CLOBs that'll be returned as UTF8 we need more bytes that
chars */
/* XXX the x4 here isn't perfect - really the code should be changed to
loop */
- if (ftype == 112 && CSFORM_IMPLIES_UTF8(csform)) {
+
+ if (ftype == ORA_CLOB && CSFORM_IMPLIES_UTF8(csform)) {
buflen = amtp * 4;
/* XXX destoffset would be counting chars here as well */
SvGROW(dest_sv, (destoffset*4) + buflen + 1);
@@ -1753,7 +1756,7 @@
sv_set_undef(dest_sv); /* signal error */
return 0;
}
- if (ftype == 112 && CSFORM_IMPLIES_UTF8(csform))
+ if (ftype == ORA_CLOB && CSFORM_IMPLIES_UTF8(csform))
SvUTF8_on(dest_sv);
}
else {
@@ -1782,10 +1785,9 @@
fetch_lob(SV *sth, imp_sth_t *imp_sth, OCILobLocator* lobloc, int ftype, SV
*dest_sv, char *name)
{
dTHX;
- ub4 loblen = 0;
- ub4 buflen;
- ub4 amtp = 0;
- int loblen_is_chars;
+ ub4 loblen = 0;
+ ub4 buflen = 0;
+ ub4 amtp = 0;
sword status;
if (!name)
@@ -1794,13 +1796,12 @@
/* this function is not called for NULL lobs */
/* The length is expressed in terms of bytes for BLOBs and BFILEs,
*/
- /* and in terms of characters for CLOBs */
+ /* and in terms of characters for CLOBs and NCLOBS
*/
OCILobGetLength_log_stat(imp_sth->svchp, imp_sth->errhp, lobloc,
&loblen, status);
if (status != OCI_SUCCESS) {
oci_error(sth, imp_sth->errhp, status, "OCILobGetLength
fetch_lob");
- return 0;
+ return 0;
}
- loblen_is_chars = (ftype == 112);
if (loblen > imp_sth->long_readlen) { /* LOB will be truncated */
int oraperl = DBIc_COMPAT(imp_sth);
@@ -1828,7 +1829,7 @@
else
amtp = loblen;
- (void)SvUPGRADE(dest_sv, SVt_PV);
+ (void)SvUPGRADE(dest_sv, SVt_PV);
/* XXXX I've hacked on this and left it probably broken
because I didn't have time to research which args to OCI funcs need
@@ -1841,70 +1842,96 @@
ora_lob_*() methods when handling CLOBs.
*/
- /* set char vs bytes and get right semantics for OCILobRead */
- if (loblen_is_chars) {
- buflen = amtp * 4; /* XXX bit of a hack, efective but
wasteful */
- }
- else buflen = amtp;
+ /* Yep you did bust it good and bad. Seem that when the charset of
+ the client and the DB are comptiable the buflen and amtp are both in
chars
+ no matter how many bytes make up the chars. If it is the case were the
Client's
+ NLS_LANG or NLS_NCHAR is not a subset of the Server's the server will
try to traslate
+ the data to the Client's wishes and that is wen it uses will send the
ampt value will be in bytes*/
- SvGROW(dest_sv, buflen+1);
- if (loblen > 0) {
- ub1 csform = 0;
- OCILobCharSetForm_log_stat(imp_sth->envhp,
imp_sth->errhp, lobloc, &csform, status );
- if (status != OCI_SUCCESS) {
- oci_error(sth, imp_sth->errhp, status,
"OCILobCharSetForm");
- sv_set_undef(dest_sv);
- return 0;
- }
+ buflen = amtp*ora_ncs_buff_mtpl;
- if (ftype == 114) {
- OCILobFileOpen_log_stat(imp_sth->svchp, imp_sth->errhp,
lobloc,
- (ub1)OCI_FILE_READONLY, status);
- if (status != OCI_SUCCESS) {
- oci_error(sth, imp_sth->errhp, status,
"OCILobFileOpen");
+ SvGROW(dest_sv, buflen+1);
+
+ if (loblen > 0) {
+ ub1 csform = 0;
+ OCILobCharSetForm_log_stat(imp_sth->envhp, imp_sth->errhp,
lobloc, &csform, status );
+ if (status != OCI_SUCCESS) {
+ oci_error(sth, imp_sth->errhp, status,
"OCILobCharSetForm");
sv_set_undef(dest_sv);
return 0;
- }
}
- OCILobRead_log_stat(imp_sth->svchp, imp_sth->errhp, lobloc,
- &amtp, (ub4)1, SvPVX(dest_sv), buflen,
- 0, 0, (ub2)0, csform, status);
- if (DBIS->debug >= 3 || dbd_verbose >= 3 )
- PerlIO_printf(DBILOGFP,
- " OCILobRead %s %s: csform %d (%s),
LOBlen %luc, LongReadLen %luc, BufLen %lub, Got %luc\n",
- name, oci_status_name(status),
csform,oci_csform_name(csform), ul_t(loblen),
- ul_t(imp_sth->long_readlen), ul_t(buflen),
ul_t(amtp));
-
- if (ftype == 114) {
- OCILobFileClose_log_stat(imp_sth->svchp, imp_sth->errhp,
- lobloc, status);
- }
+ if (ftype == ORA_BFILE) {
+ OCILobFileOpen_log_stat(imp_sth->svchp, imp_sth->errhp, lobloc,
+ (ub1)OCI_FILE_READONLY, status);
if (status != OCI_SUCCESS) {
- oci_error(sth, imp_sth->errhp, status, "OCILobRead");
+ oci_error(sth, imp_sth->errhp, status,
"OCILobFileOpen");
sv_set_undef(dest_sv);
return 0;
}
+ }
+
+ OCILobRead_log_stat(imp_sth->svchp, imp_sth->errhp, lobloc,
+ &amtp, (ub4)1, SvPVX(dest_sv), buflen,
+ 0, 0, (ub2)0, csform, status);
+
+ if (status != OCI_SUCCESS ) {
+
+ if (status == OCI_NEED_DATA ){
+ char buf[300];
+ sprintf(buf,"fetching %s. LOB and the read bufer is
only %lubytes, and the ora_ncs_buff_mtpl is %d, which is too small. Try
setting ora_ncs_buff_mtpl to %d",
+ name, buflen,
ora_ncs_buff_mtpl,ora_ncs_buff_mtpl+1);
+
+ oci_error_err(sth, NULL, OCI_ERROR, buf,
OCI_NEED_DATA); /* appropriate ORA error number */
+ croak("DBD::Oracle has returned a %s status when doing
a LobRead!! \n",oci_status_name(status));
+
+ /*why a croak here well if it goes on it will result in a
+ ORA-03127: no new operations allowed until the active
operation ends
+ This will result in a crash if there are any other fetchst*/
+ }
+ oci_error(sth, imp_sth->errhp, status, "OCILobRead");
+ sv_set_undef(dest_sv);
+ return 0;
+ }
+
+
+
+ if (DBIS->debug >= 3 || dbd_verbose >= 3 )
+ PerlIO_printf(DBILOGFP,
+ " OCILobRead %s %s: csform %d (%s), LOBlen %luc,
LongReadLen %luc, BufLen %lub, Got %luc\n",
+ name, oci_status_name(status),
csform,oci_csform_name(csform), ul_t(loblen),
+ ul_t(imp_sth->long_readlen), ul_t(buflen),
ul_t(amtp));
+
+ if (ftype == ORA_BFILE) {
+ OCILobFileClose_log_stat(imp_sth->svchp, imp_sth->errhp,
+ lobloc, status);
+ }
+
+ if (status != OCI_SUCCESS) {
+ oci_error(sth, imp_sth->errhp, status, "OCILobFileClose");
+ sv_set_undef(dest_sv);
+ return 0;
+ }
/* tell perl what we've put in its dest_sv */
+ SvCUR(dest_sv) = amtp;
+ *SvEND(dest_sv) = '\0';
+ if (ftype == ORA_CLOB && CSFORM_IMPLIES_UTF8(csform)) /* Don't set UTF8
on BLOBs */
+ SvUTF8_on(dest_sv);
+ ora_free_templob(sth, imp_sth, lobloc);
+ }
+ else { /* LOB length is 0 */
+ assert(amtp == 0);
+ /* tell perl what we've put in its dest_sv */
SvCUR(dest_sv) = amtp;
*SvEND(dest_sv) = '\0';
- if (ftype == 112 && CSFORM_IMPLIES_UTF8(csform)) /* Don't set
UTF8 on BLOBs */
- SvUTF8_on(dest_sv);
- ora_free_templob(sth, imp_sth, lobloc);
- }
- else { /* LOB length is 0 */
- assert(amtp == 0);
- /* tell perl what we've put in its dest_sv */
- SvCUR(dest_sv) = amtp;
- *SvEND(dest_sv) = '\0';
- if (DBIS->debug >= 3 || dbd_verbose >= 3 )
- PerlIO_printf(DBILOGFP,
- " OCILobRead %s %s: LOBlen %lu,
LongReadLen %lu, BufLen %lu, Got %lu\n",
- name, "SKIPPED", ul_t(loblen),
- ul_t(imp_sth->long_readlen), ul_t(buflen), ul_t(amtp));
- }
+ if (DBIS->debug >= 3 || dbd_verbose >= 3 )
+ PerlIO_printf(DBILOGFP,
+ " OCILobRead %s %s: LOBlen %lu,
LongReadLen %lu, BufLen %lu, Got %lu\n",
+ name, "SKIPPED", ul_t(loblen),
+ ul_t(imp_sth->long_readlen), ul_t(buflen),
ul_t(amtp));
+ }
SvPOK_on(dest_sv);
@@ -1976,7 +2003,7 @@
/* Using 10 means any 'runt' packets will have less impact.
*/
/* orginally set up as above but playing around with newer
versions*/
/* I found that 500 was much faster*/
- int txfr_size = 500 * 1460; /* desired transfer/cache size
*/
+ int txfr_size = 10 * 1460; /* desired transfer/cache size
*/
cache_rows = txfr_size / est_width; /* (maybe 1
or 0) */
@@ -1992,6 +2019,7 @@
if (cache_rows > 10000000) /* keep within Oracle's limits */
cache_rows = 10000000; /* seems it was ub2 at one time now ub4
this number is arbitary on my part*/
+
return cache_rows;
}
@@ -2695,7 +2723,7 @@
so RowCacheSize is for a local cache to cut down on round trips
The OCI doc state that both OCI_ATTR_PREFETCH_ROWS
OCI_ATTR_PREFETCH_MEMORY
- sets up a cleint side cache but in earluer version that 1.24 we only
selected
+ sets up a cleint side cache but in earlier version than 1.24 we only
selected
one record at a time from the fetch this means a round trip (at
least to the local cache)
at each fetch.
@@ -2779,13 +2807,13 @@
}
-/* if (imp_sth->row_cache_off){/*set the size of the Rows in Cache value
+ if (imp_sth->row_cache_off){/*set the size of the Rows in Cache value*/
imp_dbh->RowsInCache =1;
}
else {
imp_dbh->RowsInCache=imp_sth->rs_array_size;
}
-*/
+
if (DBIS->debug >= 3 || dbd_verbose >= 3 || oci_warn) /*will also
display if oci_warn is on*/
@@ -3214,20 +3242,21 @@
break;
case ORA_LONG: /* LONG
*/
-
+ imp_sth->row_cache_off = 1;
+ has_longs++;
if (imp_sth->clbk_lob){ /*get by peice with
callback a slow*/
- fbh->clbk_lob = 1;
+ fbh->clbk_lob = 1;
fbh->define_mode =
OCI_DYNAMIC_FETCH; /* piecwise fetch*/
fbh->disize =
imp_sth->long_readlen; /*user set max value for the fetch*/
fbh->piece_size =
imp_sth->piece_size; /*the size for each piece*/
- fbh->fetch_cleanup =
fetch_cleanup_pres_lobs; /* clean up buffer before each fetch*/
+ fbh->fetch_cleanup =
fetch_cleanup_pres_lobs; /* clean up buffer before each fetch*/
if (!imp_sth->piece_size){ /*if not set
use max value*/
imp_sth->piece_size=imp_sth->long_readlen;
}
- fbh->ftype = SQLT_CHR;
+ fbh->ftype = SQLT_CHR;
fbh->fetch_func = fetch_clbk_lob;
}
@@ -3237,7 +3266,7 @@
fbh->define_mode =
OCI_DYNAMIC_FETCH; /* piecwise fetch*/
fbh->disize =
imp_sth->long_readlen; /*user set max value for the fetch*/
fbh->piece_size =
imp_sth->piece_size; /*the size for each piece*/
- fbh->fetch_cleanup =
fetch_cleanup_pres_lobs; /* clean up buffer before each fetch*/
+ fbh->fetch_cleanup =
fetch_cleanup_pres_lobs; /* clean up buffer before each fetch*/
if (!imp_sth->piece_size){ /*if not set
use max value*/
imp_sth->piece_size=imp_sth->long_readlen;
@@ -3256,18 +3285,18 @@
fbh->dbsize = (fbh->disize>65535) ?
65535 : fbh->disize;
fbh->ftype = 94; /* VAR form */
fbh->fetch_func = fetch_func_varfield;
- ++has_longs;
}
break;
case ORA_LONGRAW: /* LONG
RAW */
+ has_longs++;
if (imp_sth->clbk_lob){ /*get by peice with
callback a slow*/
- fbh->clbk_lob = 1;
+ fbh->clbk_lob = 1;
fbh->define_mode =
OCI_DYNAMIC_FETCH; /* piecwise fetch*/
fbh->disize =
imp_sth->long_readlen; /*user set max value for the fetch*/
fbh->piece_size =
imp_sth->piece_size; /*the size for each piece*/
- fbh->fetch_cleanup =
fetch_cleanup_pres_lobs; /* clean up buffer before each fetch*/
+ fbh->fetch_cleanup =
fetch_cleanup_pres_lobs; /* clean up buffer before each fetch*/
if (!imp_sth->piece_size){ /*if not set
use max value*/
imp_sth->piece_size=imp_sth->long_readlen;
@@ -3279,11 +3308,11 @@
}
else if (imp_sth->piece_lob){ /*get by peice
with polling slowest*/
- fbh->piece_lob = 1;
+ fbh->piece_lob = 1;
fbh->define_mode =
OCI_DYNAMIC_FETCH; /* piecwise fetch*/
fbh->disize =
imp_sth->long_readlen; /*user set max value for the fetch*/
fbh->piece_size =
imp_sth->piece_size; /*the size for each piece*/
- fbh->fetch_cleanup =
fetch_cleanup_pres_lobs; /* clean up buffer before each fetch*/
+ fbh->fetch_cleanup =
fetch_cleanup_pres_lobs; /* clean up buffer before each fetch*/
if (!imp_sth->piece_size){ /*if not set
use max value*/
imp_sth->piece_size=imp_sth->long_readlen;
@@ -3296,7 +3325,6 @@
fbh->dbsize = (fbh->disize>65535) ?
65535 : fbh->disize;
fbh->ftype = 95; /* VAR form */
fbh->fetch_func = fetch_func_varfield;
- ++has_longs;
}
break;
@@ -3306,6 +3334,7 @@
fbh->prec = fbh->disize;
break;
case 108: /* some sort
of embedded object */
+ imp_sth->row_cache_off = 1;/* cant fetch more
thatn one at a time */
fbh->ftype = fbh->dbtype; /*varray or alike */
fbh->fetch_func = fetch_func_oci_object; /*
need a new fetch function for it */
fbh->fetch_cleanup = fetch_cleanup_oci_object;
/* clean up any AV from the fetch*/
@@ -3320,24 +3349,30 @@
break;
case ORA_CLOB: /* CLOB & NCLOB
*/
case ORA_BLOB: /* BLOB
*/
- case 114: /* BFILE
*/
- fbh->ftype = fbh->dbtype;
- imp_sth->ret_lobs = 1;
- /* do we need some addition size logic here?
(lab) */
+ case ORA_BFILE: /* BFILE
*/
+ has_longs++;
+ fbh->ftype = fbh->dbtype;
+ imp_sth->ret_lobs = 1;
+ imp_sth->row_cache_off = 1; /* Cannot use
mulit fetch for a lob*/
+
/* Unless they are just getting the locator */
+
+ if (imp_sth->pers_lob){ /*get as one peice
fasted but limited to 64k big you can get.*/
- if (imp_sth->pers_lob){ /*get as one peice
fasted but limited to how big you can get.*/
fbh->pers_lob = 1;
- if (long_readlen){
- fbh->disize =
fbh->disize*10; /*default size*/
+
+ if (long_readlen){
+ fbh->disize
=long_readlen;/*user set max value for the fetch*/
}
else {
- fbh->disize =
long_readlen;/*user set max value for the fetch*/
+ fbh->disize =
fbh->dbsize*10; /*default size*/
}
+
+
if (fbh->dbtype == ORA_CLOB){
- fbh->ftype = SQLT_CHR;
+ fbh->ftype =
SQLT_CHR;/*SQLT_LNG*/
}
else {
- fbh->ftype = SQLT_LVB; /*Binary
form seems this is the only value where we cna get the length correctly*/
+ fbh->ftype = SQLT_LVB; /*Binary
form seems this is the only value where we can get the length correctly*/
}
}
else if (imp_sth->clbk_lob){ /*get by peice
with callback a slow*/
@@ -3355,7 +3390,7 @@
fbh->ftype = SQLT_BIN; /*other
Binary*/
}
fbh->fetch_func = fetch_clbk_lob;
- imp_sth->row_cache_off=1;
+
}
else if (imp_sth->piece_lob){ /*get by peice
with polling slowest*/
fbh->piece_lob = 1;
@@ -3373,20 +3408,24 @@
fbh->ftype = SQLT_BIN; /*other
Binary */
}
fbh->fetch_func = fetch_get_piece;
- imp_sth->row_cache_off=1;
+
}
else { /*auto lob fetch with locator by far the
fastest*/
- fbh->disize = fbh->dbsize *10 ; /* XXX!
*/
- fbh->fetch_func = (imp_sth->auto_lob) ?
fetch_func_autolob : fetch_func_getrefpv;
+ fbh->disize =
sizeof(OCILobLocator*);/* Size of the lob locator ar we do not really get the
lob! */
+ if (imp_sth->auto_lob) {
+ fbh->fetch_func =
fetch_func_autolob;
+ }
+ else {
+ fbh->fetch_func =
fetch_func_getrefpv;
+ }
+
fbh->bless = "OCILobLocatorPtr";
fbh->desc_t = OCI_DTYPE_LOB;
OCIDescriptorAlloc_ok(imp_sth->envhp,
&fbh->desc_h, fbh->desc_t);
- imp_sth->row_cache_off=1;
- }
- if (fbh->csform == SQLCS_NCHAR){
- imp_sth->row_cache_off=1;
+
}
+
break;
#ifdef OCI_DTYPE_REF
@@ -3628,8 +3667,8 @@
}
else { /*Array Fetch the New Noraml Super speedy and
very nice*/
-/* PerlIO_printf(DBILOGFP, " dbd_st_fetch
fields...a\n");*/
- imp_dbh->RowsInCache--;
+
+ imp_dbh->RowsInCache--;
imp_sth->rs_array_idx++;
/*PerlIO_printf(DBILOGFP," \n
imp_sth->rs_array_idx=%d,rs_array_num_rows=%d\n",imp_sth->rs_array_idx,imp_sth->rs_array_num_rows);
*/
@@ -3731,6 +3770,11 @@
else {
int datalen =
fb_ary->arlen[imp_sth->rs_array_idx];
char *p = (char*)row_data;
+ if (rc == 1406 ){
+ datalen= fbh->disize;
+ }
+
+
if (fbh->ftype == SQLT_LVB){
/* very special case for binary lobs
that are directly fetched.
Seems I have to use SQLT_LVB to
get the length all other will fail*/
Modified: dbd-oracle/trunk/ocitrace.h
==============================================================================
--- dbd-oracle/trunk/ocitrace.h (original)
+++ dbd-oracle/trunk/ocitrace.h Wed Dec 23 14:51:20 2009
@@ -231,7 +231,7 @@
stat = OCIEnvNlsCreate(envp, mode, ctxp, f1, f2, f3, sz, usremepp
,chset, nchset ); \
(DBD_OCI_TRACEON) \
? PerlIO_printf(DBD_OCI_TRACEFP,\
- "%sNlsEnvCreate(%p,%s,%d,%d,%p,%p,%p,%d,%p,%d,%d)=%s\n", \
+ "%sEnvNlsEnvCreate(%p,%s,%d,%d,%p,%p,%p,%d,%p,%d,%d)=%s\n", \
OciTp, (void*)envp, oci_mode(mode),mode, ctxp, (void*)f1,
(void*)f2, (void*)f3, sz, (void*)usremepp ,chset, nchset,
oci_status_name(stat)),stat \
: stat