Skip to content

Commit 9950485

Browse files
committed
Merge branch 'PHP-7.1'
* PHP-7.1: update NEWS update NEWS pdo_dblib: stringify uniqidentifier field
2 parents f2ed298 + 726e3b8 commit 9950485

File tree

5 files changed

+112
-16
lines changed

5 files changed

+112
-16
lines changed

ext/pdo_dblib/dblib_driver.c

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -280,16 +280,28 @@ static int dblib_set_attr(pdo_dbh_t *dbh, zend_long attr, zval *val)
280280
switch(attr) {
281281
case PDO_ATTR_TIMEOUT:
282282
return 0;
283+
284+
case PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER:
285+
((pdo_dblib_db_handle *)dbh->driver_data)->stringify_uniqueidentifier = zval_get_long(val);
286+
return 1;
287+
283288
default:
284289
return 1;
285290
}
286-
287291
}
288292

289293
static int dblib_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *return_value)
290294
{
291-
/* dblib_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data; */
292-
return 0;
295+
switch (attr) {
296+
case PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER:
297+
ZVAL_BOOL(return_value, ((pdo_dblib_db_handle *)dbh->driver_data)->stringify_uniqueidentifier);
298+
break;
299+
300+
default:
301+
return 0;
302+
}
303+
304+
return 1;
293305
}
294306

295307
static struct pdo_dbh_methods dblib_methods = {
@@ -347,6 +359,15 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options)
347359

348360
php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, nvars);
349361

362+
H = pecalloc(1, sizeof(*H), dbh->is_persistent);
363+
H->login = dblogin();
364+
H->err.sqlstate = dbh->error_code;
365+
H->stringify_uniqueidentifier = 0;
366+
367+
if (!H->login) {
368+
goto cleanup;
369+
}
370+
350371
if (driver_options) {
351372
int connect_timeout = pdo_attr_lval(driver_options, PDO_DBLIB_ATTR_CONNECTION_TIMEOUT, -1);
352373
int query_timeout = pdo_attr_lval(driver_options, PDO_DBLIB_ATTR_QUERY_TIMEOUT, -1);
@@ -361,14 +382,8 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options)
361382

362383
dbsetlogintime(connect_timeout); /* Connection/Login Timeout */
363384
dbsettime(query_timeout); /* Statement Timeout */
364-
}
365385

366-
H = pecalloc(1, sizeof(*H), dbh->is_persistent);
367-
H->login = dblogin();
368-
H->err.sqlstate = dbh->error_code;
369-
370-
if (!H->login) {
371-
goto cleanup;
386+
H->stringify_uniqueidentifier = pdo_attr_lval(driver_options, PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER, 0);
372387
}
373388

374389
DBERRHANDLE(H->login, (EHANDLEFUNC) pdo_dblib_error_handler);

ext/pdo_dblib/dblib_stmt.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ static int pdo_dblib_stmt_cursor_closer(pdo_stmt_t *stmt)
120120
dbcancel(H->link);
121121

122122
pdo_dblib_err_dtor(&H->err);
123-
123+
124124
return 1;
125125
}
126126

@@ -213,7 +213,7 @@ static int pdo_dblib_stmt_describe(pdo_stmt_t *stmt, int colno)
213213
pdo_dblib_db_handle *H = S->H;
214214
struct pdo_column_data *col;
215215
char *fname;
216-
216+
217217
if(colno >= stmt->column_count || colno < 0) {
218218
return FAILURE;
219219
}
@@ -376,16 +376,28 @@ static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr,
376376

377377
break;
378378
}
379+
379380
#ifdef SQLUNIQUE
380381
case SQLUNIQUE: {
381382
#else
382383
case 36: { /* FreeTDS hack */
383384
#endif
384-
zv = emalloc(sizeof(zval));
385-
ZVAL_STRINGL(zv, data, 16); /* uniqueidentifier is a 16-byte binary number */
385+
if (H->stringify_uniqueidentifier) { // 36-char hex string representation
386+
tmp_data_len = 36;
387+
tmp_data = safe_emalloc(tmp_data_len, sizeof(char), 1);
388+
data_len = (unsigned int) dbconvert(NULL, SQLUNIQUE, (BYTE*)data, data_len, SQLCHAR, (BYTE*)tmp_data, tmp_data_len);
389+
php_strtoupper(tmp_data, data_len);
390+
zv = emalloc(sizeof(zval));
391+
ZVAL_STRINGL(zv, tmp_data, data_len);
392+
efree(tmp_data);
386393

394+
} else { // a 16-byte binary representation
395+
zv = emalloc(sizeof(zval));
396+
ZVAL_STRINGL(zv, data, 16);
397+
}
387398
break;
388399
}
400+
389401
default: {
390402
if (dbwillconvert(coltype, SQLCHAR)) {
391403
tmp_data_len = 32 + (2 * (data_len)); /* FIXME: We allocate more than we need here */
@@ -479,4 +491,3 @@ struct pdo_stmt_methods dblib_stmt_methods = {
479491
pdo_dblib_stmt_next_rowset, /* nextrow */
480492
pdo_dblib_stmt_cursor_closer
481493
};
482-

ext/pdo_dblib/pdo_dblib.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ PHP_MINIT_FUNCTION(pdo_dblib)
173173
{
174174
REGISTER_PDO_CLASS_CONST_LONG("DBLIB_ATTR_CONNECTION_TIMEOUT", (long) PDO_DBLIB_ATTR_CONNECTION_TIMEOUT);
175175
REGISTER_PDO_CLASS_CONST_LONG("DBLIB_ATTR_QUERY_TIMEOUT", (long) PDO_DBLIB_ATTR_QUERY_TIMEOUT);
176+
REGISTER_PDO_CLASS_CONST_LONG("DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER", (long) PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER);
176177

177178
if (FAIL == dbinit()) {
178179
return FAILURE;

ext/pdo_dblib/php_pdo_dblib_int.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ typedef struct {
113113
DBPROCESS *link;
114114

115115
pdo_dblib_err err;
116+
unsigned stringify_uniqueidentifier:1;
116117
} pdo_dblib_db_handle;
117118

118119
typedef struct {
@@ -142,7 +143,8 @@ ZEND_EXTERN_MODULE_GLOBALS(dblib)
142143

143144
enum {
144145
PDO_DBLIB_ATTR_CONNECTION_TIMEOUT = PDO_ATTR_DRIVER_SPECIFIC,
145-
PDO_DBLIB_ATTR_QUERY_TIMEOUT
146+
PDO_DBLIB_ATTR_QUERY_TIMEOUT,
147+
PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER,
146148
};
147149

148150
#endif
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
--TEST--
2+
PDO_DBLIB: Uniqueidentifier column data type stringifying
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('pdo_dblib')) die('skip not loaded');
6+
require __DIR__ . '/config.inc';
7+
?>
8+
--FILE--
9+
<?php
10+
require __DIR__ . '/config.inc';
11+
12+
13+
$testGUID = '82A88958-672B-4C22-842F-216E2B88E72A';
14+
$testGUIDBinary = base64_decode('WImogitnIkyELyFuK4jnKg==');
15+
16+
$sql = "SELECT CAST('$testGUID' as uniqueidentifier) as [guid]";
17+
18+
//--------------------------------------------------------------------------------
19+
// 1. Get and Set the attribute
20+
//--------------------------------------------------------------------------------
21+
$db->setAttribute(PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER, true);
22+
var_dump(true === $db->getAttribute(PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER));
23+
$db->setAttribute(PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER, false);
24+
var_dump(false === $db->getAttribute(PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER));
25+
26+
27+
//--------------------------------------------------------------------------------
28+
// 2. Binary
29+
//--------------------------------------------------------------------------------
30+
$stmt = $db->query($sql);
31+
$row = $stmt->fetch(PDO::FETCH_ASSOC);
32+
33+
var_dump($row['guid'] === $testGUIDBinary);
34+
35+
36+
//--------------------------------------------------------------------------------
37+
// 3. PDO::ATTR_STRINGIFY_FETCHES must not affect `uniqueidentifier` representation
38+
//--------------------------------------------------------------------------------
39+
$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true);
40+
$stmt = $db->query($sql);
41+
$row = $stmt->fetch(PDO::FETCH_ASSOC);
42+
$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);
43+
44+
var_dump($row['guid'] === $testGUIDBinary);
45+
46+
47+
//--------------------------------------------------------------------------------
48+
// 4. Stringifying
49+
// ! With TDS protocol version <7.0 binary will be returned and the test will fail !
50+
// TODO: something from PDO::ATTR_SERVER_VERSION, PDO::ATTR_CLIENT_VERSION or PDO::ATTR_SERVER_INFO should be used
51+
// to get TDS version and skip this test in this case.
52+
//--------------------------------------------------------------------------------
53+
$db->setAttribute(PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER, true);
54+
$stmt = $db->query($sql);
55+
$row = $stmt->fetch(PDO::FETCH_ASSOC);
56+
57+
var_dump($row['guid'] === $testGUID);
58+
var_dump($row['guid']);
59+
60+
?>
61+
--EXPECT--
62+
bool(true)
63+
bool(true)
64+
bool(true)
65+
bool(true)
66+
bool(true)
67+
string(36) "82A88958-672B-4C22-842F-216E2B88E72A"

0 commit comments

Comments
 (0)