diff options
author | fandrieu <fandrieu@gmail.com> | 2017-10-17 14:16:38 -0400 |
---|---|---|
committer | Adam Baratz <adambaratz@php.net> | 2017-10-17 14:16:38 -0400 |
commit | 014fd21b482cd1aa8e3fc8662936c18cee300670 (patch) | |
tree | a5417a29cbc6b0d9bcc8c9928ec52bebebb4bce4 /ext/pdo_dblib | |
parent | f16b918e471de6cef38f7768f51b5f3deb2c211d (diff) | |
download | php-git-014fd21b482cd1aa8e3fc8662936c18cee300670.tar.gz |
Implemented request #69592: allow 0-column rowsets to be skipped automatically
This adds a new attribute PDO::DBLIB_ATTR_SKIP_EMPTY_ROWSETS to enable automatic
skipping of empty rowsets.
This happens with some SQL commands (like PRINT or SET): a rowset with 0 columns
is returned by the driver.
With this option enabled, 0 columns rowsets are automatically skipped, mirroring
the behavior of the deprecated mssql extension.
Credits go to MiRacLe-RPZ for developping and promoting this patch.
Diffstat (limited to 'ext/pdo_dblib')
-rw-r--r-- | ext/pdo_dblib/dblib_driver.c | 9 | ||||
-rw-r--r-- | ext/pdo_dblib/dblib_stmt.c | 15 | ||||
-rw-r--r-- | ext/pdo_dblib/pdo_dblib.c | 1 | ||||
-rw-r--r-- | ext/pdo_dblib/php_pdo_dblib_int.h | 2 | ||||
-rw-r--r-- | ext/pdo_dblib/tests/bug_69592.phpt | 60 |
5 files changed, 84 insertions, 3 deletions
diff --git a/ext/pdo_dblib/dblib_driver.c b/ext/pdo_dblib/dblib_driver.c index efc8dc1197..e8c010c563 100644 --- a/ext/pdo_dblib/dblib_driver.c +++ b/ext/pdo_dblib/dblib_driver.c @@ -287,6 +287,9 @@ static int dblib_set_attr(pdo_dbh_t *dbh, zend_long attr, zval *val) case PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER: H->stringify_uniqueidentifier = zval_get_long(val); return 1; + case PDO_DBLIB_ATTR_SKIP_EMPTY_ROWSETS: + H->skip_empty_rowsets = zval_is_true(val); + return 1; default: return 0; } @@ -314,6 +317,10 @@ static int dblib_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *return_valu ZVAL_STRING(return_value, dbversion()); break; + case PDO_DBLIB_ATTR_SKIP_EMPTY_ROWSETS: + ZVAL_BOOL(return_value, H->skip_empty_rowsets); + break; + default: return 0; } @@ -387,6 +394,7 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options) H->err.sqlstate = dbh->error_code; H->assume_national_character_set_strings = 0; H->stringify_uniqueidentifier = 0; + H->skip_empty_rowsets = 0; if (!H->login) { goto cleanup; @@ -409,6 +417,7 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options) H->assume_national_character_set_strings = pdo_attr_lval(driver_options, PDO_ATTR_DEFAULT_STR_PARAM, 0) == PDO_PARAM_STR_NATL ? 1 : 0; H->stringify_uniqueidentifier = pdo_attr_lval(driver_options, PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER, 0); + H->skip_empty_rowsets = pdo_attr_lval(driver_options, PDO_DBLIB_ATTR_SKIP_EMPTY_ROWSETS, 0); } DBERRHANDLE(H->login, (EHANDLEFUNC) pdo_dblib_error_handler); diff --git a/ext/pdo_dblib/dblib_stmt.c b/ext/pdo_dblib/dblib_stmt.c index 6c8427da6b..469bd790de 100644 --- a/ext/pdo_dblib/dblib_stmt.c +++ b/ext/pdo_dblib/dblib_stmt.c @@ -124,20 +124,29 @@ static int pdo_dblib_stmt_next_rowset_no_cancel(pdo_stmt_t *stmt) pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data; pdo_dblib_db_handle *H = S->H; RETCODE ret; + int num_fields; + + do { + ret = dbresults(H->link); + num_fields = dbnumcols(H->link); + } while (H->skip_empty_rowsets && num_fields <= 0 && ret == SUCCEED); - ret = dbresults(H->link); if (FAIL == ret) { pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "PDO_DBLIB: dbresults() returned FAIL"); return 0; } - if(NO_MORE_RESULTS == ret) { + if (NO_MORE_RESULTS == ret) { + return 0; + } + + if (H->skip_empty_rowsets && num_fields <= 0) { return 0; } stmt->row_count = DBCOUNT(H->link); - stmt->column_count = dbnumcols(H->link); + stmt->column_count = num_fields; return 1; } diff --git a/ext/pdo_dblib/pdo_dblib.c b/ext/pdo_dblib/pdo_dblib.c index 1732cd75f9..d6a0eda07b 100644 --- a/ext/pdo_dblib/pdo_dblib.c +++ b/ext/pdo_dblib/pdo_dblib.c @@ -195,6 +195,7 @@ PHP_MINIT_FUNCTION(pdo_dblib) REGISTER_PDO_CLASS_CONST_LONG("DBLIB_ATTR_QUERY_TIMEOUT", (long) PDO_DBLIB_ATTR_QUERY_TIMEOUT); REGISTER_PDO_CLASS_CONST_LONG("DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER", (long) PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER); REGISTER_PDO_CLASS_CONST_LONG("DBLIB_ATTR_VERSION", (long) PDO_DBLIB_ATTR_VERSION); + REGISTER_PDO_CLASS_CONST_LONG("DBLIB_ATTR_SKIP_EMPTY_ROWSETS", (long) PDO_DBLIB_ATTR_SKIP_EMPTY_ROWSETS); if (FAIL == dbinit()) { return FAILURE; diff --git a/ext/pdo_dblib/php_pdo_dblib_int.h b/ext/pdo_dblib/php_pdo_dblib_int.h index c40697680f..1b59dd3a38 100644 --- a/ext/pdo_dblib/php_pdo_dblib_int.h +++ b/ext/pdo_dblib/php_pdo_dblib_int.h @@ -118,6 +118,7 @@ typedef struct { pdo_dblib_err err; unsigned assume_national_character_set_strings:1; unsigned stringify_uniqueidentifier:1; + unsigned skip_empty_rowsets:1; } pdo_dblib_db_handle; typedef struct { @@ -150,6 +151,7 @@ enum { PDO_DBLIB_ATTR_QUERY_TIMEOUT, PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER, PDO_DBLIB_ATTR_VERSION, + PDO_DBLIB_ATTR_SKIP_EMPTY_ROWSETS, }; #endif diff --git a/ext/pdo_dblib/tests/bug_69592.phpt b/ext/pdo_dblib/tests/bug_69592.phpt new file mode 100644 index 0000000000..98936618d1 --- /dev/null +++ b/ext/pdo_dblib/tests/bug_69592.phpt @@ -0,0 +1,60 @@ +--TEST-- +PDO_DBLIB: PDO::DBLIB_ATTR_SKIP_EMPTY_ROWSETS for skip junk resultsets on SET NOCOUNT expression +--SKIPIF-- +<?php +if (!extension_loaded('pdo_dblib')) die('skip not loaded'); +require dirname(__FILE__) . '/config.inc'; +?> +--FILE-- +<?php +require dirname(__FILE__) . '/config.inc'; + +$sql = ' + SET NOCOUNT ON + SELECT 0 AS [result] +'; + +var_dump($db->getAttribute(PDO::DBLIB_ATTR_SKIP_EMPTY_ROWSETS)); + +$stmt = $db->query($sql); +var_dump($stmt->fetchAll(PDO::FETCH_ASSOC)); +var_dump($stmt->nextRowset()); +var_dump($stmt->fetchAll(PDO::FETCH_ASSOC)); +$stmt->closeCursor(); + + +$db->setAttribute(PDO::DBLIB_ATTR_SKIP_EMPTY_ROWSETS, true); +var_dump($db->getAttribute(PDO::DBLIB_ATTR_SKIP_EMPTY_ROWSETS)); + +$stmt = $db->query($sql); +var_dump($stmt->fetchAll(PDO::FETCH_ASSOC)); +var_dump($stmt->nextRowset()); +var_dump($stmt->fetchAll(PDO::FETCH_ASSOC)); +$stmt->closeCursor(); +var_dump($db->getAttribute(PDO::DBLIB_ATTR_SKIP_EMPTY_ROWSETS)); + +?> +--EXPECT-- +bool(false) +array(0) { +} +bool(true) +array(1) { + [0]=> + array(1) { + ["result"]=> + int(0) + } +} +bool(true) +array(1) { + [0]=> + array(1) { + ["result"]=> + int(0) + } +} +bool(false) +array(0) { +} +bool(true) |