[svn:dbd-oracle] r13711 - in dbd-oracle/branches: DBDOracle8 drcp rs_array/t

[email protected]
Newsgroups perl.dbd.oracle.changes
Message-ID <[email protected]>
Author: byterock
Date: Thu Jan  7 16:42:24 2010
New Revision: 13711

Removed:
   dbd-oracle/branches/DBDOracle8/
Modified:
   dbd-oracle/branches/drcp/dbdimp.c
   dbd-oracle/branches/drcp/oci8.c
   dbd-oracle/branches/rs_array/t/30long.t

Log:


Modified: dbd-oracle/branches/drcp/dbdimp.c
==============================================================================
--- dbd-oracle/branches/drcp/dbdimp.c	(original)
+++ dbd-oracle/branches/drcp/dbdimp.c	Thu Jan  7 16:42:24 2010
@@ -271,6 +271,7 @@
 	case 102:	/* SQLT_CUR	OCI 7 cursor variable	*/
 	case 112:	/* SQLT_CLOB / long	*/
 	case 113:	/* SQLT_BLOB / long	*/
+	case 114:    /* BFILE */
 	case 116:	/* SQLT_RSET	OCI 8 cursor variable	*/
  	case ORA_VARCHAR2_TABLE: /* 201 */
 	case ORA_NUMBER_TABLE:	/* 202 */
@@ -379,6 +380,8 @@
 		DBD_ATTRIB_GET_IV(  attr, "dbd_verbose",  11, svp, dbd_verbose);
 	if (DBD_ATTRIB_TRUE(attr,"ora_verbose",11,svp))
 		DBD_ATTRIB_GET_IV(  attr, "ora_verbose",  11, svp, dbd_verbose);
+
+
 	if (DBD_ATTRIB_TRUE(attr,"ora_oci_success_warn",20,svp))
 		DBD_ATTRIB_GET_IV(  attr, "ora_oci_success_warn",  20, svp, oci_warn);
 	if (DBD_ATTRIB_TRUE(attr,"ora_objects",11,svp))
@@ -551,8 +554,12 @@
 					"OCINlsEnvironmentVariableGet(OCI_NLS_NCHARSET_ID) Check NLS settings etc.");
 				return 0;
 			}
+	PerlIO_printf(DBILOGFP,"uOCINlsEnvironmentVariableGe =%d ncharsetid=%d\n",charsetid,ncharsetid);
 
-		/*{
+/*if (ncharsetid == 2000){
+					ncharsetid = OCI_UTF16ID;
+			    }
+		{
 		After using OCIEnvNlsCreate() to create the environment handle,
 		**the actual lengths and returned lengths of bind and define handles are
 		always in number of bytes**. This applies to the following calls:
@@ -609,7 +616,8 @@
 			if (new_charsetid || new_ncharsetid) { /* reset the ENV with the new charset  from above*/
 				if (new_charsetid) charsetid = new_charsetid;
 				if (new_ncharsetid) ncharsetid = new_ncharsetid;
-				imp_dbh->envhp = NULL;
+
+			   imp_dbh->envhp = NULL;
 				OCIEnvNlsCreate_log_stat( &imp_dbh->envhp, init_mode, 0, NULL, NULL, NULL, 0, 0,
 							charsetid, ncharsetid, status );
 				if (status != OCI_SUCCESS) {
@@ -619,11 +627,14 @@
 				}
 			}
 
+
 			/* update the hard-coded csid constants for unicode charsets */
 			utf8_csid	  = OCINlsCharSetNameToId(imp_dbh->envhp, (void*)"UTF8");
 			al32utf8_csid  = OCINlsCharSetNameToId(imp_dbh->envhp, (void*)"AL32UTF8");
 			al16utf16_csid = OCINlsCharSetNameToId(imp_dbh->envhp, (void*)"AL16UTF16");
 
+PerlIO_printf(DBILOGFP,"utf8_csid=%d al32utf8_csid=%d al16utf16_csid=%d\n",utf8_csid,al32utf8_csid,al16utf16_csid);
+
 #else /* (the old init code) NEW_OCI_INIT */
 		/* this is now depricated and will be removed as we no longer support <9.2 oracle*/
 		/* XXX recent oracle docs recommend using OCIEnvCreate() instead of	*/
@@ -1024,6 +1035,9 @@
 	else if (kl==12 && strEQ(key, "RowCacheSize")) {
 		retsv = newSViv(imp_dbh->RowCacheSize);
 	}
+	else if (kl==11 && strEQ(key, "RowsInCache")) {
+			retsv = newSViv(imp_dbh->RowsInCache);
+	}
 	else if (kl==22 && strEQ(key, "ora_max_nested_cursors")) {
 		retsv = newSViv(imp_dbh->max_nested_cursors);
 	}
@@ -1642,12 +1656,12 @@
 
 	if (trace_level >= 3 || dbd_verbose >= 3 )
 		PerlIO_printf(DBILOGFP, "dbd_rebind_ph_varchar2_table(): bind %s <== %s "
-			"(%s, %s, csid %d->%d->%d, ftype %d, csform %d->%d, maxlen %lu, maxdata_size %lu)\n",
+			"(%s, %s, csid %d->%d->%d, ftype %d, csform %d (%s)->%d (%s), maxlen %lu, maxdata_size %lu)\n",
 			phs->name, neatsvpv(phs->sv,0),
 			(phs->is_inout) ? "inout" : "in",
 			flag_data_is_utf8 ? "is-utf8" : "not-utf8",
 			phs->csid_orig, phs->csid, csid,
-			phs->ftype, phs->csform, csform,
+			phs->ftype, phs->csform,oci_csform_name(phs->csform), csform,oci_csform_name(csform),
 			(unsigned long)phs->maxlen, (unsigned long)phs->maxdata_size);
 
 
@@ -2445,7 +2459,6 @@
 
 	 /* force stmt_type since OCIAttrGet(OCI_ATTR_STMT_TYPE) doesn't work! */
 		imp_sth_csr->stmt_type = OCI_STMT_SELECT;
-		imp_sth_csr->rs_array_on=1;	/* turn on array fetch for ref cursors */
  		DBIc_IMPSET_on(imp_sth_csr);
 
 	 /* set ACTIVE so dbd_describe doesn't do explicit OCI describe */
@@ -2542,9 +2555,9 @@
 	ub2 csid;
 
 	if (trace_level >= 5 || dbd_verbose >= 5 )
-		PerlIO_printf(DBILOGFP, "dbd_rebind_ph() (1): rebinding %s as %s (%s, ftype %d (%s), csid %d, csform %d, inout %d)\n",
+		PerlIO_printf(DBILOGFP, "dbd_rebind_ph() (1): rebinding %s as %s (%s, ftype %d (%s), csid %d, csform %d(%s), inout %d)\n",
 		phs->name, (SvPOK(phs->sv) ? neatsvpv(phs->sv,10) : "NULL"),(SvUTF8(phs->sv) ? "is-utf8" : "not-utf8"),
-		phs->ftype,sql_typecode_name(phs->ftype),phs->csid, phs->csform, phs->is_inout);
+		phs->ftype,sql_typecode_name(phs->ftype),phs->csid, phs->csform,oci_csform_name(phs->csform), phs->is_inout);
 
 	switch (phs->ftype) {
 		case ORA_VARCHAR2_TABLE:
@@ -2653,12 +2666,12 @@
 
 	if (trace_level >= 3 || dbd_verbose >= 3 )
 		PerlIO_printf(DBILOGFP, "dbd_rebind_ph(): bind %s <== %s "
-		"(%s, %s, csid %d->%d->%d, ftype %d (%s), csform %d->%d, maxlen %lu, maxdata_size %lu)\n",
+		"(%s, %s, csid %d->%d->%d, ftype %d (%s), csform %d(%s)->%d(%s), maxlen %lu, maxdata_size %lu)\n",
 		  phs->name, neatsvpv(phs->sv,10),
 		  (phs->is_inout) ? "inout" : "in",
 		  (SvUTF8(phs->sv) ? "is-utf8" : "not-utf8"),
 		  phs->csid_orig, phs->csid, csid,
-		  phs->ftype,sql_typecode_name(phs->ftype), phs->csform, csform,
+		  phs->ftype,sql_typecode_name(phs->ftype), phs->csform, oci_csform_name(phs->csform), csform, oci_csform_name(csform),
 		  (unsigned long)phs->maxlen, (unsigned long)phs->maxdata_size);
 
 
@@ -3040,9 +3053,8 @@
 		if (debug >= 2 || dbd_verbose >= 3 )
 			PerlIO_printf(DBILOGFP,"Statement Execute Mode is %d (%s)\n",imp_sth->exe_mode,oci_exe_mode(imp_sth->exe_mode));
 
-
 		OCIStmtExecute_log_stat(imp_sth->svchp, imp_sth->stmhp, imp_sth->errhp,
-					(ub4)(is_select ? 0 : 1),
+					(ub4)(is_select ? 0: 1),
 					0, 0, 0,(ub4)imp_sth->exe_mode,status);
 
 
@@ -3058,6 +3070,9 @@
 		DBIc_ACTIVE_on(imp_sth);
 		DBIc_ROW_COUNT(imp_sth) = 0; /* reset (possibly re-exec'ing) */
 		row_count = 0;
+		/*reinit the rs_array as well
+		  as we may have more thatn one exe on a prepare*/
+		rs_array_init(imp_sth);
 	}
 	else {
 		OCIAttrGet_stmhp_stat(imp_sth, &row_count, 0, OCI_ATTR_ROW_COUNT, status);
@@ -3224,12 +3239,12 @@
 
 	if (trace_level >= 3 || dbd_verbose >= 3 )
 		PerlIO_printf(DBILOGFP, "do_bind_array_exec(): bind %s <== [array of values] "
-			"(%s, %s, csid %d->%d->%d, ftype %d (%s), csform %d->%d, maxlen %lu, maxdata_size %lu)\n",
+			"(%s, %s, csid %d->%d->%d, ftype %d (%s), csform %d (%s)->%d (%s), maxlen %lu, maxdata_size %lu)\n",
 			phs->name,
 			(phs->is_inout) ? "inout" : "in",
 			(utf8 ? "is-utf8" : "not-utf8"),
 			phs->csid_orig, phs->csid, csid,
-			phs->ftype,sql_typecode_name(phs->ftype), phs->csform, csform,
+			phs->ftype,sql_typecode_name(phs->ftype), phs->csform,oci_csform_name(phs->csform), csform,oci_csform_name(csform),
 			(unsigned long)phs->maxlen, (unsigned long)phs->maxdata_size);
 
 

Modified: dbd-oracle/branches/drcp/oci8.c
==============================================================================
--- dbd-oracle/branches/drcp/oci8.c	(original)
+++ dbd-oracle/branches/drcp/oci8.c	Thu Jan  7 16:42:24 2010
@@ -92,6 +92,7 @@
 		case 102:	return "SQLT_CUR	OCI 7 cursor variable";
 		case 112:	return "SQLT_CLOB / long";
 		case 113:	return "SQLT_BLOB / long";
+		case 114:	return "SQLT_BFILE ";
 		case 116:	return "SQLT_RSET	OCI 8 cursor variable";
 		case ORA_VARCHAR2_TABLE:return "ORA_VARCHAR2_TABLE";
 		case ORA_NUMBER_TABLE: 	return "ORA_NUMBER_TABLE";
@@ -242,7 +243,7 @@
 													the new length semantics, always bytes, is used by OCIEnvNlsCreate */
 		case OCI_NO_MUTEX_STMT:	return "NO_MUTEX_STMT";			/* Do not mutex stmt handle */
 		case OCI_MUTEX_ENV_ONLY:	return "MUTEX_ENV_ONLY";  /* Mutex only the environment handle */
-/*		case OCI_SUPPRESS_NLS_VALIDATION:  return "SUPPRESS_NLS_VALIDATION";	suppress nls validation*/
+/*		case OCI_SUPPRESS_NLS_VALIDATION:return "SUPPRESS_NLS_VALIDATION";	suppress nls validation*/
 													 /* 	  nls validation suppression is on by default;*/
 													  /*	use OCI_ENABLE_NLS_VALIDATION to disable it */
 /*		case OCI_MUTEX_TRY:				return "MUTEX_TRY";	 try and acquire mutex */
@@ -347,6 +348,360 @@
 	return SvPV(sv,na);
 }
 
+/*used to look up the name of a csform value
+  used only for debugging */
+char *
+oci_csform_name(ub4 attr)
+{
+	dTHX;
+	SV *sv;
+	switch (attr) {
+
+/* CHAR/NCHAR/VARCHAR2/NVARCHAR2/CLOB/NCLOB char set "form" information */
+	case SQLCS_IMPLICIT:			return "SQLCS_IMPLICIT";/* for CHAR, VARCHAR2, CLOB w/o a specified set */
+	case SQLCS_NCHAR:				return "SQLCS_NCHAR";/* for NCHAR, NCHAR VARYING, NCLOB */
+	case SQLCS_EXPLICIT:			return "SQLCS_EXPLICIT";/* for CHAR, etc, with "CHARACTER SET ..." syntax */
+	case SQLCS_FLEXIBLE:			return "SQLCS_FLEXIBLE";/* for PL/SQL "flexible" parameters */
+	case SQLCS_LIT_NULL:			return "SQLCS_LIT_NULL";/* for typecheck of NULL and empty_clob() lits */
+	}
+
+	sv = sv_2mortal(newSViv((IV)attr));
+	return SvPV(sv,na);
+}
+
+/*used to look up the name of a OCI_DTYPE_PARAM Attribute Types
+  used only for debugging */
+char *
+oci_dtype_attr_name(ub4 attr)
+{
+	dTHX;
+	SV *sv;
+	switch (attr) {
+/*=======================Describe Handle Parameter Attributes ===============*/
+	case OCI_ATTR_DATA_SIZE:			return "OCI_ATTR_DATA_SIZE";               /* maximum size of the data */
+	case OCI_ATTR_DATA_TYPE:			return "OCI_ATTR_DATA_TYPE"; /* the SQL type of the column/argument */
+	case OCI_ATTR_DISP_SIZE:			return "OCI_ATTR_DISP_SIZE"; /* the display size */
+	case OCI_ATTR_NAME:					return "OCI_ATTR_NAME"; /* the name of the column/argument */
+	case OCI_ATTR_PRECISION:			return "OCI_ATTR_PRECISION"; /* precision if number type */
+	case OCI_ATTR_SCALE:				return "OCI_ATTR_SCALE"; /* scale if number type */
+	case OCI_ATTR_IS_NULL:				return "OCI_ATTR_IS_NULL"; /* is it null ? */
+	case OCI_ATTR_TYPE_NAME: 			return "OCI_ATTR_TYPE_NAME";
+  /* name of the named data type or a package name for package private types */
+	case OCI_ATTR_SCHEMA_NAME: 			return "OCI_ATTR_SCHEMA_NAME";  /* the schema name */
+	case OCI_ATTR_SUB_NAME: 			return "OCI_ATTR_SUB_NAME";  /* type name if package private type */
+	case OCI_ATTR_POSITION:				return "OCI_ATTR_POSITION";
+	case OCI_ATTR_CHAR_USED:            return "OCI_ATTR_CHAR_USED";      /* char length semantics */
+	case OCI_ATTR_CHAR_SIZE:            return "OCI_ATTR_CHAR_SIZE";                /* char length */
+	case OCI_ATTR_CHARSET_ID:			return "OCI_ATTR_CHARSET_ID";    /* Character Set ID */
+	case OCI_ATTR_CHARSET_FORM:			return "OCI_ATTR_CHARSET_FORM"; /* Character Set Form */
+	}
+
+	sv = sv_2mortal(newSViv((IV)attr));
+	return SvPV(sv,na);
+
+}
+
+/*used to look up the name of non a OCI_DTYPE_PARAM Attribute Types
+  used only for debugging */
+char *
+oci_attr_name(ub4 attr)
+{
+	dTHX;
+	SV *sv;
+	switch (attr) {
+	/*=============================Attribute Types===============================*/
+
+
+	case OCI_ATTR_FNCODE:				return "OCI_ATTR_FNCODE";                       /* the OCI function code */
+	case OCI_ATTR_OBJECT:				return "OCI_ATTR_OBJECT"; /* is the environment initialized in object mode */
+	case OCI_ATTR_NONBLOCKING_MODE:		return "OCI_ATTR_NONBLOCKING_MODE";                   /* non blocking mode */
+	case OCI_ATTR_SQLCODE:				return "OCI_ATTR_SQLCODE";                                  /* the SQL verb */
+	case OCI_ATTR_ENV:					return "OCI_ATTR_ENV";                            /* the environment handle */
+	case OCI_ATTR_SERVER:				return "OCI_ATTR_SERVER";                               /* the server handle*/
+	case OCI_ATTR_SESSION:				return "OCI_ATTR_SESSION";                        /* the user session handle*/
+	case OCI_ATTR_TRANS:				return "OCI_ATTR_TRANS";                         /* the transaction handle */
+	case OCI_ATTR_ROW_COUNT:			return "OCI_ATTR_ROW_COUNT";                  /* the rows processed so far */
+	case OCI_ATTR_SQLFNCODE:			return "OCI_ATTR_SQLFNCODE";               /* the SQL verb of the statement */
+	case OCI_ATTR_PREFETCH_ROWS:		return "OCI_ATTR_PREFETCH_ROWS";    /* sets the number of rows to prefetch */
+	case OCI_ATTR_NESTED_PREFETCH_ROWS:	return "OCI_ATTR_NESTED_PREFETCH_ROWS"; /* the prefetch rows of nested table*/
+	case OCI_ATTR_PREFETCH_MEMORY:		return "OCI_ATTR_PREFETCH_MEMORY";         /* memory limit for rows fetched */
+	case OCI_ATTR_NESTED_PREFETCH_MEMORY:return "OCI_ATTR_NESTED_PREFETCH_MEMORY";   /* memory limit for nested rows */
+	case OCI_ATTR_CHAR_COUNT:			return "OCI_ATTR_CHAR_COUNT";
+	                    /* this specifies the bind and define size in characters */
+	case OCI_ATTR_PDSCL:				return "OCI_ATTR_PDSCL";                          /* packed decimal scale
+	case OCI_ATTR_FSPRECISION OCI_ATTR_PDSCL:return "";*/
+	                                          /* fs prec for datetime data types */
+	case OCI_ATTR_PDPRC:				return "OCI_ATTR_PDPRC";                         /* packed decimal format
+	case OCI_ATTR_LFPRECISION OCI_ATTR_PDPRC: return "";
+	                                          /* fs prec for datetime data types */
+	case OCI_ATTR_PARAM_COUNT:			return "OCI_ATTR_PARAM_COUNT";       /* number of column in the select list */
+	case OCI_ATTR_ROWID:				return "OCI_ATTR_ROWID";                                     /* the rowid */
+	case OCI_ATTR_CHARSET:				return "OCI_ATTR_CHARSET";                     /* the character set value */
+	case OCI_ATTR_NCHAR:				return "OCI_ATTR_NCHAR"; /* NCHAR type */
+	case OCI_ATTR_USERNAME:				return "OCI_ATTR_USERNAME"; /* username attribute */
+	case OCI_ATTR_PASSWORD:				return "OCI_ATTR_PASSWORD";                           /* password attribute */
+	case OCI_ATTR_STMT_TYPE:			return "OCI_ATTR_STMT_TYPE";                           /* statement type */
+	case OCI_ATTR_INTERNAL_NAME:		return "OCI_ATTR_INTERNAL_NAME";             /* user friendly global name */
+	case OCI_ATTR_EXTERNAL_NAME:		return "OCI_ATTR_EXTERNAL_NAME";      /* the internal name for global txn */
+	case OCI_ATTR_XID:					return "OCI_ATTR_XID";           /* XOPEN defined global transaction id */
+	case OCI_ATTR_TRANS_LOCK:			return "OCI_ATTR_TRANS_LOCK";                                            /* */
+	case OCI_ATTR_TRANS_NAME:			return "OCI_ATTR_TRANS_NAME";    /* string to identify a global transaction */
+	case OCI_ATTR_HEAPALLOC:			return "OCI_ATTR_HEAPALLOC";                /* memory allocated on the heap */
+	case OCI_ATTR_CHARSET_FORM:			return "OCI_ATTR_CHARSET_FORM";                       /* Character Set Form */
+	case OCI_ATTR_MAXDATA_SIZE:			return "OCI_ATTR_MAXDATA_SIZE";       /* Maximumsize of data on the server  */
+	case OCI_ATTR_CACHE_OPT_SIZE:		return "OCI_ATTR_CACHE_OPT_SIZE";              /* object cache optimal size */
+	case OCI_ATTR_CACHE_MAX_SIZE:		return "OCI_ATTR_CACHE_MAX_SIZE";   /* object cache maximum size percentage */
+	case OCI_ATTR_PINOPTION:			return "OCI_ATTR_PINOPTION";             /* object cache default pin option */
+	case OCI_ATTR_ALLOC_DURATION:		return "OCI_ATTR_ALLOC_DURATION";
+	                                 /* object cache default allocation duration */
+	case OCI_ATTR_PIN_DURATION:				return "OCI_ATTR_PIN_DURATION";        /* object cache default pin duration */
+	case OCI_ATTR_FDO:					return "OCI_ATTR_FDO";       /* Format Descriptor object attribute */
+	case OCI_ATTR_POSTPROCESSING_CALLBACK:		return "OCI_ATTR_POSTPROCESSING_CALLBACK";
+	                                         /* Callback to process outbind data */
+	case OCI_ATTR_POSTPROCESSING_CONTEXT:		return "OCI_ATTR_POSTPROCESSING_CONTEXT";
+	                                 /* Callback context to process outbind data */
+	case OCI_ATTR_ROWS_RETURNED:		return "OCI_ATTR_ROWS_RETURNED";
+	               /* Number of rows returned in current iter - for Bind handles */
+	case OCI_ATTR_FOCBK:				return "OCI_ATTR_FOCBK";              /* Failover Callback attribute */
+	case OCI_ATTR_IN_V8_MODE:			return "OCI_ATTR_IN_V8_MODE"; /* is the server/service context in V8 mode */
+	case OCI_ATTR_LOBEMPTY:				return "OCI_ATTR_LOBEMPTY";                              /* empty lob ? */
+	case OCI_ATTR_SESSLANG:				return "OCI_ATTR_SESSLANG";                  /* session language handle */
+
+	case OCI_ATTR_VISIBILITY:			return "OCI_ATTR_VISIBILITY";                     /* visibility */
+	case OCI_ATTR_RELATIVE_MSGID:		return "OCI_ATTR_RELATIVE_MSGID";            /* relative message id */
+	case OCI_ATTR_SEQUENCE_DEVIATION:	return "OCI_ATTR_SEQUENCE_DEVIATION";             /* sequence deviation */
+
+	case OCI_ATTR_CONSUMER_NAME:		return "OCI_ATTR_CONSUMER_NAME";                  /* consumer name */
+	case OCI_ATTR_DEQ_MODE:				return "OCI_ATTR_DEQ_MODE";                   /* dequeue mode */
+	case OCI_ATTR_NAVIGATION:			return "OCI_ATTR_NAVIGATION";                     /* navigation */
+	case OCI_ATTR_WAIT:					return "OCI_ATTR_WAIT";                           /* wait */
+	case OCI_ATTR_DEQ_MSGID:			return "OCI_ATTR_DEQ_MSGID";             /* dequeue message id */
+
+	case OCI_ATTR_PRIORITY:				return "OCI_ATTR_PRIORITY";                       /* priority */
+	case OCI_ATTR_DELAY:				return "OCI_ATTR_DELAY";                          /* delay */
+	case OCI_ATTR_EXPIRATION:			return "OCI_ATTR_EXPIRATION";                     /* expiration */
+	case OCI_ATTR_CORRELATION:			return "OCI_ATTR_CORRELATION";                 /* correlation id */
+	case OCI_ATTR_ATTEMPTS:				return "OCI_ATTR_ATTEMPTS";                 /* # of attempts */
+	case OCI_ATTR_RECIPIENT_LIST:		return "OCI_ATTR_RECIPIENT_LIST";                 /* recipient list */
+	case OCI_ATTR_EXCEPTION_QUEUE:		return "OCI_ATTR_EXCEPTION_QUEUE";           /* exception queue name */
+	case OCI_ATTR_ENQ_TIME:				return "OCI_ATTR_ENQ_TIME";/* enqueue time (only OCIAttrGet) */
+	case OCI_ATTR_MSG_STATE:			return "OCI_ATTR_MSG_STATE";/* message state (only OCIAttrGet) */
+	                                                   /* NOTE: 64-66 used below */
+	case OCI_ATTR_AGENT_NAME:			return "OCI_ATTR_AGENT_NAME";                 /* agent name */
+	case OCI_ATTR_AGENT_ADDRESS:		return "OCI_ATTR_AGENT_ADDRESS";                  /* agent address */
+	case OCI_ATTR_AGENT_PROTOCOL:		return "OCI_ATTR_AGENT_PROTOCOL";                /* agent protocol */
+
+	case OCI_ATTR_SENDER_ID:			return "OCI_ATTR_SENDER_ID";                      /* sender id */
+	case OCI_ATTR_ORIGINAL_MSGID:		return "OCI_ATTR_ORIGINAL_MSGID";           /* original message id */
+
+	case OCI_ATTR_QUEUE_NAME:			return "OCI_ATTR_QUEUE_NAME";                     /* queue name */
+	case OCI_ATTR_NFY_MSGID:			return "OCI_ATTR_NFY_MSGID";                     /* message id */
+	case OCI_ATTR_MSG_PROP:				return "OCI_ATTR_MSG_PROP";            /* message properties */
+
+	case OCI_ATTR_NUM_DML_ERRORS:		return "OCI_ATTR_NUM_DML_ERRORS";       /* num of errs in array DML */
+	case OCI_ATTR_DML_ROW_OFFSET:		return "OCI_ATTR_DML_ROW_OFFSET";       /* row offset in the array */
+
+	case OCI_ATTR_DATEFORMAT:			return "OCI_ATTR_DATEFORMAT";     /* default date format string */
+	case OCI_ATTR_BUF_ADDR:				return "OCI_ATTR_BUF_ADDR";                 /* buffer address */
+	case OCI_ATTR_BUF_SIZE:				return "OCI_ATTR_BUF_SIZE";                   /* buffer size */
+	case OCI_ATTR_DIRPATH_MODE:			return "OCI_ATTR_DIRPATH_MODE";  /* mode of direct path operation */
+	case OCI_ATTR_DIRPATH_NOLOG:		return "OCI_ATTR_DIRPATH_NOLOG";               /* nologging option */
+	case OCI_ATTR_DIRPATH_PARALLEL:		return "OCI_ATTR_DIRPATH_PARALLEL";    /* parallel (temp seg) option */
+	case OCI_ATTR_NUM_ROWS:				return "OCI_ATTR_NUM_ROWS"; /* number of rows in column array */
+	                                  /* NOTE that OCI_ATTR_NUM_COLS is a column
+	                                   * array attribute too.
+	                                   */
+	case OCI_ATTR_COL_COUNT:			return "OCI_ATTR_COL_COUNT";        /* columns of column array
+	                                                     processed so far.       */
+	case OCI_ATTR_STREAM_OFFSET:		return "OCI_ATTR_STREAM_OFFSET";  /* str off of last row processed
+	case OCI_ATTR_SHARED_HEAPALLO:				return "";    /* Shared Heap Allocation Size */
+
+	case OCI_ATTR_SERVER_GROUP:			return "OCI_ATTR_SERVER_GROUP";    /* server group name */
+
+	case OCI_ATTR_MIGSESSION:			return "OCI_ATTR_MIGSESSION";  /* migratable session attribute */
+
+	case OCI_ATTR_NOCACHE:				return "OCI_ATTR_NOCACHE";                /* Temporary LOBs */
+
+	case OCI_ATTR_MEMPOOL_SIZE:			return "OCI_ATTR_MEMPOOL_SIZE";                      /* Pool Size */
+	case OCI_ATTR_MEMPOOL_INSTNAME:		return "OCI_ATTR_MEMPOOL_INSTNAME";                /* Instance name */
+	case OCI_ATTR_MEMPOOL_APPNAME:		return "OCI_ATTR_MEMPOOL_APPNAME";               /* Application name */
+	case OCI_ATTR_MEMPOOL_HOMENAME:		return "OCI_ATTR_MEMPOOL_HOMENAME";            /* Home Directory name */
+	case OCI_ATTR_MEMPOOL_MODEL:		return "OCI_ATTR_MEMPOOL_MODEL";     /* Pool Model (proc,thrd,both)*/
+	case OCI_ATTR_MODES:				return "OCI_ATTR_MODES";                          /* Modes */
+
+	case OCI_ATTR_SUBSCR_NAME:			return "OCI_ATTR_SUBSCR_NAME";           /* name of subscription */
+	case OCI_ATTR_SUBSCR_CALLBACK:		return "OCI_ATTR_SUBSCR_CALLBACK";            /* associated callback */
+	case OCI_ATTR_SUBSCR_CTX:			return "OCI_ATTR_SUBSCR_CTX";   /* associated callback context */
+	case OCI_ATTR_SUBSCR_PAYLOAD:		return "OCI_ATTR_SUBSCR_PAYLOAD";             /* associated payload */
+	case OCI_ATTR_SUBSCR_NAMESPACE:		return "OCI_ATTR_SUBSCR_NAMESPACE";          /* associated namespace */
+
+	case OCI_ATTR_PROXY_CREDENTIALS:	return "OCI_ATTR_PROXY_CREDENTIALS";         /* Proxy user credentials */
+	case OCI_ATTR_INITIAL_CLIENT_ROLES:	return "OCI_ATTR_INITIAL_CLIENT_ROLES";      /* Initial client role list */
+
+	case OCI_ATTR_UNK:					return "OCI_ATTR_UNK";                  /* unknown attribute */
+	case OCI_ATTR_NUM_COLS:				return "OCI_ATTR_NUM_COLS";                  /* number of columns */
+	case OCI_ATTR_LIST_COLUMNS:			return "OCI_ATTR_LIST_COLUMNS";       /* parameter of the column list */
+	case OCI_ATTR_RDBA:					return "OCI_ATTR_RDBA";           /* DBA of the segment header */
+	case OCI_ATTR_CLUSTERED:			return "OCI_ATTR_CLUSTERED";      /* whether the table is clustered */
+	case OCI_ATTR_PARTITIONED:			return "OCI_ATTR_PARTITIONED";    /* whether the table is partitioned */
+	case OCI_ATTR_INDEX_ONLY:			return "OCI_ATTR_INDEX_ONLY";     /* whether the table is index only */
+	case OCI_ATTR_LIST_ARGUMENTS:		return "OCI_ATTR_LIST_ARGUMENTS";      /* parameter of the argument list */
+	case OCI_ATTR_LIST_SUBPROGRAMS:		return "OCI_ATTR_LIST_SUBPROGRAMS";    /* parameter of the subprogram list */
+	case OCI_ATTR_REF_TDO:				return "OCI_ATTR_REF_TDO";          /* REF to the type descriptor */
+	case OCI_ATTR_LINK:					return "OCI_ATTR_LINK";              /* the database link name */
+	case OCI_ATTR_MIN:					return "OCI_ATTR_MIN";                       /* minimum value */
+	case OCI_ATTR_MAX:					return "OCI_ATTR_MAX";                       /* maximum value */
+	case OCI_ATTR_INCR:					return "OCI_ATTR_INCR";                     /* increment value */
+	case OCI_ATTR_CACHE:				return "OCI_ATTR_CACHE";   /* number of sequence numbers cached */
+	case OCI_ATTR_ORDER:				return "OCI_ATTR_ORDER";     /* whether the sequence is ordered */
+	case OCI_ATTR_HW_MARK:				return "OCI_ATTR_HW_MARK";                     /* high-water mark */
+	case OCI_ATTR_TYPE_SCHEMA:			return "OCI_ATTR_TYPE_SCHEMA";                  /* type's schema name */
+	case OCI_ATTR_TIMESTAMP:			return "OCI_ATTR_TIMESTAMP";             /* timestamp of the object */
+	case OCI_ATTR_NUM_ATTRS:			return "OCI_ATTR_NUM_ATTRS";                /* number of sttributes */
+	case OCI_ATTR_NUM_PARAMS:			return "OCI_ATTR_NUM_PARAMS";                /* number of parameters */
+	case OCI_ATTR_OBJID:				return "OCI_ATTR_OBJID";       /* object id for a table or view */
+	case OCI_ATTR_PTYPE:				return "OCI_ATTR_PTYPE";           /* type of info described by */
+	case OCI_ATTR_PARAM:				return "OCI_ATTR_PARAM";                /* parameter descriptor */
+	case OCI_ATTR_OVERLOAD_ID:			return "OCI_ATTR_OVERLOAD_ID";     /* overload ID for funcs and procs */
+	case OCI_ATTR_TABLESPACE:			return "OCI_ATTR_TABLESPACE";                    /* table name space */
+	case OCI_ATTR_TDO:					return "OCI_ATTR_TDO";                       /* TDO of a type */
+	case OCI_ATTR_LTYPE:				return "OCI_ATTR_LTYPE";                           /* list type */
+	case OCI_ATTR_PARSE_ERROR_OFFSET:	return "OCI_ATTR_PARSE_ERROR_OFFSET";               /* Parse Error offset */
+	case OCI_ATTR_IS_TEMPORARY:			return "OCI_ATTR_IS_TEMPORARY";          /* whether table is temporary */
+	case OCI_ATTR_IS_TYPED:				return "OCI_ATTR_IS_TYPED";              /* whether table is typed */
+	case OCI_ATTR_DURATION:				return "OCI_ATTR_DURATION";         /* duration of temporary table */
+	case OCI_ATTR_IS_INVOKER_RIGHTS:	return "OCI_ATTR_IS_INVOKER_RIGHTS";                 /* is invoker rights */
+	case OCI_ATTR_OBJ_NAME:				return "OCI_ATTR_OBJ_NAME";           /* top level schema obj name */
+	case OCI_ATTR_OBJ_SCHEMA:			return "OCI_ATTR_OBJ_SCHEMA";                         /* schema name */
+	case OCI_ATTR_OBJ_ID:				return "OCI_ATTR_OBJ_ID";          /* top level schema object id */
+
+	case OCI_ATTR_DIRPATH_SORTED_INDEX:	return "OCI_ATTR_DIRPATH_SORTED_INDEX";/* index that data is sorted on */
+
+	            /* direct path index maint method (see oci8dp.h) */
+	case OCI_ATTR_DIRPATH_INDEX_MAINT_METHOD:	return "OCI_ATTR_DIRPATH_INDEX_MAINT_METHOD";
+
+	    /* parallel load: db file, initial and next extent sizes */
+
+	case OCI_ATTR_DIRPATH_FILE:			return "OCI_ATTR_DIRPATH_FILE";     /* DB file to load into */
+	case OCI_ATTR_DIRPATH_STORAGE_INITIAL:		return "OCI_ATTR_DIRPATH_STORAGE_INITIAL";       /* initial extent size */
+	case OCI_ATTR_DIRPATH_STORAGE_NEXT:	return "OCI_ATTR_DIRPATH_STORAGE_NEXT";          /* next extent size */
+
+
+	case OCI_ATTR_TRANS_TIMEOUT:		return "OCI_ATTR_TRANS_TIMEOUT";      /* transaction timeout */
+	case OCI_ATTR_SERVER_STATUS:		return "OCI_ATTR_SERVER_STATUS";/* state of the server handle */
+	case OCI_ATTR_STATEMENT:			return "OCI_ATTR_STATEMENT"; /* statement txt in stmt hdl */
+	                                /* statement should not be executed in cache
+	case OCI_ATTR_NO_CACHE:				return "";*/
+	case OCI_ATTR_DEQCOND:				return "OCI_ATTR_DEQCOND";         /* dequeue condition */
+	case OCI_ATTR_RESERVED_2:			return "OCI_ATTR_RESERVED_2";                  /* reserved */
+
+
+	case OCI_ATTR_SUBSCR_RECPT:			return "OCI_ATTR_SUBSCR_RECPT";/* recepient of subscription */
+	case OCI_ATTR_SUBSCR_RECPTPROTO:	return "OCI_ATTR_SUBSCR_RECPTPROTO";    /* protocol for recepient */
+
+	    /* 8.2 dpapi support of ADTs */
+	case OCI_ATTR_DIRPATH_EXPR_TYPE:	return "OCI_ATTR_DIRPATH_EXPR_TYPE";       /* expr type of OCI_ATTR_NAME */
+
+	case OCI_ATTR_DIRPATH_INPUT:		return "OCI_ATTR_DIRPATH_INPUT";    /* input in text or stream format
+	case OCI_DIRPATH_INPUT_TEXT:				return "";
+	case OCI_DIRPATH_INPUT_STREAM:				return "";
+	case OCI_DIRPATH_INPUT_UNKNOWN:				return "";	*/
+	case OCI_ATTR_LDAP_HOST:			return "OCI_ATTR_LDAP_HOST";             /* LDAP host to connect to */
+	case OCI_ATTR_LDAP_PORT:			return "OCI_ATTR_LDAP_PORT";              /* LDAP port to connect to */
+	case OCI_ATTR_BIND_DN:				return "OCI_ATTR_BIND_DN";                              /* bind DN */
+	case OCI_ATTR_LDAP_CRED:			return "OCI_ATTR_LDAP_CRED";       /* credentials to connect to LDAP */
+	case OCI_ATTR_WALL_LOC:				return "OCI_ATTR_WALL_LOC";               /* client wallet location */
+	case OCI_ATTR_LDAP_AUTH:			return "OCI_ATTR_LDAP_AUTH";           /* LDAP authentication method */
+	case OCI_ATTR_LDAP_CTX:				return "OCI_ATTR_LDAP_CTX";        /* LDAP adminstration context DN */
+	case OCI_ATTR_SERVER_DNS:			return "OCI_ATTR_SERVER_DNS";      /* list of registration server DNs */
+
+	case OCI_ATTR_DN_COUNT:				return "OCI_ATTR_DN_COUNT";             /* the number of server DNs */
+	case OCI_ATTR_SERVER_DN:			return "OCI_ATTR_SERVER_DN";                 /* server DN attribute */
+
+	case OCI_ATTR_MAXCHAR_SIZE:			return "OCI_ATTR_MAXCHAR_SIZE";    /* max char size of data */
+
+	case OCI_ATTR_CURRENT_POSITION:		return "OCI_ATTR_CURRENT_POSITION"; /* for scrollable result sets*/
+
+	/* Added to get attributes for ref cursor to statement handle */
+	case OCI_ATTR_RESERVED_3:			return "OCI_ATTR_RESERVED_3";                  /* reserved */
+	case OCI_ATTR_RESERVED_4:			return "OCI_ATTR_RESERVED_4";                  /* reserved */
+	case OCI_ATTR_DIRPATH_FN_CTX:		return "";  /* fn ctx ADT attrs or args */
+	case OCI_ATTR_DIGEST_ALGO:			return "OCI_ATTR_DIRPATH_FN_CTX";         /* digest algorithm */
+	case OCI_ATTR_CERTIFICATE:			return "OCI_ATTR_CERTIFICATE";               /* certificate */
+	case OCI_ATTR_SIGNATURE_ALGO:		return "OCI_ATTR_SIGNATURE_ALGO";       /* signature algorithm */
+	case OCI_ATTR_CANONICAL_ALGO:		return "OCI_ATTR_CANONICAL_ALGO";    /* canonicalization algo. */
+	case OCI_ATTR_PRIVATE_KEY:			return "OCI_ATTR_PRIVATE_KEY";               /* private key */
+	case OCI_ATTR_DIGEST_VALUE:			return "OCI_ATTR_DIGEST_VALUE";             /* digest value */
+	case OCI_ATTR_SIGNATURE_VAL:		return "OCI_ATTR_SIGNATURE_VAL";           /* signature value */
+	case OCI_ATTR_SIGNATURE:			return "OCI_ATTR_SIGNATURE";                 /* signature */
+
+	/* attributes for setting OCI stmt caching specifics in svchp */
+	case OCI_ATTR_STMTCACHESIZE :		return "OCI_ATTR_STMTCACHESIZE";     /* size of the stm cache */
+
+	/* --------------------------- Connection Pool Attributes ------------------ */
+	case OCI_ATTR_CONN_NOWAIT:			return "OCI_ATTR_CONN_NOWAIT";
+	case OCI_ATTR_CONN_BUSY_COUNT:		return "OCI_ATTR_CONN_BUSY_COUNT";
+	case OCI_ATTR_CONN_OPEN_COUNT:		return "OCI_ATTR_CONN_OPEN_COUNT";
+	case OCI_ATTR_CONN_TIMEOUT:			return "OCI_ATTR_CONN_TIMEOUT";
+	case OCI_ATTR_STMT_STATE:			return "OCI_ATTR_STMT_STATE";
+	case OCI_ATTR_CONN_MIN:				return "OCI_ATTR_CONN_MIN";
+	case OCI_ATTR_CONN_MAX:				return "OCI_ATTR_CONN_MAX";
+	case OCI_ATTR_CONN_INCR:			return "OCI_ATTR_CONN_INCR";
+
+	case OCI_ATTR_DIRPATH_OID:			return "OCI_ATTR_DIRPATH_OID";   /* loading into an OID col */
+
+	case OCI_ATTR_NUM_OPEN_STMTS:		return "OCI_ATTR_NUM_OPEN_STMTS";    /* open stmts in session */
+	case OCI_ATTR_DESCRIBE_NATIVE:		return "OCI_ATTR_DESCRIBE_NATIVE"; /* get native info via desc */
+
+	case OCI_ATTR_BIND_COUNT:			return "OCI_ATTR_BIND_COUNT";   /* number of bind postions */
+	case OCI_ATTR_HANDLE_POSITION:		return "OCI_ATTR_HANDLE_POSITION";/* pos of bind/define handle */
+	case OCI_ATTR_RESERVED_5:			return "OCI_ATTR_RESERVED_5";                 /* reserverd */
+	case OCI_ATTR_SERVER_BUSY:			return "OCI_ATTR_SERVER_BUSY"; /* call in progress on server*/
+
+	case OCI_ATTR_DIRPATH_SID:			return "OCI_ATTR_DIRPATH_SID";   /* loading into an SID col */
+	/* notification presentation for recipient */
+	case OCI_ATTR_SUBSCR_RECPTPRES:		return "OCI_ATTR_SUBSCR_RECPTPRES";
+	case OCI_ATTR_TRANSFORMATION:		return "OCI_ATTR_TRANSFORMATION"; /* AQ message transformation */
+
+	case OCI_ATTR_ROWS_FETCHED:			return "OCI_ATTR_ROWS_FETCHED"; /* rows fetched in last call */
+
+	/* --------------------------- Snapshot attributes ------------------------- */
+	case OCI_ATTR_SCN_BASE:				return "OCI_ATTR_SCN_BASE";          /* snapshot base */
+	case OCI_ATTR_SCN_WRAP:				return "OCI_ATTR_SCN_WRAP";            /* snapshot wrap */
+
+	/* --------------------------- Miscellanous attributes --------------------- */
+	case OCI_ATTR_RESERVED_6:			return "OCI_ATTR_RESERVED_6";                 /* reserved */
+	case OCI_ATTR_READONLY_TXN:			return "OCI_ATTR_READONLY_TXN";          /* txn is readonly */
+	case OCI_ATTR_RESERVED_7:			return "OCI_ATTR_RESERVED_7";                  /* reserved */
+	case OCI_ATTR_ERRONEOUS_COLUMN:		return "OCI_ATTR_ERRONEOUS_COLUMN"; /* position of erroneous col */
+	case OCI_ATTR_RESERVED_8:			return "OCI_ATTR_RESERVED_8";                  /* reserved */
+
+	/* -------------------- 8.2 dpapi support of ADTs continued ---------------- */
+	case OCI_ATTR_DIRPATH_OBJ_CONSTR:	return "OCI_ATTR_DIRPATH_OBJ_CONSTR"; /* obj type of subst obj tbl */
+
+	/************************FREE attribute     207      *************************/
+	/************************FREE attribute     208      *************************/
+	case OCI_ATTR_ENV_UTF16:			return "OCI_ATTR_ENV_UTF16";     /* is env in utf16 mode? */
+	case OCI_ATTR_RESERVED_9:			return "OCI_ATTR_RESERVED_9";          /* reserved for TMZ */
+	case OCI_ATTR_RESERVED_10:			return "OCI_ATTR_RESERVED_10";                 /* reserved */
+
+	/* Attr to allow setting of the stream version PRIOR to calling Prepare */
+	case OCI_ATTR_DIRPATH_STREAM_VERSION:	return "OCI_ATTR_DIRPATH_STREAM_VERSION";      /* version of the stream
+	case OCI_ATTR_RESERVED_11:				return "OCI_ATTR_RESERVED_11";                 /* reserved */
+
+	case OCI_ATTR_RESERVED_12:			return "OCI_ATTR_RESERVED_12";                 /* reserved */
+	case OCI_ATTR_RESERVED_13:			return "OCI_ATTR_RESERVED_13";                 /* reserved */
+
+	/* OCI_ATTR_RESERVED_14 */
+
+	case OCI_ATTR_RESERVED_15:			return "OCI_ATTR_RESERVED_15";                /* reserved */
+	case OCI_ATTR_RESERVED_16:			return "OCI_ATTR_RESERVED_16";                /* reserved */
+
+	}
+	sv = sv_2mortal(newSViv((IV)attr));
+	return SvPV(sv,na);
+}
+
 /*used to look up the name of a fetchtype constant
   used only for debugging */
 char *
@@ -424,22 +779,34 @@
 int
 oci_error_err(SV *h, OCIError *errhp, sword status, char *what, sb4 force_err)
 {
+
 	dTHX;
 	D_imp_xxh(h);
 	sb4 errcode;
-	SV *errstr = sv_newmortal();
-	errcode = oci_error_get(errhp, status, what, errstr, DBIS->debug);
+	SV *errstr_sv = sv_newmortal();
+	SV *errcode_sv = sv_newmortal();
+	errcode = oci_error_get(errhp, status, what, errstr_sv, DBIS->debug);
+	if (CSFORM_IMPLIES_UTF8(SQLCS_IMPLICIT)) {
+	#ifdef sv_utf8_decode
+	sv_utf8_decode(errstr_sv);
+	#else
+	SvUTF8_on(errstr_sv);
+	#endif
+	}
 
-	/* DBIc_ERR *must* be SvTRUE (for RaiseError etc), some	*/
-	/* errors, like OCI_INVALID_HANDLE, don't set errcode.	*/
+	/* DBIc_ERR *must* be SvTRUE (for RaiseError etc), some */
+	/* errors, like OCI_INVALID_HANDLE, don't set errcode. */
 	if (force_err)
 	errcode = force_err;
 	if (status == OCI_SUCCESS_WITH_INFO)
-	errcode = 0;	/* record as a "warning" for DBI>=1.43 */
+	errcode = 0; /* record as a "warning" for DBI>=1.43 */
 	else if (errcode == 0)
 	errcode = (status != 0) ? status : -10000;
-	DBIh_SET_ERR_CHAR(h, imp_xxh, Nullch, errcode, SvPV_nolen(errstr), Nullch, Nullch);
-	return 0;	/* always returns 0 */
+
+	sv_setiv(errcode_sv, errcode);
+	DBIh_SET_ERR_SV(h, imp_xxh, errcode_sv, errstr_sv, Nullsv, Nullsv);
+	return 0; /* always returns 0 */
+
 }
 
 
@@ -526,6 +893,7 @@
 	/* a memory size, perhaps also default $RowCacheSize to a	*/
 	/* negative value. OCI_ATTR_PREFETCH_MEMORY */
 
+
 	if (!DBIc_ACTIVE(imp_dbh)) {
 		oci_error(sth, NULL, OCI_ERROR, "Database disconnected");
 		return 0;
@@ -549,7 +917,7 @@
 	imp_sth->auto_lob = 1;
 	imp_sth->exe_mode  = OCI_DEFAULT;
 
-		if (attribs) {
+	if (attribs) {
 		SV **svp;
 		IV ora_auto_lob = 1;
 		DBD_ATTRIB_GET_IV(  attribs, "ora_parse_lang", 14, svp, oparse_lng);
@@ -560,22 +928,26 @@
 		DBD_ATTRIB_GET_IV(  attribs, "ora_piece_lob", 13, svp, ora_piece_lob);
 		DBD_ATTRIB_GET_IV(  attribs, "ora_piece_size", 14, svp, ora_piece_size);
 
-		imp_sth->auto_lob = (ora_auto_lob) ? 1 : 0;
-		imp_sth->pers_lob = (ora_pers_lob) ? 1 : 0;
-		imp_sth->clbk_lob = (ora_clbk_lob) ? 1 : 0;
-		imp_sth->piece_lob = (ora_piece_lob) ? 1 : 0;
-		imp_sth->piece_size = (ora_piece_size) ? ora_piece_size : 0;
+		imp_sth->auto_lob	= (ora_auto_lob) ? 1 : 0;
+		imp_sth->pers_lob	= (ora_pers_lob) ? 1 : 0;
+		imp_sth->clbk_lob 	= (ora_clbk_lob) ? 1 : 0;
+		imp_sth->piece_lob	= (ora_piece_lob) ? 1 : 0;
+		imp_sth->piece_size	= (ora_piece_size) ? ora_piece_size : 0;
+		imp_sth->prefetch_rows 	= 0;
+		imp_sth->prefetch_memory= 0;
 		/* ora_check_sql only works for selects owing to Oracle behaviour */
 		DBD_ATTRIB_GET_IV(  attribs, "ora_check_sql", 13, svp, ora_check_sql);
 		DBD_ATTRIB_GET_IV(  attribs, "ora_exe_mode", 12, svp, imp_sth->exe_mode);
 		DBD_ATTRIB_GET_IV(  attribs, "ora_prefetch_memory",  19, svp, imp_sth->prefetch_memory);
+		DBD_ATTRIB_GET_IV(  attribs, "ora_prefetch_rows",  17, svp, imp_sth->prefetch_rows);
+		DBD_ATTRIB_GET_IV(  attribs, "ora_row_cache_off",  17, svp, imp_sth->row_cache_off);
 		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);
 
 		if (!dbd_verbose)
 			DBD_ATTRIB_GET_IV(  attribs, "dbd_verbose",  11, svp, dbd_verbose);
-		}
+	}
 
 
  	/* scan statement for '?', ':1' and/or ':foo' style placeholders	*/
@@ -618,8 +990,8 @@
 	DBIc_IMPSET_on(imp_sth);
 
 	if (ora_check_sql) {
-	if (!dbd_describe(sth, imp_sth))
-		return 0;
+		if (!dbd_describe(sth, imp_sth))
+			return 0;
 	}
 	else {
 		/* set initial cache size by memory */
@@ -1013,7 +1385,6 @@
 
 		imp_sth_nested->stmhp = stmhp_nested;
 		imp_sth_nested->nested_cursor = 1;
-		imp_sth_nested->rs_array_on = 1;
 		imp_sth_nested->stmt_type = OCI_STMT_SELECT;
 
 		DBIc_IMPSET_on(imp_sth_nested);
@@ -1204,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,"
@@ -1240,11 +1611,11 @@
 			  /* lab  0, 0, (ub2)0, (ub1)SQLCS_IMPLICIT, status); */
 
 		if (dbis->debug >= 3 || dbd_verbose >= 3 )
-			PerlIO_printf(DBILOGFP, "		OCILobRead field %d %s: LOBlen %lu, LongReadLen %lu, BufLen %lu, Got %lu\n",
+			PerlIO_printf(DBILOGFP, "	\nz	OCILobRead field %d %s: LOBlen %lu, LongReadLen %lu, BufLen %lu, Got %lu\n",
 				fbh->field_num+1, oci_status_name(status), ul_t(loblen),
 				ul_t(imp_sth->long_readlen), ul_t(buflen), ul_t(amtp));
 		if (status != OCI_SUCCESS) {
-			oci_error(sth, imp_sth->errhp, status, "OCILobRead");
+			oci_error(sth, imp_sth->errhp, status, "   cc OCILobRead");
 			sv_set_undef(dest_sv);	/* signal error */
 			return 0;
 		}
@@ -1261,20 +1632,20 @@
 		SvGROW(dest_sv, byte_destoffset + 1);
 		if (dbis->debug >= 3 || dbd_verbose >= 3 )
 			PerlIO_printf(DBILOGFP,
-				"		OCILobRead field %d %s: LOBlen %lu, LongReadLen %lu, BufLen %lu, Got %lu\n",
+				"	\nx	OCILobRead field %d %s: LOBlen %lu, LongReadLen %lu, BufLen %lu, Got %lu\n",
 					fbh->field_num+1, "SKIPPED", (unsigned long)loblen,
 					(unsigned long)imp_sth->long_readlen, (unsigned long)buflen,
 					(unsigned long)amtp);
 	}
 
 	if (dbis->debug >= 3 || dbd_verbose >= 3 )
-		PerlIO_printf(DBILOGFP, "	blob_read field %d, ftype %d, offset %ld, len %ld, destoffset %ld, retlen %lu\n",
+		PerlIO_printf(DBILOGFP, " y	blob_read field %d, ftype %d, offset %ld, len %ld, destoffset %ld, retlen %lu\n",
 			fbh->field_num+1, ftype, offset, len, destoffset, ul_t(amtp));
 
 	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;
@@ -1295,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,
@@ -1323,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";
 
 	/*
@@ -1343,7 +1714,7 @@
 	/* 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);
@@ -1358,7 +1729,7 @@
 		buflen = amtp;
 	}
 
-	if (DBIS->debug >= 3 || dbd_verbose >= 3 )
+	if (DBIS->debug >= 3 || dbd_verbose <= 3 )
 		PerlIO_printf(DBILOGFP,
 		"		blob_read field %d: ftype %d %s, offset %ld, len %lu."
 				"LOB csform %d, len %lu, amtp %lu, (destoffset=%ld)\n",
@@ -1373,24 +1744,24 @@
 			&amtp, (ub4)1 + offset, bufp, buflen,
 			0, 0, (ub2)0 , csform, status);
 
-		if (DBIS->debug >= 3 || dbd_verbose >= 3 )
+		if (DBIS->debug >= 3 || dbd_verbose <= 3 )
 			PerlIO_printf(DBILOGFP,
-			"		OCILobRead field %d %s: LOBlen %lu, LongReadLen %lu, BufLen %lu, amtp %lu\n",
+			"	\ns	OCILobRead field %d %s: LOBlen %lu, LongReadLen %lu, BufLen %lu, amtp %lu\n",
 				fbh->field_num+1, oci_status_name(status), ul_t(loblen),
 				ul_t(imp_sth->long_readlen), ul_t(buflen), ul_t(amtp));
 		if (status != OCI_SUCCESS) {
-			oci_error(sth, imp_sth->errhp, status, "OCILobRead");
+			oci_error(sth, imp_sth->errhp, status, " test OCILobRead");
 			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 {
 		assert(amtp == 0);
-		if (DBIS->debug >= 3 || dbd_verbose >= 3 )
+		if (DBIS->debug >= 3 || dbd_verbose <= 3 )
 			PerlIO_printf(DBILOGFP,
-				"		OCILobRead field %d %s: LOBlen %lu, LongReadLen %lu, BufLen %lu, Got %lu\n",
+				"	\nd	OCILobRead field %d %s: LOBlen %lu, LongReadLen %lu, BufLen %lu, Got %lu\n",
 				fbh->field_num+1, "SKIPPED", ul_t(loblen),
 				ul_t(imp_sth->long_readlen), ul_t(buflen), ul_t(amtp));
 	}
@@ -1418,19 +1789,30 @@
 	int loblen_is_chars;
 	sword status;
 
+
+
+
+/*	OCILobCharSetId_log_stat( imp_sth->envhp, imp_sth->errhp, lobloc, &csid, status );
+
+	OCINlsCharSetIdToName(imp_sth->envhp,charsetname, sizeof(charsetname),csid );
+*/
 	if (!name)
 		name = "an unknown field";
 
 	/* 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 no matter what the csform and csid setting	*/
+
 	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;
 	}
-	loblen_is_chars = (ftype == 112);
+
+	loblen_is_chars = (ftype == ORA_CLOB);
+
 
 	if (loblen > imp_sth->long_readlen) {	/* LOB will be truncated */
 		int oraperl = DBIc_COMPAT(imp_sth);
@@ -1439,6 +1821,7 @@
 
 		/* move setting amtp up to ensure error message OK */
 		amtp = imp_sth->long_readlen;
+
 		if (DBIc_has(imp_sth,DBIcf_LongTruncOk) || (oraperl && SvIV(imp_drh -> ora_trunc))) {
 			/* user says truncation is ok */
 			/* Oraperl recorded the truncation in ora_errno so we	*/
@@ -1455,10 +1838,11 @@
 			return 0;
 		}
 	}
-	else
+	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
@@ -1469,72 +1853,117 @@
 	to sort it out.)
 	Whatever is done here, similar changes are probably needed for the
 	ora_lob_*() methods when handling CLOBs.
+
+	Well I did much more research on this and yes you are right you did break it sort of.
+	Seems that to the DB everything is saved in the DBs native format
+	ie AL16UTF16 for Nclobs and AL32UTF8 for clobs and for a client (enviornment) with the same
+	values amtp is in chars and works nicely.  When there are  client (enviornment) setting that are
+	different then that is when onse sees amtp comming back in bytes so we have to convert over from the DB
+	to local NLS_LANG so we have to increase the size of the buffer accordaly
 	*/
 
-	/* 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 */
+
+	/* set char vs bytes and get right semantics for OCILobRead*/
+
+    buflen=amtp;
+
+  /*  if (ftype == ORA_CLOB){/*only happens with clobs
+		ub2 lob_csid=0;
+		OCILobCharSetId_log_stat( imp_sth->envhp, imp_sth->errhp, lobloc, &lob_csid, status );
+
+		if (status != OCI_SUCCESS) {
+			oci_error(sth, imp_sth->errhp, status, "OCILobCharSetId fetch_lob");
+		 	return 0;
 		}
-		else buflen = amtp;
 
-		SvGROW(dest_sv, buflen+1);
+PerlIO_printf(DBILOGFP," lob_csid=%d\n",lob_csid);
+PerlIO_printf(DBILOGFP,"  charsetid=%d \n",charsetid);
 
-		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;
-			}
+		if (lob_csid!=charsetid  ){
+	     	buflen =sizeof(utext)*buflen;
+		}
 
-		if (ftype == 114) {
-			OCILobFileOpen_log_stat(imp_sth->svchp, imp_sth->errhp, lobloc,
-					(ub1)OCI_FILE_READONLY, status);
-			if (status != OCI_SUCCESS) {
+    }
+
+	/*if (loblen_is_chars) {
+		buflen = (STRLEN) amtp;/* * 4;  /* XXX bit of a hack, efective but wasteful*/
+/*	}
+	else
+		buflen = amtp;
+if
+
+buflen =sizeof(utext)*buflen;
+*/
+
+/*if (csform==2){*/
+	/*buflen =sizeof(utext)*buflen;
+
+PerlIO_printf(DBILOGFP,"amtp=%d buflen=%d\n",amtp,buflen);
+
+*/
+buflen =sizeof(utext)*buflen;
+	SvGROW(dest_sv, (STRLEN) 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;
+		}
+
+	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, "OCILobFileOpen");
 			sv_set_undef(dest_sv);
 			return 0;
-			}
 		}
+	}
+
 
-		OCILobRead_log_stat(imp_sth->svchp, imp_sth->errhp, lobloc,
+	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, LOBlen %luc, LongReadLen %luc, BufLen %lub, Got %luc\n",
-				name, oci_status_name(status), csform, ul_t(loblen),
+
+
+	if (DBIS->debug >= 3 || dbd_verbose <= 3 )
+		PerlIO_printf(DBILOGFP,
+			"		OCILobRead %s %s: csform %d (%s), LOBlen %luc, LongReadLen %luc, BufLen %lub, Got (amtp)%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 (status != OCI_SUCCESS) {
-			oci_error(sth, imp_sth->errhp, status, "OCILobRead");
-			sv_set_undef(dest_sv);
-			return 0;
-		}
+	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, " mehd OCILobRead");
+		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",
+		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));
-		}
+	 			ul_t(imp_sth->long_readlen), ul_t(buflen), ul_t(amtp));
+	}
 
 	SvPOK_on(dest_sv);
 
@@ -1546,7 +1975,7 @@
 {
 	dTHX;
 	char name[64];
-	sprintf(name, "field %d of %d", fbh->field_num, DBIc_NUM_FIELDS(fbh->imp_sth));
+	sprintf(name, "field sss %d of %d", fbh->field_num, DBIc_NUM_FIELDS(fbh->imp_sth));
 	return fetch_lob(sth, fbh->imp_sth, (OCILobLocator*)fbh->desc_h, fbh->ftype, dest_sv, name);
 }
 
@@ -1566,7 +1995,7 @@
 fbh_setup_getrefpv(imp_fbh_t *fbh, int desc_t, char *bless)
 {
 	dTHX;
-	if (DBIS->debug >= 2 || dbd_verbose >= 3 )
+	if (DBIS->debug >= 2 || dbd_verbose <= 3 )
 	PerlIO_printf(DBILOGFP,
 		"	col %d: otype %d, desctype %d, %s", fbh->field_num, fbh->dbtype, desc_t, bless);
 	fbh->ftype  = fbh->dbtype;
@@ -1580,33 +2009,45 @@
 
 
 static int
-calc_cache_rows(int cache_rows, int num_fields, int est_width, int has_longs)
+calc_cache_rows(int cache_rows, int num_fields, int est_width, int has_longs,ub4 prefetch_memory)
 {
 	dTHX;
-	if (has_longs)			/* override/disable caching	*/
+	/* Use guessed average on-the-wire row width calculated above &	*/
+	/* add in overhead of 5 bytes per field plus 8 bytes per row.	*/
+	/* The n*5+8 was determined by studying SQL*Net v2 packets.	*/
+	/* It could probably benefit from a more detailed analysis.	*/
+
+	est_width += num_fields*5 + 8;
+
+	if (has_longs) {			/* override/disable caching	*/
 		cache_rows = 1;		/* else read_blob can't work	*/
-	else
+	}
+	else if (prefetch_memory) { /*set rows by memory*/
+
+		cache_rows=prefetch_memory/est_width;
+	}
+	else{
 		if (cache_rows == 0) {		/* automatically size the cache	*/
+		/* automatically size the cache	*/
 
-			/* Oracle packets on ethernet have max size of around 1460.	*/
-			/* We'll aim to fill our row cache with around 10 per go.	*/
-			/* Using 10 means any 'runt' packets will have less impact.	*/
-			int txfr_size  = 10 * 1460;	/* desired transfer/cache size	*/
-
-			/* Use guessed average on-the-wire row width calculated above &	*/
-			/* add in overhead of 5 bytes per field plus 8 bytes per row.	*/
-			/* The n*5+8 was determined by studying SQL*Net v2 packets.	*/
-			/* It could probably benefit from a more detailed analysis.	*/
-			est_width += num_fields*5 + 8;
-
-			cache_rows = txfr_size / est_width;		  /* (maybe 1 or 0)	*/
-
-			/* To ensure good performance with large rows (near or larger	*/
-			/* than our target transfer size) we set a minimum cache size.	*/
-			if (cache_rows < 6)	/* is cache a 'useful' size?	*/
-				cache_rows = (cache_rows > 0) ? 6 : 4;
+		/* Oracle packets on ethernet have max size of around 1460.	*/
+		/* We'll aim to fill our row cache with around 10 per go.	*/
+		/* 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	*/
+
+		cache_rows = txfr_size / est_width;		  /* (maybe 1 or 0)	*/
+
+		/* To ensure good performance with large rows (near or larger	*/
+		/* than our target transfer size) we set a minimum cache size.	*/
+		/* I made them all at least 10* what they were before this */
+		/* main reasoning this old value reprewneted a norm in the oralce 7~8 */
+		/* 9 to 11 can handel much much more */
+		if (cache_rows < 60)	/* is cache a 'useful' size?	*/
+			cache_rows = (cache_rows > 0) ? 60 : 40;
 		}
-
+	}
 	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*/
 
@@ -1776,7 +2217,7 @@
 /*gets the properties of an object from a fetch by using the attributes saved in the describe */
 
 int
-get_object (SV *sth, AV *list, imp_fbh_t *fbh,fbh_obj_t *base_obj,OCIComplexObject *value){
+get_object (SV *sth, AV *list, imp_fbh_t *fbh,fbh_obj_t *base_obj,OCIComplexObject *value, OCIType *instance_tdo){
 
 	dTHX;
 	sword 		status;
@@ -1785,13 +2226,14 @@
 	boolean		eoc;
 	ub2	 		pos;
 	dvoid 		*attr_null_struct;
-	OCIInd 		attr_null_status;
-	OCIInd 		*element_null;
+	OCIInd		attr_null_status;
+	OCIInd		*element_null;
 	OCIType 	*attr_tdo;
-	OCIIter	*itr;
+	OCIIter		*itr;
 	fbh_obj_t	*fld;
 	OCIInd		*obj_ind;
 	fbh_obj_t	*obj = base_obj;
+	 OCIType	*tdo = instance_tdo ? instance_tdo : obj->tdo;
 
 	if (DBIS->debug >= 5 || dbd_verbose >= 5 ) {
 		PerlIO_printf(DBILOGFP, " getting attributes of object named  %s with typecode=%s\n",obj->type_name,oci_typecode_name(obj->typecode));
@@ -1805,30 +2247,31 @@
 
 				OCIRef	*type_ref=0;
 				sword	status;
-				OCIType *tdo;
-
-				status = OCIObjectNew(fbh->imp_sth->envhp, fbh->imp_sth->errhp, fbh->imp_sth->svchp,
-													OCI_TYPECODE_REF, (OCIType *)0,
-													(dvoid *)0, OCI_DURATION_DEFAULT, TRUE,
-													(dvoid **) &type_ref);
-				if (status != OCI_SUCCESS) {
-					oci_error(sth, fbh->imp_sth->errhp, status, "OCIObjectNew");
-					return 0;
-				}
+				if (!instance_tdo) {
+					status = OCIObjectNew(fbh->imp_sth->envhp, fbh->imp_sth->errhp, fbh->imp_sth->svchp,
+											OCI_TYPECODE_REF, (OCIType *)0,
+											(dvoid *)0, OCI_DURATION_DEFAULT, TRUE,
+											(dvoid **) &type_ref);
+					if (status != OCI_SUCCESS) {
+						oci_error(sth, fbh->imp_sth->errhp, status, "OCIObjectNew");
+						return 0;
+					}
 
-				status=OCIObjectGetTypeRef(fbh->imp_sth->envhp,fbh->imp_sth->errhp, (dvoid*)fbh->obj->obj_value, type_ref);
-				if (status != OCI_SUCCESS) {
-					oci_error(sth, fbh->imp_sth->errhp, status, "OCIObjectGetTypeRef");
-					return 0;
-				}
+					status=OCIObjectGetTypeRef(fbh->imp_sth->envhp,fbh->imp_sth->errhp, (dvoid*)value, type_ref);
+					if (status != OCI_SUCCESS) {
+						oci_error(sth, fbh->imp_sth->errhp, status, "OCIObjectGetTypeRef");
+						return 0;
+					}
 
-				OCITypeByRef_log_stat(fbh->imp_sth->envhp,fbh->imp_sth->errhp,type_ref,&tdo,status);
+					OCITypeByRef_log_stat(fbh->imp_sth->envhp,fbh->imp_sth->errhp,type_ref,&tdo,status);
 
-				if (status != OCI_SUCCESS) {
-					oci_error(sth, fbh->imp_sth->errhp, status, "OCITypeByRef");
-					return 0;
+					if (status != OCI_SUCCESS) {
+						oci_error(sth, fbh->imp_sth->errhp, status, "OCITypeByRef");
+						return 0;
+					}
 				}
 
+
 				if (tdo != obj->tdo) {
 					/* this is subtype -> search for subtype obj */
 					while (obj->next_subtype && tdo != obj->tdo) {
@@ -1837,7 +2280,7 @@
 					if (tdo != obj->tdo) {
 						/* new subtyped -> get obj description */
 						if (DBIS->debug >= 5 || dbd_verbose >= 5 ) {
-							PerlIO_printf(DBILOGFP, " describe subtype of object type %s\n",base_obj->type_name);
+							PerlIO_printf(DBILOGFP, " describe subtype (tdo=%x) of object type %s (tdo=%x)\n",(int)tdo,base_obj->type_name,(int)base_obj->tdo);
 						}
 
 						Newz(1, obj->next_subtype, 1, fbh_obj_t);
@@ -1907,7 +2350,7 @@
 				}
 
 				status = OCIObjectGetAttr(fbh->imp_sth->envhp, fbh->imp_sth->errhp, value,
-										obj_ind, obj->tdo,
+										obj_ind, tdo,
 										(CONST oratext**)&fld->type_name, &fld->type_namel, 1,
 										(ub4 *)0, 0, &attr_null_status, &attr_null_struct,
 										&attr_value, &attr_tdo);
@@ -1926,7 +2369,7 @@
 						if (fld->typecode != OCI_TYPECODE_OBJECT)
 							attr_value = *(dvoid **)attr_value;
 
-						get_object (sth,fld->fields[0].value, fbh, &fld->fields[0],attr_value);
+						get_object (sth,fld->fields[0].value, fbh, &fld->fields[0],attr_value, attr_tdo);
 						av_push(list, new_ora_object(fld->fields[0].value, fld->typecode));
 
 					} else{  /* else, display the scaler type attribute */
@@ -1967,7 +2410,7 @@
 						} else {
 							if (obj->element_typecode == OCI_TYPECODE_OBJECT || obj->element_typecode == OCI_TYPECODE_VARRAY || obj->element_typecode== OCI_TYPECODE_TABLE || obj->element_typecode== OCI_TYPECODE_NAMEDCOLLECTION){
 								fld->value = newAV();
-								get_object (sth,fld->value, fbh, fld,element);
+								get_object (sth,fld->value, fbh, fld,element,0);
 								av_push(list, new_ora_object(fld->value, obj->element_typecode));
 							} else{  /* else, display the scaler type attribute */
 								get_attr_val(sth,list, fbh, obj->type_name, obj->element_typecode, element);
@@ -2018,7 +2461,7 @@
 	fbh->obj->value=newAV();
 
 	/*will return referance to an array of scalars*/
-	if (!get_object(sth,fbh->obj->value,fbh,fbh->obj,fbh->obj->obj_value)){
+	if (!get_object(sth,fbh->obj->value,fbh,fbh->obj,fbh->obj->obj_value,0)){
 		return 0;
 	} else {
 		sv_setsv(dest_sv, sv_2mortal(new_ora_object(fbh->obj->value, fbh->obj->typecode)));
@@ -2251,41 +2694,78 @@
 void rs_array_init(imp_sth_t *imp_sth)
 {
 	dTHX;
-	if (imp_sth->rs_array_on!=1		||
+/*	if (imp_sth->rs_array_on!=1		||
 		imp_sth->rs_array_size<1	||
 		imp_sth->rs_array_size>128){
 
 		imp_sth->rs_array_on=0;
 		imp_sth->rs_array_size=1;
 
-	}
-	imp_sth->rs_array_num_rows=0;
-	imp_sth->rs_array_idx=0;
-	imp_sth->rs_array_status=OCI_SUCCESS;
+	}*/
+	imp_sth->rs_array_num_rows	=0;
+	imp_sth->rs_array_idx		=0;
+	imp_sth->rs_fetch_count		=0;
+	/*imp_sth->prefetch_rows		=0;
+	imp_sth->prefetch_memory	=0;*/
+	imp_sth->rs_array_status	=OCI_SUCCESS;
+
 	if (DBIS->debug >= 3 || dbd_verbose >= 3 )
-		PerlIO_printf(DBILOGFP, "	rs_array_init: rs_array_on=%d, rs_array_size=%d\n",imp_sth->rs_array_on,imp_sth->rs_array_size);
+		PerlIO_printf(DBILOGFP, "	rs_array_init:imp_sth->rs_array_size=%d, rs_array_idx=%d, prefetch_rows=%d, rs_array_status=%s\n",imp_sth->rs_array_size,imp_sth->rs_array_idx,imp_sth->prefetch_rows,oci_status_name(imp_sth->rs_array_status));
 }
 
 
-static int			/* --- Setup the row cache for this sth --- */
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*static int			/* --- Setup the row cache for this sth --- */
 sth_set_row_cache(SV *h, imp_sth_t *imp_sth, int max_cache_rows, int num_fields, int has_longs)
 {
 	dTHX;
 	D_imp_dbh_from_sth;
 	D_imp_drh_from_dbh;
-	int num_errors	= 0;
-	ub4 cache_mem	= 0;
-	sb4 cache_rows	= 10000;/* set high so memory is the limit */
+	int num_errors		= 0;
+	ub4 prefetch_mem	= 0; /*Oracle prefetch memory buffer*/
+	sb4 prefetch_rows	= 0; /*Oracle prefetch Row Buffer*/
+	sb4 cache_rows		= 0;/* set high so memory is the limit */
 	sword status;
 
-	/* reworked this is little so the user can set up his own cache
-	  basically if rowcachesize or prefetch_mem is set it uses those values
-	  otherwise it does it itself
-	  no sure what happens in the last case but I lwft it in for now
-	  Also I think in later version of OCI this call does not really do anything
-	*/
+	if (imp_dbh->RowCacheSize){
+	  cache_rows=imp_dbh->RowCacheSize;
+	}
+
+	/* seems that RowCacheSize was incorrectly used in the past
+	   in the DBI Spect  RowCacheSize is to be used for a local row cache
+
+	   From DBI POD
+	      A hint to the driver indicating the size of the local
+	      row cache that the application would like the driver to
+	      use for future SELECT statements.
+
+	   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
+	   one record at a time from the fetch this means a round trip (at least to the local cache)
+	   at each fetch.
+
+	   With the new array fetch we truly have a local cache so I will use it
+	   RowCacheSize to set the value of that cache or the array fetch*/
+
+
+
+	/* number of rows to cache	 if using oraperl  will leave this in for now*/
+
 
-	/* number of rows to cache	 if using oraperl */
 	if (SvOK(imp_drh->ora_cache_o)){
 		imp_sth->cache_rows = SvIV(imp_drh->ora_cache_o);
 	}
@@ -2293,51 +2773,52 @@
 		imp_sth->cache_rows = SvIV(imp_drh->ora_cache);
 	}
 
-	if (imp_sth->is_child  && imp_sth->ret_lobs){ /*ref cursors and sp only one row is allowed*/
-		cache_rows  =1;
-		cache_mem  =0;
-
-	} else if (imp_dbh->RowCacheSize || imp_sth->prefetch_memory){
-	/*user set values */
-		 cache_rows  =imp_dbh->RowCacheSize;
-		 cache_mem	=imp_sth->prefetch_memory;
-
-	} else if (imp_sth->cache_rows >= 0) {	/* set cache size by row count	*/
+	if (imp_dbh->RowCacheSize){ /* defalut value*/
+	  cache_rows=imp_dbh->RowCacheSize;
+	}
 
-		/* imp_sth->est_width needs to be set */
-		cache_mem  = 0;			 /* so memory isn't the limit */
+	prefetch_rows	=imp_sth->prefetch_rows;
+	prefetch_mem	=imp_sth->prefetch_memory;
 
-		cache_rows = calc_cache_rows(imp_sth->cache_rows,(int)num_fields, imp_sth->est_width, has_longs);
 
-		if (max_cache_rows && cache_rows > (signed long) max_cache_rows)
-			cache_rows = max_cache_rows;
+	if (!cache_rows) { /*start with this value if not set then set default cache */
 
-		imp_sth->cache_rows = cache_rows;	/* record updated value */
+		cache_rows=calc_cache_rows(imp_sth->cache_rows,(int)num_fields, imp_sth->est_width, has_longs,0);
 
-	}
-	else {				/* set cache size by memory	*/
-						/* not sure if we ever reach this*/
-		cache_mem  = -imp_sth->cache_rows; /* cache_mem always +ve here */
-		if (max_cache_rows &&  cache_rows > (signed long) max_cache_rows) {
-			cache_rows = max_cache_rows;
-			imp_sth->cache_rows = cache_rows;	/* record updated value only if max_cache_rows */
+		if(!prefetch_rows && !prefetch_mem){ /*if there are not prefetch rows make sure I set it here to the default*/
+			  prefetch_rows=cache_rows;
 		}
+	}
+	else if (imp_dbh->RowCacheSize < 0) {/* for compaibility with DBI doc negitive value here means use the value as memory*/
+		prefetch_mem	=-imp_dbh->RowCacheSize; /* cache_mem always +ve here */
+		prefetch_rows	=0;
+		cache_rows=calc_cache_rows(imp_sth->cache_rows,(int)num_fields, imp_sth->est_width, has_longs,prefetch_mem);
+		/*The above fucntion will set the cache_rows using memory as the limit*/
+	}
+	else {
 
+	   if (!prefetch_mem){
+			prefetch_rows = cache_rows; /*use the RowCacheSize*/
+	   }
 	}
 
+	if (cache_rows <= prefetch_rows){
+		cache_rows=prefetch_rows;
+		/* is prefetch_rows are greater than the RowCahceSize then use prefetch_rows*/
+	}
 
 	OCIAttrSet_log_stat(imp_sth->stmhp, OCI_HTYPE_STMT,
-						&cache_mem,  sizeof(cache_mem), OCI_ATTR_PREFETCH_MEMORY,
+						&prefetch_mem,  sizeof(prefetch_mem), OCI_ATTR_PREFETCH_MEMORY,
 						imp_sth->errhp, status);
 
 	if (status != OCI_SUCCESS) {
 		oci_error(h, imp_sth->errhp, status,
-				"OCIAttrSet OCI_ATTR_PREFETCH_ROWS/OCI_ATTR_PREFETCH_MEMORY");
+				"OCIAttrSet OCI_ATTR_PREFETCH_MEMORY");
 		++num_errors;
 	}
 
 	OCIAttrSet_log_stat(imp_sth->stmhp, OCI_HTYPE_STMT,
-					&cache_rows, sizeof(cache_rows), OCI_ATTR_PREFETCH_ROWS,
+					&prefetch_rows, sizeof(prefetch_rows), OCI_ATTR_PREFETCH_ROWS,
 				imp_sth->errhp, status);
 
 	if (status != OCI_SUCCESS) {
@@ -2345,13 +2826,33 @@
 		++num_errors;
 	}
 
-	if (imp_sth->rs_array_on && cache_rows>0)
-		imp_sth->rs_array_size=cache_rows>128?128:cache_rows;	/* restrict to 128 for now */
+/*    if (imp_sth->ret_lobs){
+		cache_rows=30;
 
-	if (DBIS->debug >= 3 || dbd_verbose >= 3 )
+	}
+*/
+	imp_sth->rs_array_size=cache_rows;
+
+    if (max_cache_rows){/* limited by a cursor or something else*/
+		imp_sth->rs_array_size=max_cache_rows;
+	}
+
+
+/*	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*/
 		PerlIO_printf(DBILOGFP,
-			"	row cache OCI_ATTR_PREFETCH_ROWS %lu, OCI_ATTR_PREFETCH_MEMORY %lu\n",
-			(unsigned long) (cache_rows), (unsigned long) (cache_mem));
+			"	cache settings RowCacheSize=%d, OCI_ATTR_PREFETCH_ROWS=%lu, OCI_ATTR_PREFETCH_MEMORY=%lu, Rows per Fetch=%d, Multiple Row Fetch=%s\n",
+			imp_dbh->RowCacheSize,(unsigned long) (prefetch_rows), (unsigned long) (prefetch_mem),cache_rows,(imp_sth->row_cache_off)?"Off":"On");
+
+
 
 	return num_errors;
 }
@@ -2359,7 +2860,6 @@
 
 
 /*recurses down the field's TDOs and saves the little bits it need for later use on a fetch fbh->obj */
-
 int
 describe_obj(SV *sth,imp_sth_t *imp_sth,OCIParam *parm,fbh_obj_t *obj,int level )
 {
@@ -2614,9 +3114,10 @@
 	D_imp_drh_from_dbh;
 	UV	long_readlen;
 	ub4 num_fields;
-	int num_errors = 0;
-	int has_longs = 0;
-	int est_width = 0;		/* estimated avg row width (for cache)	*/
+	int num_errors	= 0;
+	int has_longs	= 0;
+	int has_lobs	= 0;
+	int est_width	= 0;		/* estimated avg row width (for cache)	*/
 	int nested_cursors = 0;
 	ub4 i = 0;
 	sword status;
@@ -2636,6 +3137,7 @@
 	/* set long_readlen for SELECT or PL/SQL with output placeholders */
 	imp_sth->long_readlen = long_readlen;
 
+
 	if (imp_sth->stmt_type != OCI_STMT_SELECT) { /* XXX DISABLED, see num_fields test below */
 		if (DBIS->debug >= 3 || dbd_verbose >= 3 )
 			PerlIO_printf(DBILOGFP, "	dbd_describe skipped for %s\n",
@@ -2712,6 +3214,7 @@
 #endif
 		fbh->csid = 0; fbh->csform = 0; /* just to be sure */
 #ifdef OCI_ATTR_CHARSET_ID
+
 		OCIAttrGet_parmdp(imp_sth, fbh->parmdp, &fbh->csid,	0, OCI_ATTR_CHARSET_ID,	status);
 		OCIAttrGet_parmdp(imp_sth, fbh->parmdp, &fbh->csform, 0, OCI_ATTR_CHARSET_FORM, status);
 #endif
@@ -2720,6 +3223,8 @@
 		OCIAttrGet_parmdp(imp_sth, fbh->parmdp, &fbh->scale,  0, OCI_ATTR_SCALE,	 status);
 		OCIAttrGet_parmdp(imp_sth, fbh->parmdp, &fbh->nullok, 0, OCI_ATTR_IS_NULL,	status);
 		OCIAttrGet_parmdp(imp_sth, fbh->parmdp, &fbh->name,	&atrlen, OCI_ATTR_NAME,status);
+
+
 		if (atrlen == 0) { /* long names can cause oracle to return 0 for atrlen */
 			char buf[99];
 			sprintf(buf,"field_%d_name_too_long", i);
@@ -2730,14 +3235,14 @@
 		fbh->name	= SvPVX(fbh->name_sv);
 		fbh->ftype	= 5;	/* default: return as null terminated string */
 
-		if (DBIS->debug >= 4 || dbd_verbose >= 4 )
-			PerlIO_printf(DBILOGFP, "Describe col #%d type=%d(%s)\n",i,fbh->dbtype,sql_typecode_name(fbh->dbtype));
+		if (DBIS->debug >= 4 || dbd_verbose <= 4 )
+			PerlIO_printf(DBILOGFP, "Describe col #%d type=%d(%s) \n",i,fbh->dbtype,sql_typecode_name(fbh->dbtype));
 
 		switch (fbh->dbtype) {
 		/*	the simple types	*/
 			case	ORA_VARCHAR2:				/* VARCHAR2	*/
 
-				if (fbh->dbsize == 0){  
+				if (fbh->dbsize == 0){
 					fbh->dbsize=4000;
 				}
 				avg_width = fbh->dbsize / 2;
@@ -2790,11 +3295,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;
@@ -2875,16 +3380,21 @@
 					}
 				}
 				break;
-			case	ORA_CLOB:				/* CLOB	& NCLOB	*/
-			case	ORA_BLOB:				/* BLOB		*/
-			case	114:				/* BFILE	*/
-				fbh->ftype  = fbh->dbtype;
+			case	ORA_CLOB:			/* CLOB	& NCLOB	*/
+			case	ORA_BLOB:			/* BLOB		*/
+			case	ORA_BFILE:				/* BFILE	*/
+				fbh->ftype  	  = fbh->dbtype;
 				imp_sth->ret_lobs = 1;
 				/* do we need some addition size logic here? (lab) */
 
 				if (imp_sth->pers_lob){  /*get as one peice fasted but limited to how big you can get.*/
 					fbh->pers_lob	= 1;
-					fbh->disize 	= fbh->disize+long_readlen; /*user set max value for the fetch*/
+					if (long_readlen){
+						fbh->disize 	= fbh->disize*10; /*default size*/
+					}
+					else {
+						fbh->disize 	= long_readlen;/*user set max value for the fetch*/
+					}
 					if (fbh->dbtype == ORA_CLOB){
 						fbh->ftype  = SQLT_CHR;
 					}
@@ -2907,6 +3417,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;
@@ -2924,6 +3435,7 @@
 						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! */
@@ -2931,8 +3443,12 @@
 					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
@@ -2951,9 +3467,12 @@
 
 			case	182:				  /* INTERVAL YEAR TO MONTH */
 			case	183:				  /* INTERVAL DAY TO SECOND */
-			case	190:				  /* INTERVAL DAY TO SECOND */
+			case	185:				  /* TIME (ocidfn.h) */
+			case	186:				  /* TIME WITH TIME ZONE (ocidfn.h) */
 			case	187:				  /* TIMESTAMP */
 			case	188: 				/* TIMESTAMP WITH TIME ZONE	*/
+			case	189:				  /* INTERVAL YEAR TO MONTH (ocidfn.h) */
+ 			case	190:				  /* INTERVAL DAY TO SECOND */
 			case	232:				  /* TIMESTAMP WITH LOCAL TIME ZONE */
 				/* actually dependent on NLS default date format*/
 					fbh->disize = 75;		/* XXX */
@@ -2971,12 +3490,12 @@
 				break;
 		}
 
-		if (DBIS->debug >= 3 || dbd_verbose >= 3 )
+		if (DBIS->debug >= 3 || dbd_verbose <= 3 )
 			  PerlIO_printf(DBILOGFP,
 				"Described col %2d: dbtype %d(%s), scale %d, prec %d, nullok %d, name %s\n"
-				 "		  : dbsize %d, char_used %d, char_size %d, csid %d, csform %d, disize %d\n",
+				 "		  : dbsize %d, char_used %d, char_size %d, csid %d, csform %d(%s), disize %d\n",
 					i, fbh->dbtype, sql_typecode_name(fbh->dbtype),fbh->scale, fbh->prec, fbh->nullok, fbh->name,
-					fbh->dbsize, fbh->len_char_used, fbh->len_char_size, fbh->csid, fbh->csform, fbh->disize);
+					fbh->dbsize, fbh->len_char_used, fbh->len_char_size, fbh->csid,fbh->csform,oci_csform_name(fbh->csform), fbh->disize);
 
 		if (fbh->ftype == 5)	/* XXX need to handle wide chars somehow */
 			fbh->disize += 1;	/* allow for null terminator */
@@ -2998,12 +3517,14 @@
 	imp_sth->est_width = est_width;
 
 	sth_set_row_cache(h, imp_sth,
-			(nested_cursors) ? imp_dbh->max_nested_cursors / nested_cursors : 0,
+			(imp_dbh->max_nested_cursors) ? 0 :nested_cursors ,
 			(int)num_fields, has_longs );
 	/* Initialise cache counters */
 	imp_sth->in_cache  = 0;
 	imp_sth->eod_errno = 0;
-	rs_array_init(imp_sth);
+	/*rs_array_init(imp_sth);*/
+
+
 
 	/* now set up the oci call with define by pos*/
 	for(i=1; i <= num_fields; ++i) {
@@ -3017,7 +3538,7 @@
 			fbh->fb_ary = fb_ary_cb_alloc(imp_sth->piece_size,define_len, imp_sth->rs_array_size);
 
 		} else {
-				fbh->fb_ary = fb_ary_alloc(define_len, imp_sth->rs_array_size);
+			fbh->fb_ary = fb_ary_alloc(define_len, imp_sth->rs_array_size);
 		}
 
 		fb_ary = fbh->fb_ary;
@@ -3084,7 +3605,7 @@
 		if ( (fbh->dbtype == 1) && fbh->csform ) {
 		/* csform may be 0 when talking to Oracle 8.0 database*/
 			if (DBIS->debug >= 3 || dbd_verbose >= 3 )
-				PerlIO_printf(DBILOGFP, "	calling OCIAttrSet OCI_ATTR_CHARSET_FORM with csform=%d\n", fbh->csform );
+				PerlIO_printf(DBILOGFP, "	calling OCIAttrSet OCI_ATTR_CHARSET_FORM with csform=%d (%s)\n", fbh->csform,oci_csform_name(fbh->csform) );
 				OCIAttrSet_log_stat( fbh->defnp, (ub4) OCI_HTYPE_DEFINE, (dvoid *) &fbh->csform,
 						 (ub4) 0, (ub4) OCI_ATTR_CHARSET_FORM, imp_sth->errhp, status );
 			if (status != OCI_SUCCESS) {
@@ -3099,7 +3620,7 @@
 	if (DBIS->debug >= 3 || dbd_verbose >= 3 )
 		PerlIO_printf(DBILOGFP,
 			"	dbd_describe'd %d columns (row bytes: %d max, %d est avg, cache: %d)\n",
-			(int)num_fields, imp_sth->t_dbsize, imp_sth->est_width, imp_sth->cache_rows);
+			(int)num_fields, imp_sth->t_dbsize, imp_sth->est_width, imp_sth->prefetch_rows);
 
 	return (num_errors>0) ? 0 : 1;
 }
@@ -3109,6 +3630,7 @@
 dbd_st_fetch(SV *sth, imp_sth_t *imp_sth){
 	dTHX;
 	sword status;
+	D_imp_dbh_from_sth;
 	int num_fields = DBIc_NUM_FIELDS(imp_sth);
 	int ChopBlanks;
 	int err;
@@ -3144,11 +3666,12 @@
 		if (imp_sth->fetch_orient != OCI_DEFAULT) {
 			if (imp_sth->exe_mode!=OCI_STMT_SCROLLABLE_READONLY)
 				croak ("attempt to use a scrollable cursor without first setting ora_exe_mode to OCI_STMT_SCROLLABLE_READONLY\n") ;
+
 			if (DBIS->debug >= 4 || dbd_verbose >= 4 )
 				PerlIO_printf(DBILOGFP,"	Scrolling Fetch, postion before fetch=%d, Orientation = %s , Fetchoffset =%d\n",
 					imp_sth->fetch_position,oci_fetch_options(imp_sth->fetch_orient),imp_sth->fetch_offset);
-			OCIStmtFetch_log_stat(imp_sth->stmhp, imp_sth->errhp,1, imp_sth->fetch_orient,imp_sth->fetch_offset, status);
 
+			OCIStmtFetch_log_stat(imp_sth->stmhp, imp_sth->errhp,1, imp_sth->fetch_orient,imp_sth->fetch_offset, status);
 				/*this will work without a round trip so might as well open it up for all statments handles*/
 				/* defualt and OCI_FETCH_NEXT are the same so this avoids miscaluation on the next value*/
 			OCIAttrGet_stmhp_stat(imp_sth, &imp_sth->fetch_position, 0, OCI_ATTR_CURRENT_POSITION, status);
@@ -3156,27 +3679,44 @@
 			if (DBIS->debug >= 4 || dbd_verbose >= 4 )
 				PerlIO_printf(DBILOGFP,"	Scrolling Fetch, postion after fetch=%d\n",imp_sth->fetch_position);
 
-		} else {
-			if (imp_sth->rs_array_on) {	/* if array fetch on, fetch only if not in cache */
+		}
+		else {
+
+			if (imp_sth->row_cache_off){ /*Do not use array fetch or local cache */
+				OCIStmtFetch_log_stat(imp_sth->stmhp, imp_sth->errhp,1,(ub2)OCI_FETCH_NEXT, OCI_DEFAULT, status);
+				imp_sth->rs_fetch_count++;
+				imp_sth->rs_array_idx=0;
+
+			}
+			else {  /*Array Fetch the New Noraml Super speedy and very nice*/
+
+/* 			PerlIO_printf(DBILOGFP, "	dbd_st_fetch fields...a\n");*/
+				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);
+*/
 				if (imp_sth->rs_array_num_rows<=imp_sth->rs_array_idx && (imp_sth->rs_array_status==OCI_SUCCESS || imp_sth->rs_array_status==OCI_SUCCESS_WITH_INFO)) {
+/* 			PerlIO_printf(DBILOGFP, "	dbd_st_fetch fields...b\n");*/
+
 					OCIStmtFetch_log_stat(imp_sth->stmhp,imp_sth->errhp,imp_sth->rs_array_size,(ub2)OCI_FETCH_NEXT,OCI_DEFAULT,status);
 					imp_sth->rs_array_status=status;
+					imp_sth->rs_fetch_count++;
 					if (oci_warn &&  (imp_sth->rs_array_status == OCI_SUCCESS_WITH_INFO)) {
 						oci_error(sth, imp_sth->errhp, status, "OCIStmtFetch");
 					}
 					OCIAttrGet_stmhp_stat(imp_sth, &imp_sth->rs_array_num_rows,0,OCI_ATTR_ROWS_FETCHED, status);
 					imp_sth->rs_array_idx=0;
+					imp_dbh->RowsInCache =imp_sth->rs_array_size;
+					if (DBIS->debug >= 4 || dbd_verbose >= 4 || oci_warn)
+						PerlIO_printf(DBILOGFP,"...Fetched %d rows\n",imp_sth->rs_array_num_rows);
+
 				}
+
 				if (imp_sth->rs_array_num_rows>imp_sth->rs_array_idx)	/* set status to success if rows in cache */
 					status=OCI_SUCCESS;
 				else
 					status=imp_sth->rs_array_status;
 			}
-			else {
-				OCIStmtFetch_log_stat(imp_sth->stmhp, imp_sth->errhp,1,(ub2)OCI_FETCH_NEXT, OCI_DEFAULT, status);
-				imp_sth->rs_array_idx=0;
-			}
 		}
 	}
 
@@ -3186,8 +3726,8 @@
 		if (status == OCI_NO_DATA) {
 			dTHR; 			/* for DBIc_ACTIVE_off	*/
 			DBIc_ACTIVE_off(imp_sth);	/* eg finish		*/
-			if (DBIS->debug >= 3 || dbd_verbose >= 3 )
-				PerlIO_printf(DBILOGFP, "	dbd_st_fetch no-more-data\n");
+			if (DBIS->debug >= 3 || dbd_verbose >= 3 || oci_warn)
+				PerlIO_printf(DBILOGFP, "	dbd_st_fetch no-more-data, fetch count=%d\n",imp_sth->rs_fetch_count-1);
 			return Nullav;
 		}
 		if (status != OCI_SUCCESS_WITH_INFO) {
@@ -3221,6 +3761,7 @@
 		ub1* row_data		= &fb_ary->abuf[0]+(fb_ary->bufl*imp_sth->rs_array_idx);
 		SV *sv 				= AvARRAY(av)[i]; /* Note: we (re)use the SV in the AV	*/;
 
+
 		if (DBIS->debug >= 4 || dbd_verbose >= 4 ) {
 			PerlIO_printf(DBILOGFP, "	field #%d with rc=%d(%s)\n",i+1,rc,oci_col_return_codes(rc));
 		}
@@ -3399,7 +3940,7 @@
 	char *orig = src;
 	char *p;
 	while(*src){
-		if (*src == '\'' || *src == '"') {
+		if (*src == '\'') {
 			char delim = *src;
 			while(*src && *src != delim) ++src;
 		}
@@ -3412,7 +3953,7 @@
 		else if (isALPHA(*src)) {
 			if (seen_key) {
 				char *start = src;
-				while(*src && (isALNUM(*src) || *src=='.' || *src=='$'))
+				while(*src && (isALNUM(*src) || *src=='.' || *src=='$' || *src=='"'))
 					++src;
 				*len = src - start;
 				if (copy) {
@@ -3466,7 +4007,7 @@
 	ub2 numcols = 0;
 	imp_fbh_t *fbh;
 	int unmatched_params;
-	I32 i;
+	I32 i,j;
 	char *p;
 	lob_refetch_t *lr = NULL;
 	STRLEN tablename_len;
@@ -3646,7 +4187,7 @@
 
 		hv_iterinit(lob_cols_hv);
 
-		while( (sv = hv_iternextsv(lob_cols_hv, &p, &i)) != NULL ) {
+		while( (sv = hv_iternextsv(lob_cols_hv, &p, &j)) != NULL ) {
 			char sql_field[200];
 			if (phs->ora_field) {	/* must match this phs by field name	*/
 				char *ora_field_name = SvPV(phs->ora_field,na);
@@ -3676,12 +4217,12 @@
 					}
 				}
 			}
-			
+
 			matched = 1;
 			sprintf(sql_field, "%s%s \"%s\"",
 			(SvCUR(sql_select)>7)?", ":"", p, &phs->name[1]);
 			sv_catpv(sql_select, sql_field);
-			
+
 			if (DBIS->debug >= 3 || dbd_verbose >= 3 )
 				PerlIO_printf(DBILOGFP,
 				"		lob refetch %s param: otype %d, matched field '%s' %s(%s)\n",
@@ -3695,9 +4236,9 @@
 					fbh->disize = 99;
 					fbh->desc_t = OCI_DTYPE_LOB;
 					OCIDescriptorAlloc_ok(imp_sth->envhp, &fbh->desc_h, fbh->desc_t);
-				
+
 			break;	/* we're done with this placeholder now	*/
-			
+
 		}
 		if (!matched) {
 			++unmatched_params;

Modified: dbd-oracle/branches/rs_array/t/30long.t
==============================================================================
--- dbd-oracle/branches/rs_array/t/30long.t	(original)
+++ dbd-oracle/branches/rs_array/t/30long.t	Thu Jan  7 16:42:24 2010
@@ -50,7 +50,7 @@
 foreach (@test_sets) {
     my ($type_name, $type_num, $test_no_type) = @$_;
     $use_utf8_data = use_utf8_data($dbh,$type_name);
-    diag( qq(
+    warn( qq(
     =========================================================================
     Running long test for $type_name ($type_num) use_utf8_data=$use_utf8_data
 ));
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.