summaryrefslogtreecommitdiff
path: root/ext/pdo_dblib
diff options
context:
space:
mode:
authorfandrieu <fandrieu@gmail.com>2017-10-17 14:16:38 -0400
committerAdam Baratz <adambaratz@php.net>2017-10-17 14:16:38 -0400
commit014fd21b482cd1aa8e3fc8662936c18cee300670 (patch)
treea5417a29cbc6b0d9bcc8c9928ec52bebebb4bce4 /ext/pdo_dblib
parentf16b918e471de6cef38f7768f51b5f3deb2c211d (diff)
downloadphp-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.c9
-rw-r--r--ext/pdo_dblib/dblib_stmt.c15
-rw-r--r--ext/pdo_dblib/pdo_dblib.c1
-rw-r--r--ext/pdo_dblib/php_pdo_dblib_int.h2
-rw-r--r--ext/pdo_dblib/tests/bug_69592.phpt60
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)