Skip to content

Commit 72c9324

Browse files
auroraeosroseweltling
authored andcommitted
Fix ODBC bug for varchars returning with length zero
1 parent 6e5958e commit 72c9324

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

ext/pdo_odbc/odbc_stmt.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,24 @@ static int odbc_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
558558
sizeof(S->cols[colno].colname)-1, &colnamelen,
559559
&S->cols[colno].coltype, &colsize, NULL, NULL);
560560

561+
/* This fixes a known issue with SQL Server and (max) lengths,
562+
may affect others as well. If we are SQL_VARCHAR,
563+
SQL_VARBINARY, or SQL_WVARCHAR (or any of the long variations)
564+
and zero is returned from colsize then consider it long */
565+
if (0 == colsize &&
566+
(S->cols[colno].coltype == SQL_VARCHAR ||
567+
S->cols[colno].coltype == SQL_LONGVARCHAR ||
568+
#ifdef SQL_WVARCHAR
569+
S->cols[colno].coltype == SQL_WVARCHAR ||
570+
#endif
571+
#ifdef SQL_WLONGVARCHAR
572+
S->cols[colno].coltype == SQL_WLONGVARCHAR ||
573+
#endif
574+
S->cols[colno].coltype == SQL_VARBINARY ||
575+
S->cols[colno].coltype == SQL_LONGVARBINARY)) {
576+
S->going_long = 1;
577+
}
578+
561579
if (rc != SQL_SUCCESS) {
562580
pdo_odbc_stmt_error("SQLDescribeCol");
563581
if (rc != SQL_SUCCESS_WITH_INFO) {

ext/pdo_odbc/tests/max_columns.phpt

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
--TEST--
2+
PDO ODBC varying character with max/no length
3+
--SKIPIF--
4+
<?php # vim:ft=php
5+
if (!extension_loaded('pdo_odbc')) print 'skip not loaded';
6+
?>
7+
--FILE--
8+
<?php
9+
require 'ext/pdo/tests/pdo_test.inc';
10+
$db = PDOTest::test_factory('ext/pdo_odbc/tests/common.phpt');
11+
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
12+
13+
if (false === $db->exec('CREATE TABLE TEST (id INT NOT NULL PRIMARY KEY, data varchar(max))')) {
14+
if (false === $db->exec('CREATE TABLE TEST (id INT NOT NULL PRIMARY KEY, data longtext)')) {
15+
if (false === $db->exec('CREATE TABLE TEST (id INT NOT NULL PRIMARY KEY, data CLOB)')) {
16+
die("BORK: don't know how to create a long column here:\n" . implode(", ", $db->errorInfo()));
17+
}
18+
}
19+
}
20+
21+
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
22+
23+
$sizes = array(32, 64, 128, 253, 254, 255, 256, 257, 258, 512, 1024, 2048, 3998, 3999, 4000);
24+
25+
$db->beginTransaction();
26+
$insert = $db->prepare('INSERT INTO TEST VALUES (?, ?)');
27+
foreach ($sizes as $num) {
28+
$insert->execute(array($num, str_repeat('i', $num)));
29+
}
30+
$insert = null;
31+
$db->commit();
32+
33+
foreach ($db->query('SELECT id, data from TEST') as $row) {
34+
$expect = str_repeat('i', $row[0]);
35+
if (strcmp($expect, $row[1])) {
36+
echo "Failed on size $row[id]:\n";
37+
printf("Expected %d bytes, got %d\n", strlen($expect), strlen($row['data']));
38+
echo bin2hex($expect) . "\n";
39+
echo bin2hex($row['data']) . "\n";
40+
}
41+
}
42+
43+
echo "Finished\n";
44+
45+
--EXPECT--
46+
Finished

0 commit comments

Comments
 (0)