Bug #81688 [Asn->Fbk]: PDO_ODBC doesn't handle fixed-length character columns with character conversio

From: Date: Tue, 14 Dec 2021 16:26:05 +0000
Subject: Bug #81688 [Asn->Fbk]: PDO_ODBC doesn't handle fixed-length character columns with character conversio
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-238405@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=81688&edit=1

 ID:                 81688
 Updated by:         cmb@php.net
 Reported by:        calvin at cmpct dot info
 Summary:            PDO_ODBC doesn't handle fixed-length character
                     columns with character conversio
-Status:             Assigned
+Status:             Feedback
 Type:               Bug
 Package:            PDO ODBC
 Operating System:   IBM i 7.2
 PHP Version:        8.0.13
 Assigned To:        cmb
 Block user comment: N
 Private report:     N



Previous Comments:
------------------------------------------------------------------------
[2021-12-14 13:47:41] cmb@php.net

Oh, forgot: could you also please check the results of the queries
with ext/odbc (i.e. the odbc_*() functions)?  The implementation
is quite different from PDO_ODBC.

------------------------------------------------------------------------
[2021-12-14 13:11:03] cmb@php.net

> Of course, the link to the Appendix isn't any more enlightening:

Yeah. :(

Anyhow, all this looks remotely related to bug #79059; see
particularly my last comment there[1].  It might be worthwhile to
try to run the scripts with PDO::ODBC_ATTR_ASSUME_UTF8 set to
true, even though that is not yet consistently implemented.

[1] <https://bugs.php.net/bug.php?id=79059#1601993047>

------------------------------------------------------------------------
[2021-12-07 16:54:56] calvin at cmpct dot info

Interesting observation: if you try to cast so PHP picks a bigger buffer size that might be able to
accommodate the conversion, you still get garbage at the end:

i.e. select cast(x as char(150)) as X from calvin.bigchars

gets you

```
Record
string(180)
"éééééééééééééééééééééééééééééé
                                                                                         0
(*Wind!@.0*) Gecko* "
Record
string(165) "ééééééééééééééé                      
                                                                                                 0
(*Windo"
Record
string(155) "ééééé                                                              
                                                                             0 (*"
```

(I'm guessing that's garbage in memory left over from parsing browscap, since this is
CLI...)

------------------------------------------------------------------------
[2021-12-07 16:13:58] kadler at us dot ibm dot com

I know my colleague has done some investigation here as to how different databases/drivers react
when running in different encodings between the database and the client. IIRC most drivers
don't do any conversion and just give back the data in the original encoding (which works
"ok" for the most part when everyone is some ASCII variant, but not so when one is
EBCDIC).

As to how the PHP code works using SQL_DESC_DISPLAY_SIZE, this is the docs:

https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlcolattribute-function?view=sql-server-ver15

"SQL_DESC_DISPLAY_SIZE - Maximum number of characters required to display data from the column.
For more information about display size, see Column Size, Decimal Digits, Transfer Octet Length, and
Display Size in Appendix D: Data Types."

Of course, the link to the Appendix isn't any more enlightening:

https://docs.microsoft.com/en-us/sql/odbc/reference/appendixes/column-size-decimal-digits-transfer-octet-length-and-display-size?view=sql-server-ver15

"The display size value for all data types corresponds to the value in a single descriptor
field, SQL_DESC_DISPLAY_SIZE."


In the straightforward reading of the spec, I suppose one could argue that the driver should account
for any encoding conversion of the data that it will do.

------------------------------------------------------------------------
[2021-12-03 19:05:15] calvin at cmpct dot info

I agree overallocation is ugly and something we want to avoid if we can help it.

SQL_DESC_OCTET_LENGTH is the same as the display length for the column (in this case, 30) when I
write a program to confirm this in C. I'm guessing this is technically correct because
it's what it's true for how the database may be representing it, but not after the driver
does conversion for the client's encoding.

My comment about the overflow is more about how there's garbage at the end there; I suspect
it's more not truncating and letting it go out reading stuff in the abyss. Or I'm also
reading the situation wrong, and it's reallocating the buffer, just not doing it correctly in a
way that leaves garbage. Orrrrrrr the driver isn't truncating properly; either way, I'll
probably bug the IBM people responsible for the driver and get their read on the situation.

(Apologies if you see dupes, bugs.php keeps timing out...)

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


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

    https://bugs.php.net/bug.php?id=81688


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


Thread (37 messages)

« previous php.bugs (#238405) next »