diff options
author | Anatol Belski <ab@php.net> | 2016-04-06 12:23:14 +0200 |
---|---|---|
committer | Anatol Belski <ab@php.net> | 2016-04-06 12:23:14 +0200 |
commit | 2267812cd21c87d2f6ff61090def2ed7ed77125f (patch) | |
tree | 5490ccd3c046ef7eaf7c59274697555097ed79c2 | |
parent | fe757f09a417b9e0a0b604337bbbf760b2ba24a1 (diff) | |
parent | 1e1500a2bc30e0f7b0846e16567ffb3728f57eef (diff) | |
download | php-git-2267812cd21c87d2f6ff61090def2ed7ed77125f.tar.gz |
Merge branch 'PHP-7.0'
* PHP-7.0:
return zvals instead of strings, cast or not based on stringify attribute
-rw-r--r-- | ext/pdo_dblib/dblib_stmt.c | 230 | ||||
-rw-r--r-- | ext/pdo_dblib/tests/bug_38955.phpt | 8 | ||||
-rw-r--r-- | ext/pdo_dblib/tests/bug_45876.phpt | 4 | ||||
-rw-r--r-- | ext/pdo_dblib/tests/bug_47588.phpt | 6 | ||||
-rw-r--r-- | ext/pdo_dblib/tests/types.phpt | 66 |
5 files changed, 239 insertions, 75 deletions
diff --git a/ext/pdo_dblib/dblib_stmt.c b/ext/pdo_dblib/dblib_stmt.c index 49b75ee2bb..6098ae515d 100644 --- a/ext/pdo_dblib/dblib_stmt.c +++ b/ext/pdo_dblib/dblib_stmt.c @@ -232,7 +232,7 @@ static int pdo_dblib_stmt_describe(pdo_stmt_t *stmt, int colno) } col->maxlen = dbcollen(H->link, colno+1); - col->param_type = PDO_PARAM_STR; + col->param_type = PDO_PARAM_ZVAL; return 1; } @@ -245,78 +245,161 @@ static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, pdo_dblib_db_handle *H = S->H; int coltype; - unsigned int tmp_len; - char *tmp_ptr = NULL; + char *data, *tmp_data; + unsigned int data_len, tmp_data_len; + zval *zv = NULL; coltype = dbcoltype(H->link, colno+1); - - *len = dbdatlen(H->link, colno+1); - *ptr = dbdata(H->link, colno+1); - - if (*len == 0 && *ptr == NULL) { - return 1; - } - - switch (coltype) { - case SQLVARBINARY: - case SQLBINARY: - case SQLIMAGE: - case SQLTEXT: - /* FIXME: Above types should be returned as a stream as they can be VERY large */ - case SQLCHAR: - case SQLVARCHAR: - tmp_ptr = emalloc(*len + 1); - memcpy(tmp_ptr, *ptr, *len); - tmp_ptr[*len] = '\0'; - *ptr = tmp_ptr; - break; - case SQLMONEY: - case SQLMONEY4: - case SQLMONEYN: { - DBFLT8 money_value; - dbconvert(NULL, coltype, *ptr, *len, SQLFLT8, (LPBYTE)&money_value, 8); - *len = spprintf(&tmp_ptr, 0, "%.4f", money_value); - *ptr = tmp_ptr; - break; - } - case SQLUNIQUE: { - *len = 37; - tmp_ptr = emalloc(*len + 1); - *len = dbconvert(NULL, SQLUNIQUE, *ptr, *len, SQLCHAR, tmp_ptr, *len); - php_strtoupper(tmp_ptr, *len); - tmp_ptr[36] = '\0'; - *ptr = tmp_ptr; - break; + data = dbdata(H->link, colno+1); + data_len = dbdatlen(H->link, colno+1); + + if (data_len != 0 || data != NULL) { + if (stmt->dbh->stringify) { + switch (coltype) { + case SQLFLT4: + case SQLFLT8: + case SQLINT4: + case SQLINT2: + case SQLINT1: + case SQLBIT: { + if (dbwillconvert(coltype, SQLCHAR)) { + tmp_data_len = 32 + (2 * (data_len)); /* FIXME: We allocate more than we need here */ + tmp_data = emalloc(tmp_data_len); + data_len = dbconvert(NULL, coltype, data, data_len, SQLCHAR, tmp_data, -1); + + zv = emalloc(sizeof(zval)); + ZVAL_STRING(zv, tmp_data); + + efree(tmp_data); + } + break; + } + } } - case SQLDATETIM4: - case SQLDATETIME: { - DBDATETIME dt; - DBDATEREC di; - - dbconvert(H->link, coltype, (BYTE*) *ptr, -1, SQLDATETIME, (LPBYTE) &dt, -1); - dbdatecrack(H->link, &di, &dt); - *len = spprintf((char**) &tmp_ptr, 20, "%d-%02d-%02d %02d:%02d:%02d", + if (!zv) { + switch (coltype) { + case SQLCHAR: + case SQLVARCHAR: + case SQLTEXT: { +#if ilia_0 + while (data_len>0 && data[data_len-1] == ' ') { /* nuke trailing whitespace */ + data_len--; + } +#endif + } + case SQLVARBINARY: + case SQLBINARY: + case SQLIMAGE: { + zv = emalloc(sizeof(zval)); + ZVAL_STRINGL(zv, data, data_len); + + break; + } + case SQLDATETIME: + case SQLDATETIM4: { + int dl; + DBDATEREC di; + DBDATEREC dt; + + dbconvert(H->link, coltype, data, -1, SQLDATETIME, (LPBYTE) &dt, -1); + dbdatecrack(H->link, &di, (DBDATETIME *) &dt); + + dl = spprintf(&tmp_data, 20, "%d-%02d-%02d %02d:%02d:%02d", #if defined(PHP_DBLIB_IS_MSSQL) || defined(MSDBLIB) - di.year, di.month, di.day, di.hour, di.minute, di.second + di.year, di.month, di.day, di.hour, di.minute, di.second +#else + di.dateyear, di.datemonth+1, di.datedmonth, di.datehour, di.dateminute, di.datesecond +#endif + ); + + zv = emalloc(sizeof(zval)); + ZVAL_STRINGL(zv, tmp_data, dl); + + efree(tmp_data); + + break; + } + case SQLFLT4: { + zv = emalloc(sizeof(zval)); + ZVAL_DOUBLE(zv, (double) (*(DBFLT4 *) data)); + + break; + } + case SQLFLT8: { + zv = emalloc(sizeof(zval)); + ZVAL_DOUBLE(zv, (double) (*(DBFLT8 *) data)); + + break; + } + case SQLINT4: { + zv = emalloc(sizeof(zval)); + ZVAL_LONG(zv, (long) ((int) *(DBINT *) data)); + + break; + } + case SQLINT2: { + zv = emalloc(sizeof(zval)); + ZVAL_LONG(zv, (long) ((int) *(DBSMALLINT *) data)); + + break; + } + case SQLINT1: + case SQLBIT: { + zv = emalloc(sizeof(zval)); + ZVAL_LONG(zv, (long) ((int) *(DBTINYINT *) data)); + + break; + } + case SQLMONEY: + case SQLMONEY4: + case SQLMONEYN: { + DBFLT8 money_value; + dbconvert(NULL, coltype, data, 8, SQLFLT8, (LPBYTE)&money_value, -1); + + zv = emalloc(sizeof(zval)); + ZVAL_DOUBLE(zv, money_value); + + if (stmt->dbh->stringify) { + convert_to_string(zv); + } + + break; + } +#ifdef SQLUNIQUE + case SQLUNIQUE: { #else - di.dateyear, di.datemonth+1, di.datedmonth, di.datehour, di.dateminute, di.datesecond + case 36: { /* FreeTDS hack */ #endif - ); + zv = emalloc(sizeof(zval)); + ZVAL_STRINGL(zv, data, 16); /* uniqueidentifier is a 16-byte binary number */ - *ptr = (char*) tmp_ptr; - break; - } - default: - if (dbwillconvert(coltype, SQLCHAR)) { - tmp_len = 32 + (2 * (*len)); /* FIXME: We allocate more than we need here */ - tmp_ptr = emalloc(tmp_len); - *len = dbconvert(NULL, coltype, *ptr, *len, SQLCHAR, tmp_ptr, -1); - *ptr = tmp_ptr; - } else { - *len = 0; /* FIXME: Silently fails and returns null on conversion errors */ - *ptr = NULL; + break; + } + default: { + if (dbwillconvert(coltype, SQLCHAR)) { + tmp_data_len = 32 + (2 * (data_len)); /* FIXME: We allocate more than we need here */ + tmp_data = emalloc(tmp_data_len); + data_len = dbconvert(NULL, coltype, data, data_len, SQLCHAR, tmp_data, -1); + + zv = emalloc(sizeof(zval)); + ZVAL_STRING(zv, tmp_data); + + efree(tmp_data); + } + + break; + } } + } + } + + if (zv != NULL) { + *ptr = (char*)zv; + *len = sizeof(zval); + } else { + *ptr = NULL; + *len = 0; } *caller_frees = 1; @@ -335,6 +418,7 @@ static int pdo_dblib_stmt_get_column_meta(pdo_stmt_t *stmt, zend_long colno, zva pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data; pdo_dblib_db_handle *H = S->H; DBTYPEINFO* dbtypeinfo; + int coltype; if(colno >= stmt->column_count || colno < 0) { return FAILURE; @@ -346,14 +430,28 @@ static int pdo_dblib_stmt_get_column_meta(pdo_stmt_t *stmt, zend_long colno, zva if(!dbtypeinfo) return FAILURE; + coltype = dbcoltype(H->link, colno+1); + add_assoc_long(return_value, "max_length", dbcollen(H->link, colno+1) ); add_assoc_long(return_value, "precision", (int) dbtypeinfo->precision ); add_assoc_long(return_value, "scale", (int) dbtypeinfo->scale ); add_assoc_string(return_value, "column_source", dbcolsource(H->link, colno+1)); - add_assoc_string(return_value, "native_type", pdo_dblib_get_field_name(dbcoltype(H->link, colno+1))); - add_assoc_long(return_value, "native_type_id", dbcoltype(H->link, colno+1)); + add_assoc_string(return_value, "native_type", pdo_dblib_get_field_name(coltype)); + add_assoc_long(return_value, "native_type_id", coltype); add_assoc_long(return_value, "native_usertype_id", dbcolutype(H->link, colno+1)); + switch (coltype) { + case SQLBIT: + case SQLINT1: + case SQLINT2: + case SQLINT4: + add_assoc_long(return_value, "pdo_type", PDO_PARAM_INT); + break; + default: + add_assoc_long(return_value, "pdo_type", PDO_PARAM_STR); + break; + } + return 1; } diff --git a/ext/pdo_dblib/tests/bug_38955.phpt b/ext/pdo_dblib/tests/bug_38955.phpt index 1954ed460b..57adbf6c40 100644 --- a/ext/pdo_dblib/tests/bug_38955.phpt +++ b/ext/pdo_dblib/tests/bug_38955.phpt @@ -37,21 +37,21 @@ array(4) { [0]=> array(1) { ["val"]=> - string(1) "1" + int(1) } [1]=> array(1) { ["val"]=> - string(1) "2" + int(2) } [2]=> array(1) { ["val"]=> - string(1) "3" + int(3) } [3]=> array(1) { ["val"]=> - string(1) "4" + int(4) } } diff --git a/ext/pdo_dblib/tests/bug_45876.phpt b/ext/pdo_dblib/tests/bug_45876.phpt index 3d527e5ffe..5f1026e623 100644 --- a/ext/pdo_dblib/tests/bug_45876.phpt +++ b/ext/pdo_dblib/tests/bug_45876.phpt @@ -30,10 +30,10 @@ array(10) { int(%d) ["native_usertype_id"]=> int(%d) + ["pdo_type"]=> + int(2) ["name"]=> string(13) "TABLE_CATALOG" ["len"]=> int(255) - ["pdo_type"]=> - int(2) } diff --git a/ext/pdo_dblib/tests/bug_47588.phpt b/ext/pdo_dblib/tests/bug_47588.phpt index d8f424e872..262720f632 100644 --- a/ext/pdo_dblib/tests/bug_47588.phpt +++ b/ext/pdo_dblib/tests/bug_47588.phpt @@ -23,21 +23,21 @@ array(3) { [0]=> array(2) { ["My Field"]=> - string(1) "1" + int(1) ["Another Field"]=> string(11) "test_string" } [1]=> array(2) { ["My Field"]=> - string(1) "2" + int(2) ["Another Field"]=> string(11) "test_string" } [2]=> array(2) { ["My Field"]=> - string(1) "3" + int(3) ["Another Field"]=> string(11) "test_string" } diff --git a/ext/pdo_dblib/tests/types.phpt b/ext/pdo_dblib/tests/types.phpt new file mode 100644 index 0000000000..dd849adcf8 --- /dev/null +++ b/ext/pdo_dblib/tests/types.phpt @@ -0,0 +1,66 @@ +--TEST-- +PDO_DBLIB: Column data types, with or without stringifying +--SKIPIF-- +<?php +if (!extension_loaded('pdo_dblib')) die('skip not loaded'); +require __DIR__ . '/config.inc'; +?> +--FILE-- +<?php +require __DIR__ . '/config.inc'; + +$sql = " + SELECT + 'foo' AS [char], + CAST('2030-01-01 23:59:59' AS DATETIME) AS [datetime], + CAST(0 AS BIT) AS [false], + 10.5 AS [float], + 1000 AS [int], + CAST(10.5 AS MONEY) AS [money], + CAST('1950-01-18 23:00:00' AS SMALLDATETIME) as [smalldatetime], + CAST(1 AS BIT) AS [true] +"; + +$stmt = $db->query($sql); +$row = $stmt->fetch(PDO::FETCH_ASSOC); + +var_dump($row['char'] === 'foo'); +var_dump($row['datetime'] === '2030-01-01 23:59:59'); +var_dump($row['false'] === 0); +var_dump($row['float'] === 10.5); +var_dump($row['int'] === 1000); +var_dump($row['money'] === 10.5); +var_dump($row['smalldatetime'] === '1950-01-18 23:00:00'); +var_dump($row['true'] === 1); + +$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true); +$stmt = $db->query($sql); +$row = $stmt->fetch(PDO::FETCH_ASSOC); + +var_dump($row['char'] === 'foo'); +var_dump($row['datetime'] === '2030-01-01 23:59:59'); +var_dump($row['false'] === '0'); +var_dump($row['float'] === '10.5'); +var_dump($row['int'] === '1000'); +var_dump($row['money'] === '10.5'); +var_dump($row['smalldatetime'] === '1950-01-18 23:00:00'); +var_dump($row['true'] === '1'); + +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) |