ID: 25972 Updated by: [EMAIL PROTECTED] Reported By: phpbug at chipple dot net Status: Analyzed Bug Type: Feature/Change Request Operating System: Win2K 5.00.2195 SP4 PHP Version: 4.3, 5 New Comment:
I do not like the idea of introducing ODBCv3 based code/ options to a system predominately defined by ODBCv2 specifications. So I am against the inclusion of Moriyoshi's initial suggested fix for this. That being said, I did a bit more research on this today and think the following change should allow the double wide characters to work much better. I haven't tested it out yet myself, but if someone else has the time, it would be beneficial to all. Sorry about the bug system mangling. Essentially the SQL_COLUMNS_DISPLAY_SIZE lists the number of characters needed to display everything. This works fine but in the case of a double wide character array it doesn't (as explained my Moriyoshi). The SQL_COLUMN_LENGTH should return the number of bytes necessary for retrival of the column. WARNING: this change may fundamentally alter the functionality of the longreadlen variable comparisons as well. Use at your own risk right now. Index: php_odbc.c ======================================================== =========== RCS file: /repository/php-src/ext/odbc/php_odbc.c,v retrieving revision 1.176 diff -r1.176 php_odbc.c 671,672c671,672 < rc = SQLColAttributes(result->stmt, (UWORD)(i+1), SQL_COLUMN_DISPLAY_SIZE, < NULL, 0, NULL, &displaysize); --- > rc = SQLColAttributes(result->stmt, (UWORD)(i+1), > SQL_COLUMN_LENGTH, NULL, 0, NULL, &displaysize); Previous Comments: ------------------------------------------------------------------------ [2003-11-04 09:31:56] [EMAIL PROTECTED] Well, then how did you conclude NVARCHAR support will break some kinds of compatibilities? I think I have already pointed out that we'd still be able to handle it on ODBCv2. (Sorry if this sounds offending. I don't mean so :) Basically we don't have to check whether the column type is NVARCHAR or not, but just allocate enough space for that type of characters. That way we also got to take a slight loss of memory into account though. ------------------------------------------------------------------------ [2003-11-04 07:56:51] [EMAIL PROTECTED] moriyoshi, It's not as simple as you show it to be. First you must realize that PHP's ODBC layer is written as an ODBC v2 compliant system, to just randomly add in support for NVARCHAR (and friends) will break support for other database systems. The point of my post wasn't to say this isn't a bug (hence why I marked it as verified), but rather to say it's a known bug and the issue is the extension is in need of updating. ------------------------------------------------------------------------ [2003-11-03 17:13:35] [EMAIL PROTECTED] I might be wrong, but I think this is a valid bug. According to the documentation on msdn [1] [2], the fifth parameter of SQLBindCol() expects the size of the buffer in byte, while the code mentioned below appears to give it the number of characters allocated for the column (display size) instead. This kind of confusion will most likely cause unexpected behaviour like described in this report. php_odbc.c 669: ------------------------------------------------------ default: rc = SQLColAttributes(result->stmt, (UWORD)(i+1), SQL_COLUMN_DISPLAY_SIZE, NULL, 0, NULL, &displaysize); displaysize = displaysize <= result->longreadlen ? displaysize : result->longreadlen; result->values[i].value = (char *)emalloc(displaysize + 1); rc = SQLBindCol(result->stmt, (UWORD)(i+1), SQL_C_CHAR, result->values[i].value, displaysize + 1, &result->values[i].vallen); break; ------------------------------------------------------ If the driver supports ODBCv3, we should use SQL_DESC_OCTET_LENGTH, which can be used to determine the actual number of bytes. If not, we may be able to safely calculate the maximum column size by simply multiplying the display size by 2, as NVARCHAR columns are known to not contain multi-byte strings, but double-byte strings. [1] http://msdn.microsoft.com/library/en-us/odbc/htm/odch04pr_13.asp?frame=true [2] http://msdn.microsoft.com/library/en-us/odbc/htm/odappdpr_24.asp?frame=true ------------------------------------------------------------------------ [2003-10-31 09:26:28] [EMAIL PROTECTED] Is this really a bug? The debate rages like so: One the one hand ODBC does not support multi-byte characters at all. On the other, the idea of multi- byte characters didn't exist (or if it did, not very prevailent) at the time of the original authoring of the ODBC system. Next question is, is there an easy fix. Nope. I've had a fix in the works, I've just lost all time to work upon it. Marking as verified, but not really sure it's a bug. Maybe a feature request really... Following the ODBCv2 specs, NVARCHAR is a type that doesn't exist, nor does TEXT, NTEXT, and many of the other wonderful types found today. ------------------------------------------------------------------------ [2003-10-24 00:10:01] phpbug at chipple dot net Sorry here's the MSSQL extension code that should have been in the 2nd part of "Reproduce code". // MSSQL EXTENSION, data retrieved correctly $oConn = mssql_connect("localhost",C_Gen_sDbUser,C_Gen_sDbPassword); mssql_select_db("icds",$oConn); $oRs = mssql_query("SELECT * FROM T_Course WHERE aCourseID=1"); $aRow = mssql_fetch_array($oRs); // GOOD: Complete title retrieved (60 chars=120 bytes) echo $aRow["tTitle"]; mssql_close($oConn); ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at http://bugs.php.net/25972 -- Edit this bug report at http://bugs.php.net/?id=25972&edit=1