Author: byterock
Date: Thu Jul  9 11:13:37 2009
New Revision: 13026

Modified:
   dbd-oracle/branches/rs_array/Oracle.pm
   dbd-oracle/branches/rs_array/dbdimp.c
   dbd-oracle/branches/rs_array/dbdimp.h
   dbd-oracle/branches/rs_array/oci8.c
   dbd-oracle/branches/rs_array/ocitrace.h

Log:
nice working copy

Modified: dbd-oracle/branches/rs_array/Oracle.pm
==============================================================================
--- dbd-oracle/branches/rs_array/Oracle.pm      (original)
+++ dbd-oracle/branches/rs_array/Oracle.pm      Thu Jul  9 11:13:37 2009
@@ -322,7 +322,7 @@
                  ora_session_mode      => undef,
                  ora_verbose           => undef,
                  ora_oci_success_warn  => undef,
-                 ora_objects   => undef
+                 ora_objects           => undef,
                  };
     }
    
@@ -930,20 +930,23 @@
     }
 
     sub private_attribute_info {
-        return { ora_lengths           => undef,
-                 ora_types             => undef,
-                 ora_rowid             => undef,
-                 ora_est_row_width     => undef,
-                 ora_type               => undef,
-                 ora_field              => undef,
-                 ora_csform            => undef,
-                 ora_maxdata_size      => undef,
-                 ora_parse_lang                => undef,
-                 ora_placeholders      => undef,
-                 ora_auto_lob          => undef,
-                 ora_check_sql         => undef
-                };
-    }
+       return {ora_lengths             => undef,
+               ora_types               => undef,
+               ora_rowid               => undef,
+               ora_est_row_width       => undef,
+               ora_type                => undef,
+               ora_field               => undef,
+               ora_csform              => undef,
+               ora_maxdata_size        => undef,
+               ora_parse_lang          => undef,
+               ora_placeholders        => undef,
+               ora_auto_lob            => undef,
+               ora_check_sql           => undef,
+               ora_row_cache_off       => undef,
+               ora_prefetch_rows       => undef,
+               ora_prefetch_memory     => undef,
+               };
+   }
    
 }
 
@@ -1329,7 +1332,7 @@
 Oracle technical support (and not the dbi-users mailing list). Thanks.
 Thanks to Mark Dedlow for this information.
 
-=head2 Constants
+=head1 Constants
 
 =over 4
 
@@ -1393,6 +1396,9 @@
 
   OCI_STMT_SCROLLABLE_READONLY 
 
+
+=head1 Attributes
+
 =head2 Connect Attributes
 
 =over 4
@@ -1675,16 +1681,27 @@
 
 See L</Scrollable Cursors> for more details.
 
+=item ora_prefetch_rows
+
+Sets the number of rows to be prefetched. If it is not set, then the default 
value is 1.
+See L</Prefetching Rows> for more details.
+
 =item ora_prefetch_memory
 
-Sets the memory level for top level rows to be prefetched. Rows up to the 
specified top level row 
-count C<RowCacheSize> are fetched if it occupies no more than the specified 
memory usage limit. The default value is 0, 
-which means that memory size is not included in computing the number of rows 
to prefetch. If
-the C<RowCacheSize> value is set to 0 or a negative number when using this 
value then only 
-the memory value entered is used to compute the number of rows to prefetch.
+Sets the memory level for rows to be prefetched. The application then fetches 
as many rows as will fit into that much memory.
+See L</Prefetching Rows> for more details.
+
+=item ora_row_cache_off
 
+By default DBD::Oracle will use a row cache when fetching to cut down the 
number of round 
+trips to the server. If you do not want to use an array fetch set this value 
to any value other than 0;
 See L</Prefetching Rows> for more details.
 
+=item 
+
+You can customize the value of the row cache with this value.  By default it 
will normlly be set to the 
+RowCacheSize or one cles to it.
+
 =item ora_verbose
 
 Use this value to enable DBD::Oracle only tracing.  Simply set the attribute 
to the trace level you desire.
@@ -1767,9 +1784,77 @@
 Specify internal data representation. Currently is supported only for
 ORA_NUMBER_TABLE.
 
+=head1 Optimizing Results
+
+=head2 Prepare postponed till execute
+
+The DBD::Oracle module can avoid an explicit 'describe' operation
+prior to the execution of the statement unless the application requests
+information about the results (such as $sth->{NAME}). This reduces
+communication with the server and increases performance (reducing the
+number of PARSE_CALLS inside the server).
+
+However, it also means that SQL errors are not detected until
+C<execute()> (or $sth->{NAME} etc) is called instead of when
+C<prepare()> is called. Note that if the describe is triggered by the
+use of $sth->{NAME} or a similar attribute and the describe fails then
+I<an exception is thrown> even if C<RaiseError> is false!
+
+Set L</ora_check_sql> to 0 in prepare() to enable this behaviour.
+
+=head1 Prefetching & Row Caching 
+
+DBD::Oracle now supports both Server pre-fetch and Client side row caching. By 
defualt both 
+are trurned on to give optimum performance. Most of the time one can just let 
DBD::Oracle
+figure out the best optimization. 
+
+=head2 Row Caching
+
+Row caching occures on the client side and the object of it is to cut down the 
number of round 
+trips made to the server when fetching rows. At each fetch a set number of 
rows will be retreived
+from the server and stored locally. Further calls the server are made only 
when the end of the 
+local buffer(cache) is reached.
+
+Rows up to the specified top level row 
+count C<RowCacheSize> are fetched if it occupies no more than the specified 
memory usage limit. 
+The default value is 0, which means that memory size is not included in 
computing the number of rows to prefetch. If
+the C<RowCacheSize> value is set to a negative number then the positive value 
of RowCacheSize is used 
+to compute the number of rows to prefetch.
+
+By default C<RowCacheSize> is automaticaly set. If you want to totaly turn off 
prefetching set this to 1.
+
+
+
+=head2 Row Prefetching
+
+Row prefetching occurs on the server side and uses the DBI database handle 
attribute C<RowCacheSize> and or the 
+Prepare Attribute 'ora_prefetch_memory'. Tweaking these values may yield 
improved performance. 
+
+   $dbh->{RowCacheSize} = 100;
+   
$sth=$dbh->prepare($SQL,{ora_exe_mode=>OCI_STMT_SCROLLABLE_READONLY,ora_prefetch_memory=>10000});
+   
+In the above example 10 rows will be prefetched up to a maximum of 10000 bytes 
of data.  The Oracle� Call Interface Programmer's Guide,
+suggests a good row cache value for a scrollable cursor is about 20% of 
expected size of the record set. 
+
+The prefetch settings tell the DBD::Oracle to grab x rows (or x-bytes) when it 
needs to get new rows. This happens on the first 
+fetch that sets the current_positon to any value other than 0. In the above 
example if we do a OCI_FETCH_FIRST the first 10 rows are
+loaded into the buffer and DBD::Oracle will not have to go back to the server 
for more rows. When record 11 is fetched DBD::Oracle
+fetches and returns this row and the next 9 rows are loaded into the buffer. 
In this case if you fetch backwards from 10 to 1 
+no server round trips are made.
+
+With large record sets it is best not to attempt to go to the last record as 
this may take some time, A large buffer size might even slow down
+the fetch. If you must get the number of rows in a large record set you might 
try using an few large OCI_FETCH_ABSOLUTEs and then an OCI_FETCH_LAST,
+this might save some time. So if you had a record set of 10000 rows and you 
set the buffer to 5000 and did a OCI_FETCH_LAST one would fetch the first 5000 
rows into the buffer then the next 5000 rows.  
+If one requires only the first few rows there is no need to set a large 
prefetch value.  
+
+If the ora_prefetch_memory less than 1 or not present then memory size is not 
included in computing the 
+number of rows to prefetch otherwise the number of rows will be limited to 
memory size. Likewise if the RowCacheSize is less than 1 it
+is not included in the computing of the prefetch rows.  
 
 =back
 
+=head1 Spaces & Padding
+
 =head2 Trailing Spaces
 
 Please note that only the Oracle OCI 8 strips trailing spaces from VARCHAR 
placeholder
@@ -2687,23 +2772,6 @@
 
 =back
 
-=head1 Prepare postponed till execute
-
-The DBD::Oracle module can avoid an explicit 'describe' operation
-prior to the execution of the statement unless the application requests
-information about the results (such as $sth->{NAME}). This reduces
-communication with the server and increases performance (reducing the
-number of PARSE_CALLS inside the server).
-
-However, it also means that SQL errors are not detected until
-C<execute()> (or $sth->{NAME} etc) is called instead of when
-C<prepare()> is called. Note that if the describe is triggered by the
-use of $sth->{NAME} or a similar attribute and the describe fails then
-I<an exception is thrown> even if C<RaiseError> is false!
-
-Set L</ora_check_sql> to 0 in prepare() to enable this behaviour.
-
-
 =head1 Scrollable Cursors
 
 Oracle supports the concept of a 'Scrollable Cursor' which is defined as a 
'Result Set' where
@@ -2918,33 +2986,6 @@
 When using scrollable cursors it is required that you use the $sth->finish() 
method when you are done with the cursor as this type of
 cursor has to be explicitly canceled on the server. If you do not do this you 
may cause resource problems on your database.  
 
-=head2 Prefetching Rows
-
-One can override the DBD::Oracle's default pre-fetch values by using the DBI 
database handle attribute C<RowCacheSize> and or the 
-Prepare Attribute 'ora_prefetch_memory'. Tweaking these values may yield 
improved performance. 
-
-   $dbh->{RowCacheSize} = 10;
-   
$sth=$dbh->prepare($SQL,{ora_exe_mode=>OCI_STMT_SCROLLABLE_READONLY,ora_prefetch_memory=>10000});
-   
-In the above example 10 rows will be prefetched up to a maximum of 10000 bytes 
of data.  The Oracle� Call Interface Programmer's Guide,
-suggests a good row cache value for a scrollable cursor is about 20% of 
expected size of the record set. 
-
-The prefetch settings tell the DBD::Oracle to grab x rows (or x-bytes) when it 
needs to get new rows. This happens on the first 
-fetch that sets the current_positon to any value other than 0. In the above 
example if we do a OCI_FETCH_FIRST the first 10 rows are
-loaded into the buffer and DBD::Oracle will not have to go back to the server 
for more rows. When record 11 is fetched DBD::Oracle
-fetches and returns this row and the next 9 rows are loaded into the buffer. 
In this case if you fetch backwards from 10 to 1 
-no server round trips are made.
-
-With large record sets it is best not to attempt to go to the last record as 
this may take some time, A large buffer size might even slow down
-the fetch. If you must get the number of rows in a large record set you might 
try using an few large OCI_FETCH_ABSOLUTEs and then an OCI_FETCH_LAST,
-this might save some time. So if you had a record set of 10000 rows and you 
set the buffer to 5000 and did a OCI_FETCH_LAST one would fetch the first 5000 
rows into the buffer then the next 5000 rows.  
-If one requires only the first few rows there is no need to set a large 
prefetch value.  
-
-If the ora_prefetch_memory less than 1 or not present then memory size is not 
included in computing the 
-number of rows to prefetch otherwise the number of rows will be limited to 
memory size. Likewise if the RowCacheSize is less than 1 it
-is not included in the computing of the prefetch rows.  
-
-
 =head1 LOBs and LONGs
 
 The key to working with LOBs (CLOB, BLOBs) is to remember the value of an 
Oracle LOB column is not the content of the LOB. It's a

Modified: dbd-oracle/branches/rs_array/dbdimp.c
==============================================================================
--- dbd-oracle/branches/rs_array/dbdimp.c       (original)
+++ dbd-oracle/branches/rs_array/dbdimp.c       Thu Jul  9 11:13:37 2009
@@ -379,6 +379,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))
@@ -1024,6 +1026,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);
        }
@@ -2445,7 +2450,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 */
@@ -3058,6 +3062,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);

Modified: dbd-oracle/branches/rs_array/dbdimp.h
==============================================================================
--- dbd-oracle/branches/rs_array/dbdimp.h       (original)
+++ dbd-oracle/branches/rs_array/dbdimp.h       Thu Jul  9 11:13:37 2009
@@ -41,7 +41,8 @@
        OCISession      *authp;
        int proc_handles;                  /* If true, srvhp, svchp, and authp 
handles
                                                                   are owned by 
ProC and must not be freed. */
-       int RowCacheSize;
+       int RowCacheSize; /* both of these are defined by DBI spec*/
+       int RowsInCache;        /* this vaue is RO and cannot be set*/
        int ph_type;            /* default oratype for placeholders */
        ub1 ph_csform;          /* default charset for placeholders */
        int parse_error_offset; /* position in statement of last error */
@@ -78,7 +79,7 @@
        ub4                             piece_size;     /*used in callback to 
set the size of the piece to get*/
        int                             has_lobs;       /*Statement has bound 
LOBS */
     int                                ret_lobs;       /*Statement returns 
LOBS */
-       lob_refetch_t   *lob_refetch;
+       lob_refetch_t   *lob_refetch;
        int                             nested_cursor;  /* cursors fetched from 
SELECTs */
        AV                              *bind_tuples;   /* Bind tuples in array 
execute, or NULL */
        int                             rowwise;                /* If true, 
bind_tuples is list of */
@@ -111,15 +112,15 @@
        int                     fetch_orient;
        int                             fetch_offset;
        int                             fetch_position;
-       int                     prefetch_memory;   /* OCI_PREFETCH_MEMORY*/
-       int                             prefetch_rows;     /* OCI_PREFETCH_ROWS 
*/
+       int                     prefetch_memory;        /* OCI_PREFETCH_MEMORY*/
+       int                             prefetch_rows;          /* 
OCI_PREFETCH_ROWS
        /* array fetch: state variables */
        int                             row_cache_off;
-       /*bool                  rs_array_on;               /* if array to be 
used */
-       int                             rs_array_size;           /* array size 
*/
-       int                             rs_array_num_rows;       /* num rows in 
last fetch */
-       int                             rs_array_idx;             /* index of 
current row */
-       sword                   rs_array_status;           /* status of last 
fetch */
+       int                     rs_fetch_count;         /*fetch count*/
+       int                             rs_array_size;          /*array size 
local value for RowCacheSize as I do not want to change RowCacheSize */
+       int                             rs_array_num_rows;      /* num rows in 
last fetch */
+       int                             rs_array_idx;           /* index of 
current row */
+       sword                   rs_array_status;        /* status of last fetch 
*/
 };
 #define IMP_STH_EXECUTING      0x0001
 
@@ -308,6 +309,7 @@
 char *oci_bind_options _((ub4 options));
 char *oci_define_options _((ub4 options));
 char *oci_hdtype_name _((ub4 hdtype));
+char *oci_attr_name _((ub4 attr));
 char *oci_exe_mode _((ub4 mode));
 char *oci_col_return_codes _((int rc));
 int dbd_rebind_ph_lob _((SV *sth, imp_sth_t *imp_sth, phs_t *phs));
@@ -344,7 +346,7 @@
 void * oci_db_handle(imp_dbh_t *imp_dbh, int handle_type, int flags);
 void * oci_st_handle(imp_sth_t *imp_sth, int handle_type, int flags);
 void fb_ary_free(fb_ary_t *fb_ary);
-
+void rs_array_init(imp_sth_t *imp_sth);
 
 
 

Modified: dbd-oracle/branches/rs_array/oci8.c
==============================================================================
--- dbd-oracle/branches/rs_array/oci8.c (original)
+++ dbd-oracle/branches/rs_array/oci8.c Thu Jul  9 11:13:37 2009
@@ -242,7 +242,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 +347,317 @@
        return SvPV(sv,na);
 }
 
+/*used to look up the name of a Attribute Types
+  used only for debugging */
+char *
+oci_attr_name(ub4 attr)
+{
+       dTHX;
+       SV *sv;
+       switch (attr) {
+       /*=============================Attribute 
Types===============================*/
+       /* 
+          Note: All attributes are global.  New attibutes should be added to 
the end
+          of the list. Before you add an attribute see if an existing one can 
be 
+          used for your handle. 
+       
+          If you see any holes please use the holes first. 
+        
+       */
+       
/*===========================================================================*/
+       
+       
+       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_ID:                       return 
"OCI_ATTR_CHARSET_ID";                           /* Character Set ID */
+       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 "";              
   /* # of attempts */
+       case OCI_ATTR_RECIPIENT_LIST:                           return "";      
           /* recipient list */
+       case OCI_ATTR_EXCEPTION_QUEUE:                          return "";      
     /* exception queue name */
+       case OCI_ATTR_ENQ_TIME:                         return "";/* enqueue 
time (only OCIAttrGet) */
+       case OCI_ATTR_MSG_STATE:                                return "";/* 
message state (only OCIAttrGet) */
+                                                          /* NOTE: 64-66 used 
below */
+       case OCI_ATTR_AGENT_NAME:                               return "";      
           /* agent name */
+       case OCI_ATTR_AGENT_ADDRESS:                            return "";      
            /* agent address */
+       case OCI_ATTR_AGENT_PROTOCOL:                           return "";      
          /* agent protocol */
+       
+       case OCI_ATTR_SENDER_ID:                                return "";      
                /* sender id */
+       case OCI_ATTR_ORIGINAL_MSGID:                           return "";      
     /* original message id */
+       
+       case OCI_ATTR_QUEUE_NAME:                               return "";      
               /* queue name */
+       case OCI_ATTR_NFY_MSGID:                                return "";      
               /* message id */
+       case OCI_ATTR_MSG_PROP:                         return "";            
/* message properties */
+       
+       case OCI_ATTR_NUM_DML_ERRORS:                           return "";      
 /* num of errs in array DML */
+       case OCI_ATTR_DML_ROW_OFFSET:                           return "";      
 /* row offset in the array */
+       
+       case OCI_ATTR_DATEFORMAT:                               return "";     
/* default date format string */
+       case OCI_ATTR_BUF_ADDR:                         return "";              
   /* buffer address */
+       case OCI_ATTR_BUF_SIZE:                         return "";              
     /* buffer size */
+       case OCI_ATTR_DIRPATH_MODE:                             return "";  /* 
mode of direct path operation */
+       case OCI_ATTR_DIRPATH_NOLOG:                            return "";      
         /* nologging option */
+       case OCI_ATTR_DIRPATH_PARALLEL:                         return "";    
/* parallel (temp seg) option */
+       case OCI_ATTR_NUM_ROWS:                         return ""; /* number of 
rows in column array */
+                                         /* NOTE that OCI_ATTR_NUM_COLS is a 
column
+                                          * array attribute too.
+                                          */
+       case OCI_ATTR_COL_COUNT:                                return "";      
  /* columns of column array
+                                                            processed so far.  
     */
+       case OCI_ATTR_STREAM_OFFSET:                            return "";  /* 
str off of last row processed 
+       case OCI_ATTR_SHARED_HEAPALLO:                          return "";    
/* Shared Heap Allocation Size */
+       
+       case OCI_ATTR_SERVER_GROUP:                             return "";    
/* server group name */
+       
+       case OCI_ATTR_MIGSESSION:                               return "";  /* 
migratable session attribute */
+       
+       case OCI_ATTR_NOCACHE:                          return "";              
  /* Temporary LOBs */
+       
+       case OCI_ATTR_MEMPOOL_SIZE:                             return "";      
                /* Pool Size */
+       case OCI_ATTR_MEMPOOL_INSTNAME:                         return "";      
          /* Instance name */
+       case OCI_ATTR_MEMPOOL_APPNAME:                          return "";      
         /* Application name */
+       case OCI_ATTR_MEMPOOL_HOMENAME:                         return "";      
      /* Home Directory name */
+       case OCI_ATTR_MEMPOOL_MODEL:                            return "";     
/* Pool Model (proc,thrd,both)*/
+       case OCI_ATTR_MODES:                            return "";              
            /* Modes */
+       
+       case OCI_ATTR_SUBSCR_NAME:                              return "";      
     /* name of subscription */
+       case OCI_ATTR_SUBSCR_CALLBACK:                          return "";      
      /* associated callback */
+       case OCI_ATTR_SUBSCR_CTX:                               return "";   /* 
associated callback context */
+       case OCI_ATTR_SUBSCR_PAYLOAD:                           return "";      
       /* associated payload */
+       case OCI_ATTR_SUBSCR_NAMESPACE:                         return "";      
    /* associated namespace */
+       
+       case OCI_ATTR_PROXY_CREDENTIALS:                                return 
"";         /* Proxy user credentials */
+       case OCI_ATTR_INITIAL_CLIENT_ROLES:                             return 
"";      /* Initial client role list */
+       
+       case OCI_ATTR_UNK:                              return "";              
    /* unknown attribute */
+       case OCI_ATTR_NUM_COLS:                         return "";              
    /* number of columns */
+       case OCI_ATTR_LIST_COLUMNS:                             return "";      
 /* parameter of the column list */
+       case OCI_ATTR_RDBA:                             return "";           /* 
DBA of the segment header */
+       case OCI_ATTR_CLUSTERED:                                return "";      
/* whether the table is clustered */
+       case OCI_ATTR_PARTITIONED:                              return "";    
/* whether the table is partitioned */
+       case OCI_ATTR_INDEX_ONLY:                               return "";     
/* whether the table is index only */
+       case OCI_ATTR_LIST_ARGUMENTS:                           return "";      
/* parameter of the argument list */
+       case OCI_ATTR_LIST_SUBPROGRAMS:                         return "";    
/* parameter of the subprogram list */
+       case OCI_ATTR_REF_TDO:                          return "";          /* 
REF to the type descriptor */
+       case OCI_ATTR_LINK:                             return "";              
/* the database link name */
+       case OCI_ATTR_MIN:                              return "";              
         /* minimum value */
+       case OCI_ATTR_MAX:                              return "";              
         /* maximum value */
+       case OCI_ATTR_INCR:                             return "";              
       /* increment value */
+       case OCI_ATTR_CACHE:                            return "";   /* number 
of sequence numbers cached */
+       case OCI_ATTR_ORDER:                            return "";     /* 
whether the sequence is ordered */
+       case OCI_ATTR_HW_MARK:                          return "";              
       /* high-water mark */
+       case OCI_ATTR_TYPE_SCHEMA:                              return "";      
            /* type's schema name */
+       case OCI_ATTR_TIMESTAMP:                                return "";      
       /* timestamp of the object */
+       case OCI_ATTR_NUM_ATTRS:                                return "";      
          /* number of sttributes */
+       case OCI_ATTR_NUM_PARAMS:                               return "";      
          /* number of parameters */
+       case OCI_ATTR_OBJID:                            return "";       /* 
object id for a table or view */
+       case OCI_ATTR_PTYPE:                            return "";           /* 
type of info described by */
+       case OCI_ATTR_PARAM:                            return "";              
  /* parameter descriptor */
+       case OCI_ATTR_OVERLOAD_ID:                              return "";     
/* overload ID for funcs and procs */
+       case OCI_ATTR_TABLESPACE:                               return "";      
              /* table name space */
+       case OCI_ATTR_TDO:                              return "";              
         /* TDO of a type */
+       case OCI_ATTR_LTYPE:                            return "";              
             /* list type */
+       case OCI_ATTR_PARSE_ERROR_OFFSET:                               return 
"";               /* Parse Error offset */
+       case OCI_ATTR_IS_TEMPORARY:                             return "";      
    /* whether table is temporary */
+       case OCI_ATTR_IS_TYPED:                         return "";              
/* whether table is typed */
+       case OCI_ATTR_DURATION:                         return "";         /* 
duration of temporary table */
+       case OCI_ATTR_IS_INVOKER_RIGHTS:                                return 
"";                 /* is invoker rights */
+       case OCI_ATTR_OBJ_NAME:                         return "";           /* 
top level schema obj name */
+       case OCI_ATTR_OBJ_SCHEMA:                               return "";      
                   /* schema name */
+       case OCI_ATTR_OBJ_ID:                           return "";          /* 
top level schema object id */
+       
+       case OCI_ATTR_DIRPATH_SORTED_INDEX:                             return 
"";/* index that data is sorted on */
+       
+                   /* direct path index maint method (see oci8dp.h) */
+       case OCI_ATTR_DIRPATH_INDEX_MAINT_METHOD:                               
return "";
+       
+           /* parallel load: db file, initial and next extent sizes */
+       
+       case OCI_ATTR_DIRPATH_FILE:                             return "";     
/* DB file to load into */
+       case OCI_ATTR_DIRPATH_STORAGE_INITIAL:                          return 
"";       /* initial extent size */
+       case OCI_ATTR_DIRPATH_STORAGE_NEXT:                             return 
"";          /* next extent size */
+       
+       
+       case OCI_ATTR_TRANS_TIMEOUT:                            return "";      
/* transaction timeout */
+       case OCI_ATTR_SERVER_STATUS:                            return "";/* 
state of the server handle */
+       case OCI_ATTR_STATEMENT:                                return ""; /* 
statement txt in stmt hdl */
+                                       /* statement should not be executed in 
cache 
+       case OCI_ATTR_NO_CACHE:                         return "";*/
+       case OCI_ATTR_DEQCOND:                          return "";         /* 
dequeue condition */
+       case OCI_ATTR_RESERVED_2:                               return "";      
            /* reserved */
+       
+         
+       case OCI_ATTR_SUBSCR_RECPT:                             return "";/* 
recepient of subscription */
+       case OCI_ATTR_SUBSCR_RECPTPROTO:                                return 
"";    /* protocol for recepient */
+       
+           /* 8.2 dpapi support of ADTs */
+       case OCI_ATTR_DIRPATH_EXPR_TYPE:                                return 
"";       /* expr type of OCI_ATTR_NAME */
+       
+       case OCI_ATTR_DIRPATH_INPUT:                            return "";    
/* 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 "";      
       /* LDAP host to connect to */
+       case OCI_ATTR_LDAP_PORT:                                return "";      
        /* LDAP port to connect to */
+       case OCI_ATTR_BIND_DN:                          return "";              
                /* bind DN */
+       case OCI_ATTR_LDAP_CRED:                                return "";      
 /* credentials to connect to LDAP */
+       case OCI_ATTR_WALL_LOC:                         return "";              
 /* client wallet location */
+       case OCI_ATTR_LDAP_AUTH:                                return "";      
     /* LDAP authentication method */
+       case OCI_ATTR_LDAP_CTX:                         return "";        /* 
LDAP adminstration context DN */
+       case OCI_ATTR_SERVER_DNS:                               return "";      
/* list of registration server DNs */
+       
+       case OCI_ATTR_DN_COUNT:                         return "";             
/* the number of server DNs */
+       case OCI_ATTR_SERVER_DN:                                return "";      
           /* server DN attribute */
+       
+       case OCI_ATTR_MAXCHAR_SIZE:                             return "";    
/* max char size of data */
+       
+       case OCI_ATTR_CURRENT_POSITION:                         return ""; /* 
for scrollable result sets*/
+       
+       /* Added to get attributes for ref cursor to statement handle */
+       case OCI_ATTR_RESERVED_3:                               return "";      
            /* reserved */
+       case OCI_ATTR_RESERVED_4:                               return "";      
            /* reserved */
+       case OCI_ATTR_DIRPATH_FN_CTX:                           return "";  /* 
fn ctx ADT attrs or args */
+       case OCI_ATTR_DIGEST_ALGO:                              return "";      
   /* digest algorithm */
+       case OCI_ATTR_CERTIFICATE:                              return "";      
         /* certificate */
+       case OCI_ATTR_SIGNATURE_ALGO:                           return "";      
 /* signature algorithm */
+       case OCI_ATTR_CANONICAL_ALGO:                           return "";    
/* canonicalization algo. */
+       case OCI_ATTR_PRIVATE_KEY:                              return "";      
         /* private key */
+       case OCI_ATTR_DIGEST_VALUE:                             return "";      
       /* digest value */
+       case OCI_ATTR_SIGNATURE_VAL:                            return "";      
     /* signature value */
+       case OCI_ATTR_SIGNATURE:                                return "";      
           /* signature */
+       
+       /* attributes for setting OCI stmt caching specifics in svchp */
+       case OCI_ATTR_STMTCACHESIZE :                           return "";     
/* size of the stm cache */
+       
+       /* --------------------------- Connection Pool Attributes 
------------------ */
+       case OCI_ATTR_CONN_NOWAIT:                              return "";
+       case OCI_ATTR_CONN_BUSY_COUNT:                          return "";
+       case OCI_ATTR_CONN_OPEN_COUNT:                          return "";
+       case OCI_ATTR_CONN_TIMEOUT:                             return "";
+       case OCI_ATTR_STMT_STATE:                               return "";
+       case OCI_ATTR_CONN_MIN:                         return "";
+       case OCI_ATTR_CONN_MAX:                         return "";
+       case OCI_ATTR_CONN_INCR:                                return "";
+       
+       case OCI_ATTR_DIRPATH_OID:                              return "";   /* 
loading into an OID col */
+       
+       case OCI_ATTR_NUM_OPEN_STMTS:                           return "";    
/* open stmts in session */
+       case OCI_ATTR_DESCRIBE_NATIVE:                          return ""; /* 
get native info via desc */
+       
+       case OCI_ATTR_BIND_COUNT:                               return "";   /* 
number of bind postions */
+       case OCI_ATTR_HANDLE_POSITION:                          return "";/* 
pos of bind/define handle */
+       case OCI_ATTR_RESERVED_5:                               return "";      
           /* reserverd */
+       case OCI_ATTR_SERVER_BUSY:                              return ""; /* 
call in progress on server*/
+       
+       case OCI_ATTR_DIRPATH_SID:                              return "";   /* 
loading into an SID col */
+       /* notification presentation for recipient */
+       case OCI_ATTR_SUBSCR_RECPTPRES:                         return "";
+       case OCI_ATTR_TRANSFORMATION:                           return ""; /* 
AQ message transformation */
+       
+       case OCI_ATTR_ROWS_FETCHED:                             return ""; /* 
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 *
@@ -537,6 +848,8 @@
        /* row cache. Change later to set up row cache using just a     */
        /* 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");
@@ -1027,7 +1340,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);
@@ -1601,25 +1913,26 @@
                cache_rows = 1;         /* else read_blob can't work    */
        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.     
*/
+               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;
+       }
 
        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*/
@@ -2275,28 +2588,57 @@
                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: 
row_cache_off=%d, 
rs_array_size=%d\n",imp_sth->row_cache_off,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;
+       int num_errors          = 0;
        ub4 prefetch_mem        = 0; /*Oracle prefetch memory buffer*/
        ub4 prefetch_rows       = 0; /*Oracle prefetch Row Buffer*/
        sb4 cache_rows          = 0;/* set high so memory is the limit */
        sword status;
        
+       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 as we use to select one 1 record at 
a time from 
+          the fetch this means the records are never really cached locally.as 
each fecth did 
+          a round trim
+          
+          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 */
+
+       /* number of rows to cache       if using oraperl  will leave this in 
for now*/
+       
+
        if (SvOK(imp_drh->ora_cache_o)){
                imp_sth->cache_rows = SvIV(imp_drh->ora_cache_o);
        }
@@ -2304,13 +2646,11 @@
                imp_sth->cache_rows = SvIV(imp_drh->ora_cache);
        }
 
-
-
-    if (imp_dbh->RowCacheSize){
+       if (imp_dbh->RowCacheSize){
          cache_rows=imp_dbh->RowCacheSize;
-       }
-    
-    prefetch_rows      =imp_sth->prefetch_rows;
+       } 
+
+       prefetch_rows   =imp_sth->prefetch_rows;
        prefetch_mem    =imp_sth->prefetch_memory;
        
        
@@ -2323,11 +2663,15 @@
                }
        }
        else if (imp_dbh->RowCacheSize < 0) {/* for compaibility with DBI doc 
negitive value here means use the value as memory*/
-               PerlIO_printf(DBILOGFP,"2\n");
                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);
                /*Sill use local cache but it is calulated nothing in the doc 
for this so I will use it like this*/
+       } 
+       else {
+          if (!prefetch_mem){
+                       prefetch_rows = cache_rows;
+          }
        }
                
        
@@ -2356,14 +2700,19 @@
     if (max_cache_rows){
                imp_sth->rs_array_size=max_cache_rows;
        } 
-       else{
-         
+       
+       
+       if (imp_sth->row_cache_off){
+               imp_dbh->RowsInCache =1;
+       } 
+       else {
+               imp_dbh->RowsInCache=imp_sth->rs_array_size;
        }
        
-       if (DBIS->debug >= 3 || dbd_verbose >= 3 )
+       if (DBIS->debug >= 3 || dbd_verbose >= 3 || oci_warn)
                PerlIO_printf(DBILOGFP,
-                       "       cache settings OCI_ATTR_PREFETCH_ROWS %lu, 
OCI_ATTR_PREFETCH_MEMORY %lu Rows per Fetch=%d, Multiple Row Fetch on=%d"
-                       (unsigned long) (prefetch_rows), (unsigned long) 
(prefetch_mem),cache_rows,imp_sth->row_cache_off);
+                       "       cache settings RowCacheSize=%d, 
OCI_ATTR_PREFETCH_ROWS %lu, OCI_ATTR_PREFETCH_MEMORY %lu Rows per Fetch=%d, 
Multiple Row Fetch off=%d\n",
+                       imp_dbh->RowCacheSize,(unsigned long) (prefetch_rows), 
(unsigned long) (prefetch_mem),cache_rows,imp_sth->row_cache_off);
 
 
    
@@ -2373,7 +2722,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 )
 {
@@ -3010,13 +3358,9 @@
        }/* end define of filed struct[i] fbh*/
 
        imp_sth->est_width = est_width;
-sth_set_row_cache(h, imp_sth,
+       sth_set_row_cache(h, imp_sth,
                        (imp_dbh->max_nested_cursors) ? 0 :nested_cursors ,
                        (int)num_fields, has_longs );
-                       
-       /*sth_set_row_cache(h, imp_sth,
-                       (nested_cursors) ? imp_dbh->max_nested_cursors / 
nested_cursors : 0,
-                       (int)num_fields, has_longs );*/
        /* Initialise cache counters */
        imp_sth->in_cache  = 0;
        imp_sth->eod_errno = 0;
@@ -3034,7 +3378,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;
@@ -3126,6 +3470,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;
@@ -3161,11 +3506,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);
-
                                /*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);
@@ -3173,24 +3519,33 @@
                        if (DBIS->debug >= 4 || dbd_verbose >= 4 )
                                PerlIO_printf(DBILOGFP,"        Scrolling 
Fetch, postion after fetch=%d\n",imp_sth->fetch_position);
 
-               } else {
+               } 
+               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*/
-                               if (DBIS->debug >= 4 || dbd_verbose <= 4 )
-                                       
PerlIO_printf(DBILOGFP,"rs_array_num_rows=%d rs_array_idx=%d, 
rs_array_status=%d 
rs_array_size=%d\n",imp_sth->rs_array_num_rows,imp_sth->rs_array_idx,imp_sth->rs_array_status,imp_sth->rs_array_size);
-                                       
+                                       
+                               imp_dbh->RowsInCache--;
                                imp_sth->rs_array_idx++;
+                               
                                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)) {
                                        
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," fetch count=%d\n",imp_sth->rs_fetch_count);*/
+                               
                                }               
                                                
                                if 
(imp_sth->rs_array_num_rows>imp_sth->rs_array_idx)   /* set status to success 
if rows in cache */
@@ -3207,8 +3562,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) {

Modified: dbd-oracle/branches/rs_array/ocitrace.h
==============================================================================
--- dbd-oracle/branches/rs_array/ocitrace.h     (original)
+++ dbd-oracle/branches/rs_array/ocitrace.h     Thu Jul  9 11:13:37 2009
@@ -259,8 +259,8 @@
 #define OCIAttrSet_log_stat(th,ht,ah,s1,a,eh,stat)                             
                \
        stat=OCIAttrSet(th,ht,ah,s1,a,eh);                              \
        (DBD_OCI_TRACEON) ? PerlIO_printf(DBD_OCI_TRACEFP,                      
\
-               "%sAttrSet(%p,%s,%p,%lu,%lu,%p)=%s\n",                  \
-               OciTp, 
(void*)th,oci_hdtype_name(ht),(void*)(ah),ul_t(s1),ul_t(a),(void*)eh,    \
+               "%sAttrSet(%p,%s, %p,%lu,Attr=%s,%p)=%s\n",                     
\
+               OciTp, 
(void*)th,oci_hdtype_name(ht),sl_t(ah),ul_t(s1),oci_attr_name(a),(void*)eh,     
 \
                oci_status_name(stat)),stat : stat
 
 #define OCIBindByName_log_stat(sh,bp,eh,p1,pl,v,vs,dt,in,al,rc,mx,cu,md,stat)  
\

Reply via email to