Merge branch 'PHP-7.1'

* PHP-7.1:
  Handle SQLDECIMAL/SQLNUMERIC types, which are used by later TDS versions
This commit is contained in:
Adam Baratz 2016-09-13 16:34:27 -04:00
commit 0b75b3761b
4 changed files with 56 additions and 12 deletions

View file

@ -10,3 +10,14 @@ The following database products are free for testing:
- Sybase Adaptive Server (Windows, Linux, *NIX) - Sybase Adaptive Server (Windows, Linux, *NIX)
- Microsoft SQL Server Azure (One Month Trial Cloud Service) - Microsoft SQL Server Azure (One Month Trial Cloud Service)
You must set the following environment variables to run the tests:
- PDO_DBLIB_TEST_DSN - DSN (e.g., dblib:host=localhost;dbname=test)
- PDO_DBLIB_TEST_USER - database user
- PDO_DBLIB_TEST_PASS - database user password
This extension supports multiple versions of the TDS protocol. There are
behavioral differences between versions. When making changes, it's recommended
to test across all supported versions. You can specify a version using a version
parameter in the DSN. See dblib_driver.c:pdo_dblib_handle_factory() for valid
values. Some tests check version-specific behavior by parsing this string, so
it's best to use the DSN (rather than freetds.conf, etc.) to set the version.

View file

@ -266,6 +266,11 @@ static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr,
if (data_len != 0 || data != NULL) { if (data_len != 0 || data != NULL) {
if (stmt->dbh->stringify) { if (stmt->dbh->stringify) {
switch (coltype) { switch (coltype) {
case SQLDECIMAL:
case SQLNUMERIC:
case SQLMONEY:
case SQLMONEY4:
case SQLMONEYN:
case SQLFLT4: case SQLFLT4:
case SQLFLT8: case SQLFLT8:
case SQLINT4: case SQLINT4:
@ -361,18 +366,16 @@ static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr,
break; break;
} }
case SQLDECIMAL:
case SQLNUMERIC:
case SQLMONEY: case SQLMONEY:
case SQLMONEY4: case SQLMONEY4:
case SQLMONEYN: { case SQLMONEYN: {
DBFLT8 money_value; DBFLT8 float_value;
dbconvert(NULL, coltype, data, 8, SQLFLT8, (LPBYTE)&money_value, -1); dbconvert(NULL, coltype, data, 8, SQLFLT8, (LPBYTE)&float_value, -1);
zv = emalloc(sizeof(zval)); zv = emalloc(sizeof(zval));
ZVAL_DOUBLE(zv, money_value); ZVAL_DOUBLE(zv, float_value);
if (stmt->dbh->stringify) {
convert_to_string(zv);
}
break; break;
} }

View file

@ -1,5 +1,21 @@
<?php <?php
function get_tds_version() {
global $dsn;
$dsn_parts = explode(':', $dsn, 2);
if ($dsn_parts[0] == 'dblib') { // uri is an option, which we'll ignore
foreach (explode(';', $dsn_parts[1]) as $arg) {
$arg = explode('=', $arg);
if ($arg[0] == 'version') {
return $arg[1];
}
}
}
return null;
}
if (false !== getenv('PDO_DBLIB_TEST_DSN')) if (false !== getenv('PDO_DBLIB_TEST_DSN'))
$dsn = getenv('PDO_DBLIB_TEST_DSN'); $dsn = getenv('PDO_DBLIB_TEST_DSN');
else else

View file

@ -9,14 +9,28 @@ require __DIR__ . '/config.inc';
<?php <?php
require __DIR__ . '/config.inc'; require __DIR__ . '/config.inc';
function get_expected_float_string() {
switch (get_tds_version()) {
case '5.0':
case '6.0':
case '7.0':
case '7.1':
case '7.2':
case '8.0':
return '10.500';
default:
return '10.5';
}
}
$sql = " $sql = "
SELECT SELECT
'foo' AS [char], 'foo' AS [char],
CAST('2030-01-01 23:59:59' AS DATETIME) AS [datetime], CAST('2030-01-01 23:59:59' AS DATETIME) AS [datetime],
CAST(0 AS BIT) AS [false], CAST(0 AS BIT) AS [false],
10.5 AS [float], 10.500 AS [float],
1000 AS [int], 1000 AS [int],
CAST(10.5 AS MONEY) AS [money], CAST(10.500 AS MONEY) AS [money],
CAST('1950-01-18 23:00:00' AS SMALLDATETIME) as [smalldatetime], CAST('1950-01-18 23:00:00' AS SMALLDATETIME) as [smalldatetime],
CAST(1 AS BIT) AS [true] CAST(1 AS BIT) AS [true]
"; ";
@ -40,9 +54,9 @@ $row = $stmt->fetch(PDO::FETCH_ASSOC);
var_dump($row['char'] === 'foo'); var_dump($row['char'] === 'foo');
var_dump($row['datetime'] === '2030-01-01 23:59:59'); var_dump($row['datetime'] === '2030-01-01 23:59:59');
var_dump($row['false'] === '0'); var_dump($row['false'] === '0');
var_dump($row['float'] === '10.5'); var_dump($row['float'] === get_expected_float_string());
var_dump($row['int'] === '1000'); var_dump($row['int'] === '1000');
var_dump($row['money'] === '10.5'); var_dump($row['money'] === '10.50');
var_dump($row['smalldatetime'] === '1950-01-18 23:00:00'); var_dump($row['smalldatetime'] === '1950-01-18 23:00:00');
var_dump($row['true'] === '1'); var_dump($row['true'] === '1');