summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Baratz <adambaratz@php.net>2017-01-27 18:41:11 -0500
committerAdam Baratz <adambaratz@php.net>2017-01-27 18:47:00 -0500
commitf45e6364b46d40a747d183ee11cbaa5c8743a141 (patch)
treea995e62888b75dc02e07a786352eaa720047fdc7
parent9e18f1d4aff855161eeb0de2f4979a2e7eff7175 (diff)
downloadphp-git-f45e6364b46d40a747d183ee11cbaa5c8743a141.tar.gz
Add test coverage for bug #72969
This was not an issue with pdo_dblib, but rather with FreeTDS. FreeTDS has been fixed as of the fc820490336c50d5c175d2a15327383256add4c9 on that repo. These tests will be skipped if a version of FreeTDS with that issue is present. I only cleaned up this commit for pushing. For fixing the FreeTDS issue and writing corresponding pdo_dblib tests, thanks to: Jeff Farr <jefarr@wayfair.com>
-rw-r--r--ext/pdo_dblib/tests/batch_stmt_ins_exec.phpt62
-rw-r--r--ext/pdo_dblib/tests/batch_stmt_ins_sel_up_del.phpt73
-rw-r--r--ext/pdo_dblib/tests/batch_stmt_ins_up.phpt59
-rw-r--r--ext/pdo_dblib/tests/batch_stmt_rowcount.phpt144
-rw-r--r--ext/pdo_dblib/tests/batch_stmt_transaction.phpt111
-rw-r--r--ext/pdo_dblib/tests/batch_stmt_try.phpt99
-rw-r--r--ext/pdo_dblib/tests/config.inc23
7 files changed, 571 insertions, 0 deletions
diff --git a/ext/pdo_dblib/tests/batch_stmt_ins_exec.phpt b/ext/pdo_dblib/tests/batch_stmt_ins_exec.phpt
new file mode 100644
index 0000000000..5d218051e8
--- /dev/null
+++ b/ext/pdo_dblib/tests/batch_stmt_ins_exec.phpt
@@ -0,0 +1,62 @@
+--TEST--
+PDO_DBLIB: driver supports a batch of queries containing SELECT, INSERT, UPDATE, EXEC statements
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo_dblib')) die('skip not loaded');
+require dirname(__FILE__) . '/config.inc';
+
+if (!driver_supports_batch_statements_without_select($db)) die('xfail test will fail with this version of FreeTDS');
+?>
+--FILE--
+<?php
+require dirname(__FILE__) . '/config.inc';
+
+// creating a proc need to be a statement in it's own batch, so we need to do a little setup first
+$db->query("create table #php_pdo(id int); ");
+$db->query(
+"create proc php_pdo_exec_select_proc as " .
+"begin " .
+" insert into #php_pdo values(2), (3), (4); " .
+" select * from #php_pdo; " .
+"end; "
+);
+
+// now lets get some results
+$stmt = $db->query(
+"insert into #php_pdo values(1); " .
+"exec php_pdo_exec_select_proc; " .
+"drop table #php_pdo; " .
+"drop procedure php_pdo_exec_select_proc; ");
+
+// check results from the insert
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the exec
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the drop table
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the drop procedure
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check that there are no more results
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+?>
+--EXPECT--
+int(1)
+bool(true)
+int(-1)
+bool(true)
+int(-1)
+bool(true)
+int(-1)
+bool(false)
+int(-1)
+bool(false)
diff --git a/ext/pdo_dblib/tests/batch_stmt_ins_sel_up_del.phpt b/ext/pdo_dblib/tests/batch_stmt_ins_sel_up_del.phpt
new file mode 100644
index 0000000000..e2c5f6ac47
--- /dev/null
+++ b/ext/pdo_dblib/tests/batch_stmt_ins_sel_up_del.phpt
@@ -0,0 +1,73 @@
+--TEST--
+PDO_DBLIB: driver supports a batch of queries containing SELECT, INSERT, UPDATE statements
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo_dblib')) die('skip not loaded');
+require dirname(__FILE__) . '/config.inc';
+
+if (!driver_supports_batch_statements_without_select($db)) die('xfail test will fail with this version of FreeTDS');
+?>
+--FILE--
+<?php
+require dirname(__FILE__) . '/config.inc';
+
+$stmt = $db->query(
+"create table #php_pdo(id int);" .
+"insert into #php_pdo values(1), (2), (3);" .
+"select * from #php_pdo;" .
+"update #php_pdo set id = 4;" .
+"delete from #php_pdo;" .
+"select * from #php_pdo;" .
+"drop table #php_pdo;"
+);
+
+// check results from the create table
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the first insert
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the select
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the update
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the delete
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the select
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the drop
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check that there are no more results
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+?>
+--EXPECT--
+int(-1)
+bool(true)
+int(3)
+bool(true)
+int(-1)
+bool(true)
+int(3)
+bool(true)
+int(3)
+bool(true)
+int(0)
+bool(true)
+int(-1)
+bool(false)
+int(-1)
+bool(false)
diff --git a/ext/pdo_dblib/tests/batch_stmt_ins_up.phpt b/ext/pdo_dblib/tests/batch_stmt_ins_up.phpt
new file mode 100644
index 0000000000..8f162e7a6d
--- /dev/null
+++ b/ext/pdo_dblib/tests/batch_stmt_ins_up.phpt
@@ -0,0 +1,59 @@
+--TEST--
+PDO_DBLIB: driver supports multiple queries in a single \PDO::query() call that doesn't return any rowsets
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo_dblib')) die('skip not loaded');
+require dirname(__FILE__) . '/config.inc';
+
+if (!driver_supports_batch_statements_without_select($db)) die('xfail test will fail with this version of FreeTDS');
+?>
+--FILE--
+<?php
+require dirname(__FILE__) . '/config.inc';
+
+$stmt = $db->query(
+"create table #php_pdo(id int);" .
+"insert into #php_pdo values(1), (2), (3);" .
+"update #php_pdo set id = 1;" .
+"insert into #php_pdo values(2);" .
+"drop table #php_pdo;"
+);
+
+// check results from the create table
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the first insert
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the update
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the second insert
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the drop
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check that there are no more results
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+?>
+--EXPECT--
+int(-1)
+bool(true)
+int(3)
+bool(true)
+int(3)
+bool(true)
+int(1)
+bool(true)
+int(-1)
+bool(false)
+int(-1)
+bool(false)
diff --git a/ext/pdo_dblib/tests/batch_stmt_rowcount.phpt b/ext/pdo_dblib/tests/batch_stmt_rowcount.phpt
new file mode 100644
index 0000000000..287a7e3528
--- /dev/null
+++ b/ext/pdo_dblib/tests/batch_stmt_rowcount.phpt
@@ -0,0 +1,144 @@
+--TEST--
+PDO_DBLIB: driver supports SET ROWCOUNT and SELECT @@ROWCOUNT in batch statements
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo_dblib')) die('skip not loaded');
+require dirname(__FILE__) . '/config.inc';
+
+if (!driver_supports_batch_statements_without_select($db)) die('xfail test will fail with this version of FreeTDS');
+?>
+--FILE--
+<?php
+require dirname(__FILE__) . '/config.inc';
+
+$stmt = $db->query(
+"create table #php_pdo(id int); " .
+"set rowcount 2; " .
+"insert into #php_pdo values(1), (2), (3); " .
+"insert into #php_pdo values(4), (5), (6); " .
+"update #php_pdo set id = 4; " .
+"select @@rowcount; "
+);
+
+// check results from the create table
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the set rowcount
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the first insert
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the second insert
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the update
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the select rowcount
+var_dump($stmt->fetchAll());
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check that there are no more results
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// now cleanup and check that the results are expected
+$stmt = $db->query("set rowcount 0;" .
+"select * from #php_pdo;" .
+"delete from #php_pdo;" .
+"drop table #php_pdo;"
+);
+
+// check results from set rowcount
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the select
+var_dump($stmt->fetchAll());
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the delete
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the drop
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check that there are no more results
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+?>
+--EXPECT--
+int(-1)
+bool(true)
+int(-1)
+bool(true)
+int(2)
+bool(true)
+int(2)
+bool(true)
+int(2)
+bool(true)
+array(1) {
+ [0]=>
+ array(2) {
+ ["computed"]=>
+ int(2)
+ [0]=>
+ int(2)
+ }
+}
+int(-1)
+bool(false)
+int(-1)
+bool(false)
+int(-1)
+bool(true)
+array(4) {
+ [0]=>
+ array(2) {
+ ["id"]=>
+ int(4)
+ [0]=>
+ int(4)
+ }
+ [1]=>
+ array(2) {
+ ["id"]=>
+ int(4)
+ [0]=>
+ int(4)
+ }
+ [2]=>
+ array(2) {
+ ["id"]=>
+ int(4)
+ [0]=>
+ int(4)
+ }
+ [3]=>
+ array(2) {
+ ["id"]=>
+ int(5)
+ [0]=>
+ int(5)
+ }
+}
+int(-1)
+bool(true)
+int(4)
+bool(true)
+int(-1)
+bool(false)
+int(-1)
+bool(false)
diff --git a/ext/pdo_dblib/tests/batch_stmt_transaction.phpt b/ext/pdo_dblib/tests/batch_stmt_transaction.phpt
new file mode 100644
index 0000000000..d811f6786f
--- /dev/null
+++ b/ext/pdo_dblib/tests/batch_stmt_transaction.phpt
@@ -0,0 +1,111 @@
+--TEST--
+PDO_DBLIB: driver supports a batch of queries containing SELECT, INSERT, UPDATE statements
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo_dblib')) die('skip not loaded');
+require dirname(__FILE__) . '/config.inc';
+
+if (!driver_supports_batch_statements_without_select($db)) die('xfail test will fail with this version of FreeTDS');
+?>
+--FILE--
+<?php
+require dirname(__FILE__) . '/config.inc';
+
+$stmt = $db->query(
+"create table #php_pdo(id int);" .
+"insert into #php_pdo values(1), (2), (3);" .
+"select * from #php_pdo;" .
+"begin transaction;" .
+"update #php_pdo set id = 4;" .
+"rollback transaction;" .
+"select * from #php_pdo;" .
+"delete from #php_pdo;" .
+"drop table #php_pdo;"
+);
+
+// check results from the create table
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the first insert
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the select
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from begin transaction
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the update
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from rollback
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the select
+var_dump($stmt->fetchAll());
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the delete
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the drop
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check that there are no more results
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+?>
+--EXPECT--
+int(-1)
+bool(true)
+int(3)
+bool(true)
+int(-1)
+bool(true)
+int(-1)
+bool(true)
+int(3)
+bool(true)
+int(-1)
+bool(true)
+array(3) {
+ [0]=>
+ array(2) {
+ ["id"]=>
+ int(1)
+ [0]=>
+ int(1)
+ }
+ [1]=>
+ array(2) {
+ ["id"]=>
+ int(2)
+ [0]=>
+ int(2)
+ }
+ [2]=>
+ array(2) {
+ ["id"]=>
+ int(3)
+ [0]=>
+ int(3)
+ }
+}
+int(-1)
+bool(true)
+int(3)
+bool(true)
+int(-1)
+bool(false)
+int(-1)
+bool(false)
diff --git a/ext/pdo_dblib/tests/batch_stmt_try.phpt b/ext/pdo_dblib/tests/batch_stmt_try.phpt
new file mode 100644
index 0000000000..0f74d0b701
--- /dev/null
+++ b/ext/pdo_dblib/tests/batch_stmt_try.phpt
@@ -0,0 +1,99 @@
+--TEST--
+PDO_DBLIB: driver supports exceptions
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo_dblib')) die('skip not loaded');
+require dirname(__FILE__) . '/config.inc';
+
+if (!driver_supports_batch_statements_without_select($db)) die('xfail test will fail with this version of FreeTDS');
+?>
+--FILE--
+<?php
+require dirname(__FILE__) . '/config.inc';
+
+$stmt = $db->query(
+"create table #php_pdo(id int);" .
+"insert into #php_pdo values(1), (2), (3);" .
+"select * from #php_pdo;" .
+"begin try " .
+" update #php_pdo set id = 'f';" .
+"end try " .
+"begin catch " .
+" throw;" .
+"end catch " .
+"select * from #php_pdo;" .
+"delete from #php_pdo;" .
+"drop table #php_pdo;"
+);
+
+// check results from the create table
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the first insert
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the select
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from try
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the update
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check that the update statement throws an error
+try {
+ var_dump($stmt->rowCount());
+ var_dump($stmt->nextRowset());
+} catch (PDOException $e) {
+ var_dump($e->getMessage());
+}
+
+// once an error is thrown, the batch is terminated.
+// there should no results from here on
+// check results from the select
+var_dump($stmt->fetchAll());
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the delete
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check results from the drop
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+// check that there are no more results
+var_dump($stmt->rowCount());
+var_dump($stmt->nextRowset());
+
+?>
+--EXPECT--
+int(-1)
+bool(true)
+int(3)
+bool(true)
+int(-1)
+bool(true)
+int(-1)
+bool(true)
+int(0)
+bool(true)
+int(-1)
+string(68) "SQLSTATE[HY000]: General error: PDO_DBLIB: dbresults() returned FAIL"
+array(0) {
+}
+int(-1)
+bool(false)
+int(-1)
+bool(false)
+int(-1)
+bool(false)
+int(-1)
+bool(false)
diff --git a/ext/pdo_dblib/tests/config.inc b/ext/pdo_dblib/tests/config.inc
index 3cc81f39b2..40e8bf6ff9 100644
--- a/ext/pdo_dblib/tests/config.inc
+++ b/ext/pdo_dblib/tests/config.inc
@@ -16,6 +16,29 @@ function get_tds_version() {
return null;
}
+// bug #72969 reflects a bug with FreeTDS, not with pdo_dblib
+// this function will version detect so the relevant tests can XFAILIF
+function driver_supports_batch_statements_without_select($db) {
+ $version = $db->getAttribute(PDO::DBLIB_ATTR_VERSION);
+
+ // assume driver doesn't have this bug if not using FreeTDS
+ if (!strstartswith($version, 'freetds ')) {
+ return true;
+ }
+
+ // hasn't made it to numbered release yet
+ if (!strstartswith($version, 'freetds v1.1.dev.')) {
+ return false;
+ }
+
+ // fc820490336c50d5c175d2a15327383256add4c9 was committed on the 5th
+ return intval(substr($version, -8)) >= 20161206;
+}
+
+function strstartswith($haystack, $needle) {
+ return $needle === "" || strrpos($haystack, $needle, -strlen($haystack)) !== false;
+}
+
if (false !== getenv('PDO_DBLIB_TEST_DSN')) {
$dsn = getenv('PDO_DBLIB_TEST_DSN');
} else {