Author: byterock
Date: Thu Jan 15 09:51:55 2009
New Revision: 12446

Modified:
   dbd-oracle/trunk/Changes
   dbd-oracle/trunk/Oracle.pm
   dbd-oracle/trunk/dbdimp.c
   dbd-oracle/trunk/dbdimp.h
   dbd-oracle/trunk/oci8.c

Log:
Fix for a reported issue from Martin Evans regarding very slow cursor fetch.  
The root issue was that a ref cursor cannot buffer more than 1 row when it has 
lobs  this was the default for all ref cursors which makes them all slow.  This 
way only ones with lobs will be slow.

Modified: dbd-oracle/trunk/Changes
==============================================================================
--- dbd-oracle/trunk/Changes    (original)
+++ dbd-oracle/trunk/Changes    Thu Jan 15 09:51:55 2009
@@ -1,6 +1,7 @@
 =head1 Changes in DBD-Oracle 1.23(svn rev #####)
-  Added rt.cpan.org Ticket #=42328 ora_objects attribute for extended embedded 
objects support from tnt at netsafe.cz
-  Fix for rt.cpan.org Ticket #=42328 user defined types from different schema 
in describe_obj from tnt at netsafe.cz
+  Added a change from a suggestion from Martic Evans for makeing ref cursors 
faster.
+  Added rt.cpan.org Ticket #=42328 ora_objects attribute for extended embedded 
objects support from Tomas Pokorny
+  Fix for rt.cpan.org Ticket #=42328 user defined types from different schema 
in describe_obj from Tomas Pokorny 
   Added a README for sun suggested by Jim McCullars
   Clean up of white space and formating to 4 tabs  from John Scoles
   Fix for GCC 4.3 warnings from Eric Simon

Modified: dbd-oracle/trunk/Oracle.pm
==============================================================================
--- dbd-oracle/trunk/Oracle.pm  (original)
+++ dbd-oracle/trunk/Oracle.pm  Thu Jan 15 09:51:55 2009
@@ -3990,10 +3990,11 @@
 
 DBD::Oracle supports only the 'selection' of embedded objects of the following 
types OBJECT, VARRAY
 and TABLE in any combination. Support is seamless and recursive, meaning you 
-need only supply a simple SQL statement to get all the values in an embedded 
object 
-as an array of scalars. 
+need only supply a simple SQL statement to get all the values in an embedded 
object.
+You can either get the values as an array of scalars or they can be returned 
into a DBD::Oracle::Object.
 
-For example, given this type and table;
+
+Array example, given this type and table;
 
   CREATE OR REPLACE TYPE  "PHONE_NUMBERS" as varray(10) of varchar(30);
   
@@ -4059,6 +4060,51 @@
       print "\n";
    }
 
+Object example, given this object and table;
+
+   CREATE OR REPLACE TYPE Person AS OBJECT (
+     name    VARCHAR2(20),
+     age     INTEGER)
+   ) NOT FINAL;
+
+   CREATE TYPE Employee UNDER Person (
+     salary  NUMERIC(8,2)
+   );
+
+   CREATE TABLE people (id INTEGER, obj Person);
+   
+   INSERT INTO people VALUES (1, Person('Black', 25));
+   INSERT INTO people VALUES (2, Employee('Smith', 44, 5000));
+
+The following code will access the data;
+
+   $dbh{'ora_objects'} =>1;
+   
+   $sth = $dbh->prepare("select * from people order by id");
+   $sth->execute();
+   
+   # object are fetched as instance of DBD::Oracle::Object
+   my ($id1, $obj1) = $sth->fetchrow();
+   my ($id2, $obj2) = $sth->fetchrow();
+   
+   # get full type-name of object
+   print $obj1->type_name."44\n";     # 'TEST.PERSON' is printed
+   print $obj2->type_name."4\n";      # 'TEST.EMPLOYEE' is printed
+   
+   # get attribute NAME from object 
+   print $obj1->attr('NAME')."3\n";   # 'Black' is printed
+   print $obj2->attr('NAME')."3\n";   # 'Smith' is printed
+   
+   # get all atributes as hash reference
+   my $h1 = $obj1->attr;        # returns {'NAME' => 'Black', 'AGE' => 25}
+   my $h2 = $obj2->attr;        # returns {'NAME' => 'Smith', 'AGE' => 44,
+                                #          'SALARY' => 5000 }
+   
+   # get all attributes (names and values) as array
+   my @a1 = $obj1->attributes;  # returns ('NAME', 'Black', 'AGE', 25)
+   my @a2 = $obj2->attributes;  # returns ('NAME', 'Smith', 'AGE', 44,
+                                #          'SALARY', 5000 )
+   
 So far DBD::Oracle has been tested on a table with 20 embedded Objects, 
Varrays and Tables 
 nested to 10 levels.
 

Modified: dbd-oracle/trunk/dbdimp.c
==============================================================================
--- dbd-oracle/trunk/dbdimp.c   (original)
+++ dbd-oracle/trunk/dbdimp.c   Thu Jan 15 09:51:55 2009
@@ -2395,7 +2395,7 @@
                if (status != OCI_SUCCESS) {
                        oci_error(sth, imp_sth->errhp, status, "OCIBindByName 
SQLT_RSET");
                        return 0;
-                }
+               }
 
                ENTER;
                SAVETMPS;

Modified: dbd-oracle/trunk/dbdimp.h
==============================================================================
--- dbd-oracle/trunk/dbdimp.h   (original)
+++ dbd-oracle/trunk/dbdimp.h   Thu Jan 15 09:51:55 2009
@@ -72,17 +72,17 @@
        int                             is_child;  /* if this is child from a 
ref cursor or SP*/
        ub2                             stmt_type;      /* OCIAttrGet 
OCI_ATTR_STMT_TYPE        */
        U16                             auto_lob;       /* use auto lobs*/
-       int                             pers_lob;   /*use dblink for lobs only 
for 10g Release 2. or later*/
-       int                             clbk_lob;   /*use dblink for lobs only 
for 10g Release 2. or later*/
-       int                             piece_lob;  /*use piece fetch for lobs*/
-       ub4                             piece_size; /*used in callback to set 
the size of the piece to get*/
-       int                     has_lobs;   /* Statement has bound LOBS*/
-
+       int                             pers_lob;       /*use dblink for lobs 
only for 10g Release 2. or later*/
+       int                             clbk_lob;       /*use dblink for lobs 
only for 10g Release 2. or later*/
+       int                             piece_lob;      /*use piece fetch for 
lobs*/
+       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;
-       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 */
-                                                                  /* tuples, 
otherwise list of columns. */
+       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 */
+                                                                       /* 
tuples, otherwise list of columns. */
        /* Input Details        */
        char                    *statement;             /* sql (see sth_scan)   
        */
        HV                              *all_params_hv; /* all params, keyed by 
name    */

Modified: dbd-oracle/trunk/oci8.c
==============================================================================
--- dbd-oracle/trunk/oci8.c     (original)
+++ dbd-oracle/trunk/oci8.c     Thu Jan 15 09:51:55 2009
@@ -1043,7 +1043,7 @@
        }
        else {
        /* Call a special rebinder for cursor ref "in" params */
-       return(pp_rebind_ph_rset_in(sth, imp_sth, phs));
+               return(pp_rebind_ph_rset_in(sth, imp_sth, phs));
        }
 }
 
@@ -2293,7 +2293,7 @@
                imp_sth->cache_rows = SvIV(imp_drh->ora_cache);
        }
 
-       if (imp_sth->is_child){ /*ref cursors and sp only one row is allowed*/
+       if (imp_sth->is_child  && imp_sth->ret_lobs){ /*ref cursors and sp only 
one row is allowed*/
                cache_rows  =1;
                cache_mem  =0;
 
@@ -2873,25 +2873,25 @@
                        case    ORA_BLOB:                               /* BLOB 
        */
                        case    114:                            /* BFILE        
*/
                                fbh->ftype  = fbh->dbtype;
-
+                               imp_sth->ret_lobs = 1;
                                /* do we need some addition size logic here? 
(lab) */
 
                                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*/
+                                       fbh->pers_lob   = 1;
+                                       fbh->disize     = 
fbh->disize+long_readlen; /*user set max value for the fetch*/
                                        if (fbh->dbtype == ORA_CLOB){
-                                               fbh->ftype = SQLT_CHR;
+                                               fbh->ftype  = SQLT_CHR;
                                        }
                                        else {
                                                fbh->ftype = SQLT_LVB; /*Binary 
form seems this is the only value where we cna get the length correctly*/
                                        }
                                }
                                else if (imp_sth->clbk_lob){ /*get by peice 
with callback a slow*/
-                                       fbh->clbk_lob     = 1;
+                                       fbh->clbk_lob           = 1;
                                        fbh->define_mode        = 
OCI_DYNAMIC_FETCH; /* piecwise fetch*/
                                        fbh->disize             = 
imp_sth->long_readlen; /*user set max value for the fetch*/
                                        fbh->piece_size         = 
imp_sth->piece_size; /*the size for each piece*/
-                                       fbh->fetch_cleanup = 
fetch_cleanup_pres_lobs; /* clean up buffer before each fetch*/
+                                       fbh->fetch_cleanup      = 
fetch_cleanup_pres_lobs; /* clean up buffer before each fetch*/
                                        if (!imp_sth->piece_size){ /*if not set 
use max value*/
                                                
imp_sth->piece_size=imp_sth->long_readlen;
                                        }
@@ -2903,11 +2903,11 @@
                                        fbh->fetch_func = fetch_clbk_lob;
                                }
                                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;
                                        }

Reply via email to