Author: byterock
Date: Sun Jan 17 18:32:51 2010
New Revision: 13732
Modified:
dbd-oracle/trunk/Oracle.pm
dbd-oracle/trunk/dbdimp.c
dbd-oracle/trunk/dbdimp.h
dbd-oracle/trunk/oci8.c
dbd-oracle/trunk/ocitrace.h
Log:
changes from RC#1.24-3
Modified: dbd-oracle/trunk/Oracle.pm
==============================================================================
--- dbd-oracle/trunk/Oracle.pm (original)
+++ dbd-oracle/trunk/Oracle.pm Sun Jan 17 18:32:51 2010
@@ -1609,7 +1609,8 @@
=item ora_oci_success_warn
-Use this value to print silent OCI warnings that may happen when an execute or
fetch returns "Success With Info".
+Use this value to print silent OCI warnings that may happen when an execute or
fetch returns "Success With Info" or when
+you want to tune RowCaching and LOB Reads
$dbh->{ora_oci_success_warn} =1;
@@ -3155,16 +3156,26 @@
You can now customize the size of the buffer by setting the
'ora_ncs_buff_mtpl' either on the connection or statement handle. You can
also set this as 'ORA_DBD_NCS_BUFFER' OS environment variable so you will have
to go back and change all your code if you are getting into trouble.
-Most of the time the Client and the Server use the same NCharSet so the
default value has been set to 1. DBD Oracle will now die with a
-message warning you that your buffer is too small for the desired number of
characters. The error that is trapped is a
+
+The default value is set to 4 for backward compatiblty. You can lower this
value and thus increase the amount of data you can retreive. If the
+ora_ncs_buff_mtpl is too small DBD::Oracle will thow and error telling you to
increase this buffer by one.
+
+If the error is not captured then you may get
ORA-03127: no new operations allowed until the active operation ends
-which is one of the more obscure ORA errors (have some fun and report it to
Meta-Link they will scratch their heads for hours).
+which is one of the more obscure ORA errors (have some fun and report it to
Meta-Link they will scratch their heads for hours) at some random point later
on,
+usually at a finish() or disconnect() or even a fetch().
+
If you get this, simply increment the ora_ncs_buff_mtpl by one until it goes
away.
This should greatly increase your ability to select very large CLOBs or
NCLOBs, by freeing up a large block of menory.
+You can tune this value by setting ora_oci_success_warn which will display the
following
+
+ OCILobRead field 2 of 3 SUCCESS: csform 1 (SQLCS_IMPLICIT), LOBlen
10240(characters), LongReadLen 20(characters), BufLen 80(characters), Got
28(characters)
+
+In the case above we Got 28 characters (well really only 20 characters of 28
bytes) so we could use ora_ncs_buff_mtpl=>2 (20*2=40) thus saving 40bytes of
memory.
For example give this table;
Modified: dbd-oracle/trunk/dbdimp.c
==============================================================================
--- dbd-oracle/trunk/dbdimp.c (original)
+++ dbd-oracle/trunk/dbdimp.c Sun Jan 17 18:32:51 2010
@@ -44,7 +44,7 @@
int dbd_verbose = 0; /* DBD only debugging*/
int oci_warn = 0; /* show oci warnings */
int ora_objects = 0; /* get oracle embedded objects as
instance of DBD::Oracle::Object */
-int ora_ncs_buff_mtpl = 1; /* a mulitplyer for ncs clob buffers */
+int ora_ncs_buff_mtpl = 4; /* a mulitplyer for ncs clob buffers */
/* bitflag constants for figuring out how to handle utf8 for array binds */
#define ARRAY_BIND_NATIVE 0x01
@@ -543,14 +543,14 @@
#ifdef NEW_OCI_INIT /* XXX needs merging into use_proc_connection branch */
/* Get CLIENT char and nchar charset id values */
- OCINlsEnvironmentVariableGet_log_stat( &charsetid, 0,
OCI_NLS_CHARSET_ID, 0, &rsize ,status );
+ OCINlsEnvironmentVariableGet_log_stat(
&charsetid,(size_t) 0, OCI_NLS_CHARSET_ID, 0, &rsize ,status );
if (status != OCI_SUCCESS) {
oci_error(dbh, NULL, status,
"OCINlsEnvironmentVariableGet(OCI_NLS_CHARSET_ID) Check NLS settings etc.");
return 0;
}
- OCINlsEnvironmentVariableGet_log_stat( &ncharsetid, 0,
OCI_NLS_NCHARSET_ID, 0, &rsize ,status );
+ OCINlsEnvironmentVariableGet_log_stat(
&ncharsetid,(size_t) 0, OCI_NLS_NCHARSET_ID, 0, &rsize ,status );
if (status != OCI_SUCCESS) {
oci_error(dbh, NULL, status,
"OCINlsEnvironmentVariableGet(OCI_NLS_NCHARSET_ID) Check NLS settings etc.");
@@ -899,7 +899,7 @@
if (!SvROK(attribs)) {
croak ("attributes is not a reference");
- }
+ }
else if (SvTYPE(SvRV(attribs)) != SVt_PVHV) {
croak ("attributes not a hash reference");
}
@@ -3974,7 +3974,7 @@
else if (kl==11 && strEQ(key, "RowsInCache")) {
retsv = newSViv(imp_sth->RowsInCache);
cacheit = FALSE;
-
+
}else if (kl==12 && strEQ(key, "RowCacheSize")) {
retsv = newSViv(imp_sth->RowCacheSize);
cacheit = FALSE;
@@ -3984,7 +3984,7 @@
retsv = newRV(sv_2mortal((SV*)av));
while(--i >= 0)
av_store(av, i, boolSV(imp_sth->fbh[i].nullok));
- }
+ }
else if (kl==13 && strEQ(key, "len_char_size")) {
AV *av = newAV();
retsv = newRV(sv_2mortal((SV*)av));
Modified: dbd-oracle/trunk/dbdimp.h
==============================================================================
--- dbd-oracle/trunk/dbdimp.h (original)
+++ dbd-oracle/trunk/dbdimp.h Sun Jan 17 18:32:51 2010
@@ -154,8 +154,9 @@
OCITypeCode element_typecode; /*if collection this is its
element's OCI_ATTR_TYPECODE*/
OCIRef *obj_ref; /*if an embeded
object this is ref handle to its TDO*/
OCIInd *obj_ind; /*Null
indictator for object */
- OCIComplexObject *obj_value; /*the actual value from the DB*/
- OCIType *obj_type; /*if an embeded
object this is the OCIType returned by a OCIObjectPin*/
+ OCIComplexObject *obj_value; /*the actual value from the DB*/
+ OCIType *obj_type; /*if an embeded
object this is the OCIType returned by a OCIObjectPin*/
+ ub1 is_final_type; /*object's
OCI_ATTR_IS_FINAL_TYPE*/
fbh_obj_t *fields; /*one object
for each field/property*/
int field_count; /*The number of
fields Not really needed but nice to have*/
fbh_obj_t *next_subtype; /*There is strored
information about subtypes for inteherited objects*/
Modified: dbd-oracle/trunk/oci8.c
==============================================================================
--- dbd-oracle/trunk/oci8.c (original)
+++ dbd-oracle/trunk/oci8.c Sun Jan 17 18:32:51 2010
@@ -983,10 +983,10 @@
return 0;
}
/* else {
- /* set initial cache size by memory
+ /* set initial cache size by memory
[I'm not now sure why this is here - from a patch sometime
ago - Tim]
you are right Tim thre is no need to have this here so out
it goes
- a very useless call to the server
+ a very useless call to the server
ub4 cache_mem;
IV cache_mem_iv;
D_imp_dbh_from_sth ;
@@ -1781,6 +1781,7 @@
ub4 amtp = 0;
sword status;
+
if (!name)
name = "an unknown field";
@@ -1839,8 +1840,10 @@
NLS_LANG or NLS_NCHAR is not a subset of the Server's the server will
try to traslate
the data to the Client's wishes and that is wen it uses will send the
ampt value will be in bytes*/
+ buflen = amtp;
+ if (ftype == ORA_CLOB)
+ buflen = buflen*ora_ncs_buff_mtpl;
- buflen = amtp*ora_ncs_buff_mtpl;
SvGROW(dest_sv, buflen+1);
@@ -1872,28 +1875,38 @@
if (status == OCI_NEED_DATA ){
char buf[300];
sprintf(buf,"fetching %s. LOB and the read bufer is
only %lubytes, and the ora_ncs_buff_mtpl is %d, which is too small. Try
setting ora_ncs_buff_mtpl to %d",
- name, buflen,
ora_ncs_buff_mtpl,ora_ncs_buff_mtpl+1);
+ name, (unsigned long)buflen,
ora_ncs_buff_mtpl,ora_ncs_buff_mtpl+1);
oci_error_err(sth, NULL, OCI_ERROR, buf,
OCI_NEED_DATA); /* appropriate ORA error number */
- croak("DBD::Oracle has returned a %s status when doing
a LobRead!! \n",oci_status_name(status));
+ /*croak("DBD::Oracle has returned a %s status when
doing a LobRead!! \n",oci_status_name(status));*/
/*why a croak here well if it goes on it will result in a
ORA-03127: no new operations allowed until the active
operation ends
This will result in a crash if there are any other fetchst*/
}
- oci_error(sth, imp_sth->errhp, status, "OCILobRead");
+ else {
+ oci_error(sth, imp_sth->errhp, status, "OCILobRead");
sv_set_undef(dest_sv);
+
+ }
return 0;
}
- if (DBIS->debug >= 3 || dbd_verbose >= 3 )
+ if (DBIS->debug >= 3 || dbd_verbose >= 3 || oci_warn){
+ char buf[10];
+ sprintf(buf,"bytes");
+
+ if (ftype == ORA_CLOB)
+ sprintf(buf,"characters");
+
PerlIO_printf(DBILOGFP,
- " OCILobRead %s %s: csform %d (%s), LOBlen %luc,
LongReadLen %luc, BufLen %lub, Got %luc\n",
- name, oci_status_name(status),
csform,oci_csform_name(csform), ul_t(loblen),
- ul_t(imp_sth->long_readlen), ul_t(buflen),
ul_t(amtp));
+ " OCILobRead %s %s: csform %d (%s), LOBlen
%lu(%s), LongReadLen %lu(%s), BufLen %lu(%s), Got %lu(%s)\n",
+ name, oci_status_name(status),
csform,oci_csform_name(csform), ul_t(loblen),buf ,
+ ul_t(imp_sth->long_readlen),buf,
ul_t(buflen),buf, ul_t(amtp),buf);
+ }
if (ftype == ORA_BFILE) {
OCILobFileClose_log_stat(imp_sth->svchp, imp_sth->errhp,
lobloc, status);
@@ -2205,9 +2218,10 @@
case OCI_TYPECODE_OPAQUE: /*doesn't do anything though*/
if (ora_objects){
- OCIRef *type_ref=0;
+
sword status;
- if (!instance_tdo) {
+ if (!instance_tdo && !obj->is_final_type) {
+ OCIRef *type_ref=0;
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,
@@ -2229,6 +2243,14 @@
oci_error(sth,
fbh->imp_sth->errhp, status, "OCITypeByRef");
return 0;
}
+
+ status =
OCIObjectFree(fbh->imp_sth->envhp, fbh->imp_sth->errhp, type_ref, (ub2)0);
+
+ if (status != OCI_SUCCESS) {
+ oci_error(sth,
fbh->imp_sth->errhp, status, "OCIObjectFree");
+ return 0;
+ }
+
}
@@ -2240,7 +2262,7 @@
if (tdo != obj->tdo) {
/* new subtyped -> get obj
description */
if (DBIS->debug >= 5 ||
dbd_verbose >= 5 ) {
- PerlIO_printf(DBILOGFP,
" describe subtype (tdo=%x) of object type %s
(tdo=%x)\n",(int)tdo,base_obj->type_name,(int)base_obj->tdo);
+ PerlIO_printf(DBILOGFP,
" describe subtype (tdo=%p) of object type %s
(tdo=%p)\n",(void*)tdo,base_obj->type_name,(void*)base_obj->tdo);
}
Newz(1, obj->next_subtype, 1,
fbh_obj_t);
@@ -2699,14 +2721,14 @@
sb4 cache_rows = 0;/* set high so memory is the limit */
sword status;
-
+
if (imp_sth->RowCacheSize ) { /*Statment value will crump the handle
value */
cache_rows=imp_sth->RowCacheSize;
}
else if (imp_dbh->RowCacheSize){
cache_rows=imp_dbh->RowCacheSize;
-
+
}
/* seems that RowCacheSize was incorrectly used in the past
@@ -2809,7 +2831,7 @@
}
-
+
if (DBIS->debug >= 3 || dbd_verbose >= 3 || oci_warn) /*will also
display if oci_warn is on*/
PerlIO_printf(DBILOGFP,
" cache settings DB Handle
RowCacheSize=%d,Statement Handle RowCacheSize=%d, OCI_ATTR_PREFETCH_ROWS=%lu,
OCI_ATTR_PREFETCH_MEMORY=%lu, Rows per Fetch=%d, Multiple Row Fetch=%s\n",
@@ -2933,6 +2955,12 @@
return 0;
}
+ OCIAttrGet_parmdp(imp_sth, obj->parmdp, (dvoid
*)&obj->is_final_type,(ub4 *) 0, OCI_ATTR_IS_FINAL_TYPE, status);
+
+ if (status != OCI_SUCCESS) {
+ oci_error(sth,imp_sth->errhp, status, "OCIAttrGet");
+ return 0;
+ }
OCIAttrGet_parmdp(imp_sth, obj->parmdp, (dvoid
*)&obj->field_count,(ub4 *) 0, OCI_ATTR_NUM_TYPE_ATTRS, status);
if (status != OCI_SUCCESS) {
@@ -3051,6 +3079,7 @@
PerlIO_printf(DBILOGFP, " obj_ref = %p\n",obj->obj_ref);
PerlIO_printf(DBILOGFP, " obj_value = %p\n",obj->obj_value);
PerlIO_printf(DBILOGFP, " obj_type = %p\n",obj->obj_type);
+ PerlIO_printf(DBILOGFP, " is_final_type =
%u\n",obj->is_final_type);
PerlIO_printf(DBILOGFP, " field_count = %d\n",obj->field_count);
PerlIO_printf(DBILOGFP, " fields = %p\n",obj->fields);
@@ -3079,7 +3108,6 @@
ub4 num_fields;
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;
@@ -3667,7 +3695,7 @@
/* 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)) {
@@ -3677,16 +3705,16 @@
imp_sth->rs_array_idx=0;
imp_dbh->RowsInCache
=imp_sth->rs_array_size;
imp_sth->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);
}
imp_dbh->RowsInCache--;
imp_sth->RowsInCache--;
-
-
-
+
+
+
if
(imp_sth->rs_array_num_rows>imp_sth->rs_array_idx) /* set status to success
if rows in cache */
status=OCI_SUCCESS;
@@ -3794,7 +3822,7 @@
int sts;
D_imp_xxh(sth);
char errstr[256];
-
+
sts =
DBIc_DBISTATE(imp_sth)->sql_type_cast_svpv(
aTHX_ sv, fbh->req_type,
fbh->bind_flags, NULL);
if (sts == 0) {
@@ -3803,8 +3831,8 @@
i+1,
fbh->req_type);
oci_error(sth,
imp_sth->errhp, OCI_ERROR, errstr);
return Nullav;
-
- }
+
+ }
else if (sts == -2) {
sprintf(errstr,
"unsupported
bind type %ld for column %d",
@@ -3812,7 +3840,7 @@
return Nullav;
}
}
- else
+ else
#endif /* DBISTATE_VERSION > 94 */
{
if
(CSFORM_IMPLIES_UTF8(fbh->csform) ){
Modified: dbd-oracle/trunk/ocitrace.h
==============================================================================
--- dbd-oracle/trunk/ocitrace.h (original)
+++ dbd-oracle/trunk/ocitrace.h Sun Jan 17 18:32:51 2010
@@ -222,8 +222,8 @@
stat = OCINlsEnvironmentVariableGet( valp, size, item, charset,
rsizep ); \
(DBD_OCI_TRACEON) \
? PerlIO_printf(DBD_OCI_TRACEFP,\
- "%sNlsEnvironmentVariableGet(%d,%d,%d,%d,%d)=%s\n",\
- OciTp, *valp, size, item, charset, *rsizep,
oci_status_name(stat)),stat \
+ "%sNlsEnvironmentVariableGet(%d,%llu,%d,%d,%llu)=%s\n",\
+ OciTp, *valp, (unsigned long long)size, item, charset,
(unsigned long long)*rsizep, oci_status_name(stat)),stat \
: stat
/* added by lab */