ID:               25972
 User updated by:  phpbug at chipple dot net
 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:

In case this helps...

One thing I just noticed from my test above (in the results before the
change) is that strlen() on the tTitle field value gives 86 [bytes],
the string's correct length. I verified that the 6 last bytes are all
null (ASCII 0), only the first 80 bytes are correctly being returned.


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

[2003-11-05 01:18:08] phpbug at chipple dot net

Thank you very much for the attention to my bug report.

I gave the fix a try in my environment but then all field values
received are empty (details below).

Perhaps the SQL_COLUMN_LENGTH attribute always contains the value 0?

// Test code

$oOdbcConn =
odbc_connect(C_Gen_sDbDSN,C_Gen_sDbUser,C_Gen_sDbPassword);
$oOdbcRs = odbc_exec($oOdbcConn,$sSql);
$aOdbcRow = odbc_fetch_array($oOdbcRs);
for ($i = 1; $i <= odbc_num_fields($oOdbcRs); $i++)
  echo odbc_field_name($oOdbcRs,$i).": ".
       odbc_field_len($oOdbcRs,$i).": ".
       strlen($aOdbcRow[odbc_field_name($oOdbcRs,$i)]).": ".
       gettype($aOdbcRow[odbc_field_name($oOdbcRs,$i)])."<br>";

// Result with php4-STABLE-200311050430 before change
// (SQL_COLUMN_DISPLAY_SIZE)

aCourseID: 10: 1: string
tTitle: 80: 86: string

// Result with php4-STABLE-200311050430 after change
// (SQL_COLUMN_LENGTH)

aCourseID: 10: 0: NULL
tTitle: 80: 0: NULL

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

[2003-11-04 18:33:10] [EMAIL PROTECTED]

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);

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

[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



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

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

Reply via email to