Author: byterock
Date: Fri Oct 3 11:51:48 2008
New Revision: 11920
Modified:
dbd-oracle/branches/utf8_ea/Oracle.pm
dbd-oracle/branches/utf8_ea/dbdimp.c
dbd-oracle/branches/utf8_ea/dbdimp.h
dbd-oracle/branches/utf8_ea/oci8.c
Log:
hold this for now
Modified: dbd-oracle/branches/utf8_ea/Oracle.pm
==============================================================================
--- dbd-oracle/branches/utf8_ea/Oracle.pm (original)
+++ dbd-oracle/branches/utf8_ea/Oracle.pm Fri Oct 3 11:51:48 2008
@@ -935,7 +935,8 @@
ora_parse_lang => undef,
ora_placeholders => undef,
ora_auto_lob => undef,
- ora_check_sql => undef
+ ora_check_sql => undef,
+ ora_ary_is_utf8 => undef
};
}
@@ -2054,6 +2055,49 @@
$dbh->{ora_ph_csform} = SQLCS_NCHAR; # default for all future placeholders
+B<Sending Array Data using Execute_array>
+
+The Array data bound to a placeholder, which is to be executed with
execute_array,
+by default does not handle Unicode strings containing non-ASCII characters,
unless
+the default client character set is AL32UTF8.
+
+If your data contains Perl Unicode strings (UTF-8) then you will have to
explictly
+tell DBD::Oracle how to handle this data at the prepare stage or at the bind
levle.
+
+Use ora_
+
+
+
+
+
+If your array data If one of the tuble As the nature of Array Data except for
a few special
+cases. These are listed here with the highest precedence first:
+
+If the C<ora_csid> attribute is given to bind_param() then that
+is passed to Oracle and takes precedence.
+
+If the value is a Perl Unicode string (UTF-8) then DBD::Oracle
+ensures that Oracle uses the Unicode character set, regardless of
+the NLS_LANG and NLS_NCHAR settings.
+
+If the placeholder is for inserting an NCLOB then the client NLS_NCHAR
+character set is used. (That's useful but inconsistent with the other behaviour
+so may change. Best to be explicit by using the C<ora_csform>
+attribute.)
+
+If the C<ora_csform> attribute is given to bind_param() then that
+determines if the value should be assumed to be in the default
+(NLS_LANG) or NCHAR (NLS_NCHAR) client character set.
+
+
+ use DBD::Oracle qw( SQLCS_IMPLICIT SQLCS_NCHAR );
+ ...
+ $sth->bind_param(1, $value, { ora_csform => SQLCS_NCHAR });
+
+or
+
+ $dbh->{ora_ph_csform} = SQLCS_NCHAR; # default for all future placeholders
+
B<Sending Data using SQL>
Oracle assumes the SQL statement is in the default client character
Modified: dbd-oracle/branches/utf8_ea/dbdimp.c
==============================================================================
--- dbd-oracle/branches/utf8_ea/dbdimp.c (original)
+++ dbd-oracle/branches/utf8_ea/dbdimp.c Fri Oct 3 11:51:48 2008
@@ -2759,11 +2759,15 @@
if ( (svp=hv_fetch((HV*)SvRV(attribs), "ora_field",9, 0))
!= NULL) {
phs->ora_field = SvREFCNT_inc(*svp);
}
+ if ( (svp=hv_fetch((HV*)SvRV(attribs),
"ora_ary_is_utf8",15, 0)) != NULL) {
+ phs->utf8_array = 1;
+ }
if ( (svp=hv_fetch((HV*)SvRV(attribs), "ora_csform", 10,
0)) != NULL) {
if (SvIV(*svp) == SQLCS_IMPLICIT || SvIV(*svp)
== SQLCS_NCHAR)
phs->csform = (ub1)SvIV(*svp);
else warn("ora_csform must be 1
(SQLCS_IMPLICIT) or 2 (SQLCS_NCHAR), not %d", SvIV(*svp));
}
+
if ( (svp=hv_fetch((HV*)SvRV(attribs), "ora_maxdata_size",
16, 0)) != NULL) {
phs->maxdata_size = SvUV(*svp);
}
@@ -3131,8 +3135,8 @@
OCIAttrGet_log_stat(phs->bndhp, OCI_HTYPE_BIND, &phs->csid_orig, (ub4)0 ,
OCI_ATTR_CHARSET_ID, imp_sth->errhp, status);
-
-PerlIO_printf(DBILOGFP, "OCI_ATTR_CHARSET_ID=%d\n\n",phs->csid_orig);
+
+PerlIO_printf(DBILOGFP, "OCI_ATTR_CHARSET_ID=%d\n\n",phs->csid_orig);
OCIBindDynamic_log(phs->bndhp, imp_sth->errhp,
(dvoid *)phs, dbd_phs_in,
(dvoid *)phs, dbd_phs_out, status);
@@ -3191,45 +3195,15 @@
PerlIO_printf(DBILOGFP, " ARRAY_BIND_UTF8=%d CS_IS_NOT_UTF8=%d
\n",ARRAY_BIND_UTF8,CS_IS_NOT_UTF8(csid));
PerlIO_printf(DBILOGFP, " ARRAY_BIND_UTF8=%d CS_IS_NOT_UTF8=%d
\n",ARRAY_BIND_UTF8,CS_IS_UTF8(csid));
- if ((utf8 & ARRAY_BIND_UTF8) && CS_IS_NOT_UTF8(csid)) {
- /* if the specified or default csid is not utf8 _compatible_
AND we have */
- /* mixed utf8 and native (non-utf8) data, then it's a fatal
problem */
- /* utf8 _compatible_ means, can be upgraded to utf8, ie. utf8 or
ascii */
-
- PerlIO_printf(DBILOGFP, " phs->csid=%d phs->csform=%d \n", phs->csid ,
phs->csform);
- PerlIO_printf(DBILOGFP, " csid=%d \n", csid);
-
- csid = (utf8 && !CS_IS_UTF8(csid)) ? utf8_csid :
CSFORM_IMPLIED_CSID(csform);
- phs->csid = csid;
- phs->csform = csform;
-
-
- PerlIO_printf(DBILOGFP, " out phs->csid=%d phs->csform=%d \n", phs->csid ,
phs->csform);
- PerlIO_printf(DBILOGFP, " out csid=%d \n", csid);
-
-
-
-/*# if ((utf8 & ARRAY_BIND_NATIVE) && !CS_IS_UTF8_COMPATIBLE(csid)) {*/
- PerlIO_printf(DBILOGFP, "Can't mix utf8 and non-utf8 in array bind\n");
- /* croak("Can't mix utf8 and non-utf8 in array bind");*/
- /* } else {
- csid = utf8_csid; not al32utf8_csid here on purpose
- }*/
- }
-
-
-#ifdef OCI_ATTR_CHARSET_ID
-
- PerlIO_printf(DBILOGFP, "OCI_ATTR_CHARSET_ID is set \n");
-
-
-#else
- /* Effectively only used so AL32UTF8 works properly */
- PerlIO_printf(DBILOGFP, "OCI_ATTR_CHARSET_ID is Not set \n");
-
-
-#endif /* OCI_ATTR_CHARSET_ID */
- /* if data is utf8 but charset isn't then switch to utf8 csid */
+ if ((utf8 & ARRAY_BIND_UTF8) && !CS_IS_UTF8(csid)) {
+ /* if the specified or default csid is not utf8 _compatible_ AND
we have
+ * mixed utf8 and native (non-utf8) data, then it's a fatal
problem
+ * utf8 _compatible_ means, can be upgraded to utf8, ie. utf8 or
ascii */
+ if ((utf8 & ARRAY_BIND_NATIVE) && !CS_IS_UTF8_COMPATIBLE(csid)) {
+ warn("Can't mix utf8 and non-utf8 in array bind");
+ }
+ csid = utf8_csid; /* not al32utf8_csid here on purpose */
+ }
if (trace_level >= 3 || dbd_verbose <= 3 )
PerlIO_printf(DBILOGFP, "do_bind_array_exec() (3): bind %s <==
[array of values] "
@@ -3385,6 +3359,7 @@
}
av = (AV*)SvRV(sv);
for(i = 0; i < param_count; i++) {
+
if(!phs[i]) {
SV **phs_svp;
sprintf(namebuf, ":p%d", i+1);
@@ -3433,35 +3408,13 @@
/* update the utf8_flgs for this value */
- PerlIO_printf(DBILOGFP, "\n SvUTF8(sv)=%d. and
sv=%s..\n",SvUTF8(sv),neatsvpv(sv,1));
-
-
-
-
if (SvUTF8(sv)) {
- /*STRLEN len2;
- char* xx;
- xx=SvPVutf8(
sv, len2);*/
utf8_flgs[i] |= ARRAY_BIND_UTF8;
}
else {
- /*STRLEN len2;
- char* xx;
- bool is_utf8;
- xx=SvPVutf8( sv, len2);
- PerlIO_printf(DBILOGFP, "
xx=%s,len2=%d...\n",xx,len2);
-
- is_utf8=is_utf8_string((U8*)sv,1);
-
- PerlIO_printf(DBILOGFP,
"is_utf8=%d...\n",is_utf8);
-*/
-
utf8_flgs[i] |= ARRAY_BIND_NATIVE;
-
}
-
-
/* Do OCI bind calls on last iteration. */
if( ((unsigned int) j ) == exe_count - 1 ) {
if(!do_bind_array_exec(sth, imp_sth, phs[i], utf8_flgs[i]))
{
Modified: dbd-oracle/branches/utf8_ea/dbdimp.h
==============================================================================
--- dbd-oracle/branches/utf8_ea/dbdimp.h (original)
+++ dbd-oracle/branches/utf8_ea/dbdimp.h Fri Oct 3 11:51:48 2008
@@ -213,6 +213,7 @@
ub2 csid_orig; /* original oracle default csid */
ub2 csid; /* 0 for automatic */
ub1 csform; /* 0 for automatic */
+ ub1 utf8_array; /* Array has non ascii characters */
ub4 maxdata_size; /* set OCI_ATTR_MAXDATA_SIZE if >0 */
bool is_inout;
@@ -256,7 +257,6 @@
extern ub2 ncharsetid;
extern ub2 us7ascii_csid;
extern ub2 utf8_csid;
-extern ub2 we8mswin1252; /*default for windows */
extern ub2 al32utf8_csid;
extern ub2 al16utf16_csid;
@@ -264,11 +264,11 @@
( ( cs == us7ascii_csid ) )
#define CS_IS_UTF8( cs ) \
- ( ( cs == utf8_csid ) || ( cs == al32utf8_csid )|| ( cs == we8mswin1252 ) )
+ ( ( cs == utf8_csid ) || ( cs == al32utf8_csid ) )
+
+#define CS_IS_UTF8_COMPATIBLE( cs ) \
+ ( CS_IS_UTF8(cs) || ( (cs) == us7ascii_csid ) )
-/*#define CS_IS_UTF8_COMPATIBLE( cs ) \
- ( CS_IS_UTF8(cs) || ( (cs) == us7ascii_csid ) || ( (cs) == we8mswin1252 ) )
-*/
#define CS_IS_UTF16( cs ) ( cs == al16utf16_csid )
Modified: dbd-oracle/branches/utf8_ea/oci8.c
==============================================================================
--- dbd-oracle/branches/utf8_ea/oci8.c (original)
+++ dbd-oracle/branches/utf8_ea/oci8.c Fri Oct 3 11:51:48 2008
@@ -518,6 +518,7 @@
ub4 oparse_lng = 1; /* auto v6 or v7 as suits db connected
to */
int ora_check_sql = 1; /* to force a describe to check SQL */
IV ora_placeholders = 1; /* find and handle placeholders */
+ IV ora_ary_is_utf8 = 0;
/* XXX we set ora_check_sql on for now to force setup of the */
/* row cache. Change later to set up row cache using just a */
/* a memory size, perhaps also default $RowCacheSize to a */
@@ -556,7 +557,7 @@
DBD_ATTRIB_GET_IV( attribs, "ora_clbk_lob", 12, svp,
ora_clbk_lob);
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);
-
+ DBD_ATTRIB_GET_IV( attribs, "ora_ary_is_utf8", 15, svp,
ora_ary_is_utf8);
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;
@@ -2082,7 +2083,7 @@
sv_setpvn(dest_sv, (char*)fb_ary->cb_abuf,(STRLEN)actual_bufl);
if (fbh->ftype != SQLT_BIN){
-
+
if (CSFORM_IMPLIES_UTF8(fbh->csform) ){ /* do the UTF 8 magic*/
SvUTF8_on(dest_sv);
}
@@ -3396,7 +3397,7 @@
char new_tablename[100];
ub4 syn_schema_len = 0, syn_name_len = 0,tn_len;
OCIAttrGet_log_stat(imp_sth->dschp, OCI_HTYPE_DESCRIBE,
- &parmhp, 0, OCI_ATTR_PARAM, errhp, status);
+ &parmhp, 0, OCI_ATTR_PARAM, errhp, status);
OCIAttrGet_log_stat(parmhp, OCI_DTYPE_PARAM,
&syn_schema, &syn_schema_len, OCI_ATTR_SCHEMA_NAME,
errhp, status);
OCIAttrGet_log_stat(parmhp, OCI_DTYPE_PARAM,