php/php-src — pull request #348 by dpayne (2013-05-23 21:25:55+00:00)
Title: ODBC bug fix for varchars returning with length zero

This is a fix for this issue filed a long time ago and submitted to the original bug tracker site https://bugs.php.net/bug.php?id=54169

This bug also currently affects vertica DB.

From the original description

Description:
------------
I found an issue this week that exists in both odbc and pdo_odbc with
SQL Server. The ODBC implemention of Windows returns 0 as the length
for for varchar(max) and nvarchar(max). This makes the allocation of
the strings incorrect and you get back garbage pointers for the
contents.

This was a pretty easy fix for pdo_odbc, simply check if the colsize
is returned as 0 and the type is one of the varchar types, if so
always treat it as a column with "long" data. This works perfectly
without breaking things. Attached is a patch that works for both 5.3
and trunk, includes an additional test for the issue.

ODBC shows the same issue - don't have a fix for that

Occurs in all versions of PHP

There are multiple bug reports concerning this and related to it - I'll try to gather them all up (later)

Test script:
---------------
$db = new PDO('odbc:yourdsnhere', 'username', 'password');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->exec('CREATE TABLE testing(id INT NOT NULL PRIMARY KEY, data varchar(max))');
$insert = $db->prepare('INSERT INTO testing VALUES (?, ?)');
$insert->execute(array(1, str_repeat('i', 500)));
$stmt = $db->query('select * from testing');
var_dump($stmt->fetchAll());

unset($db, $insert, $smt);

// This shows the same issue in odbc
$db = odbc_connect ('yourdsnhere', 'username', 'password');
$stmt = odbc_exec($db, 'select * from testing');
var_dump(odbc_fetch_array($stmt));

Expected result:
----------------
array(1) { [0]=> array(4) { ["id"]=> string(1) "1" [0]=> string(1) "1" ["data"]=> string(500) "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii" [1]=> string(500) "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii" } }

Same for the odbc call

Actual result:
--------------
array(1) { [0]=> array(4) { ["id"]=> string(1) "1" [0]=> string(1) "1" ["data"]=> string(500) "�-\p-\!������ˆòE�������ii����iiii!���!���select * from foo�iiiiii���!�������hall�iiiiiii!������ÀùE�������ii��������1���!���­|a���ìòEáE����ðE��������stmt����!���1���(áE����������������1���!�������������������`óEàõE$E ©"���1���1�����������óE����àõE������������€������1���1�������������������óE�������@éEøëE���!���1���àóEô������������������!���iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii" [1]=> string(500) "�-\p-\!������ˆòE�������ii����iiii!���!���select * from foo�iiiiii���!�������hall�iiiiiii!������ÀùE�������ii��������1���!���­|a���ìòEáE����ðE��������stmt����!���1���(áE����������������1���!�������������������`óEàõE$E ©"���1���1�����������óE����àõE������������€������1���1�������������������óE�������@éEøëE���!���1���àóEô������������������!���iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii" } } array(2) { ["id"]=> string(1) "1" ["data"]=> string(500) "�èE8öEp�����HöEHöE$.\päE����icrosoft][SQL Server Native Client 10.0]String data, right truncation�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������" }