ID:               32140
 Updated by:       [EMAIL PROTECTED]
 Reported By:      bmr at comtime dot com
-Status:           Open
+Status:           Feedback
 Bug Type:         OCI8 related
 Operating System: Linux
 PHP Version:      4.3.10
 New Comment:

See also #31042, #27156.
Why do you multiple storage size by 2? Why not 4 (afaik max.  UTF char
length is 4 bytes)? 6 (other Unicodes may contain such chars too)?
This is known solution and it's *ugly*.



Previous Comments:
------------------------------------------------------------------------

[2005-02-28 23:08:28] bmr at comtime dot com

Description:
------------
NVARCHAR2 columns can be used to store UTF-8 or UTF-16 characters. 
When using UTF-8 it can take 3 (or more??) bytes to represent one
character.  PHP truncates strings that have byte representations longer
than 2 times the character length.    This is actually an Oracle bug
because the OCI call returns the wrong byte length.

Here's my patch:
--- php-4.3.10/ext/oci8/oci8.c  Wed Nov  3 08:35:56 2004
+++ php-4.3.10.cti/ext/oci8/oci8.c      Mon Feb 28 15:37:54 2005
@@ -1443,6 +1443,7 @@
        ub4 iters;
        ub4 colcount;
        ub2 dynamic;
+       ub1 charset_form;
        int dtype;
        dvoid *buf;
        oci_descriptor *descr;
@@ -1573,6 +1574,21 @@
                                return 0; /* XXX we loose memory!!! */
                        }

+                       if(outcol->data_type == SQLT_CHR) {
+                                CALL_OCI_RETURN(error, OCIAttrGet(
+                                                                (dvoid
*)param,
+                                                               
OCI_DTYPE_PARAM,
+                                                                (dvoid
*)&charset_form,
+                                                                (dvoid
*)0,
+                                                               
OCI_ATTR_CHARSET_FORM,
+                                                               
statement->pError));
+                                statement->error =
oci_error(statement->pError, "OCIAttrGet
OCI_DTYPE_PARAM/OCI_ATTR_CHARS
ET_FORM", error);
+                                if (statement->error) {
+                                        
oci_handle_error(statement->conn, statement->error);
+                                         return 0; /* XXX we loose
memory!!! */
+                                }
+                       }
+
                        CALL_OCI_RETURN(error, OCIAttrGet(
                                                (dvoid *)param,
                                                OCI_DTYPE_PARAM,
@@ -1700,6 +1716,9 @@
                                                ) {
                                                outcol->storage_size4 =
512; /* XXX this should fit "most" NLS date-formats
 and Numbers */
                                        } else {
+                                               if(charset_form ==
SQLCS_NCHAR)
+                                                       
outcol->storage_size4 *=2; /* double for unicode */
+
                                               
outcol->storage_size4++; /* add one for string terminator */
                                        }
                                        if (outcol->data_type ==
SQLT_BIN) {

Reproduce code:
---------------
ocifetchinto()



------------------------------------------------------------------------


-- 
Edit this bug report at http://bugs.php.net/?id=32140&edit=1

Reply via email to