[svn:dbd-oracle] r13705 - dbd-oracle/trunk

[email protected]
Newsgroups perl.dbd.oracle.changes
Message-ID <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.