summaryrefslogtreecommitdiff
path: root/ext/pdo/tests
diff options
context:
space:
mode:
Diffstat (limited to 'ext/pdo/tests')
-rw-r--r--ext/pdo/tests/bug47769.phpt37
-rw-r--r--ext/pdo/tests/bug61292.phpt36
-rw-r--r--ext/pdo/tests/bug_34630.phpt57
-rw-r--r--ext/pdo/tests/bug_34687.phpt32
-rw-r--r--ext/pdo/tests/bug_35671.phpt45
-rw-r--r--ext/pdo/tests/bug_36428.phpt33
-rw-r--r--ext/pdo/tests/bug_36798.phpt39
-rw-r--r--ext/pdo/tests/bug_38253.phpt53
-rw-r--r--ext/pdo/tests/bug_38394.phpt51
-rw-r--r--ext/pdo/tests/bug_39398.phpt35
-rw-r--r--ext/pdo/tests/bug_39656.phpt51
-rw-r--r--ext/pdo/tests/bug_40285.phpt27
-rw-r--r--ext/pdo/tests/bug_42917.phpt40
-rw-r--r--ext/pdo/tests/bug_43130.phpt40
-rw-r--r--ext/pdo/tests/bug_43139.phpt41
-rw-r--r--ext/pdo/tests/bug_43663.phpt31
-rw-r--r--ext/pdo/tests/bug_44159.phpt43
-rw-r--r--ext/pdo/tests/bug_44173.phpt78
-rw-r--r--ext/pdo/tests/bug_44409.phpt51
-rw-r--r--ext/pdo/tests/bug_44861.phpt106
-rw-r--r--ext/pdo/tests/bug_50458.phpt29
-rw-r--r--ext/pdo/tests/pdo.inc10
-rw-r--r--ext/pdo/tests/pdo_001.phpt50
-rw-r--r--ext/pdo/tests/pdo_002.phpt50
-rw-r--r--ext/pdo/tests/pdo_003.phpt62
-rw-r--r--ext/pdo/tests/pdo_004.phpt50
-rw-r--r--ext/pdo/tests/pdo_005.phpt154
-rw-r--r--ext/pdo/tests/pdo_006.phpt77
-rw-r--r--ext/pdo/tests/pdo_007.phpt65
-rw-r--r--ext/pdo/tests/pdo_008.phpt40
-rw-r--r--ext/pdo/tests/pdo_009.phpt131
-rw-r--r--ext/pdo/tests/pdo_010.phpt119
-rw-r--r--ext/pdo/tests/pdo_011.phpt301
-rw-r--r--ext/pdo/tests/pdo_012.phpt98
-rw-r--r--ext/pdo/tests/pdo_013.phpt96
-rw-r--r--ext/pdo/tests/pdo_014.phpt102
-rw-r--r--ext/pdo/tests/pdo_015.phpt100
-rw-r--r--ext/pdo/tests/pdo_016.phpt204
-rw-r--r--ext/pdo/tests/pdo_016a.phpt204
-rw-r--r--ext/pdo/tests/pdo_017.phpt74
-rw-r--r--ext/pdo/tests/pdo_018.phpt276
-rw-r--r--ext/pdo/tests/pdo_019.phpt71
-rw-r--r--ext/pdo/tests/pdo_020.phpt34
-rw-r--r--ext/pdo/tests/pdo_021.phpt59
-rw-r--r--ext/pdo/tests/pdo_022.phpt62
-rw-r--r--ext/pdo/tests/pdo_023.phpt112
-rw-r--r--ext/pdo/tests/pdo_024.phpt35
-rw-r--r--ext/pdo/tests/pdo_025.phpt113
-rw-r--r--ext/pdo/tests/pdo_026.phpt111
-rw-r--r--ext/pdo/tests/pdo_027.phpt29
-rw-r--r--ext/pdo/tests/pdo_028.phpt45
-rw-r--r--ext/pdo/tests/pdo_029.phpt125
-rw-r--r--ext/pdo/tests/pdo_030.phpt139
-rw-r--r--ext/pdo/tests/pdo_031.phpt63
-rw-r--r--ext/pdo/tests/pdo_032.phpt83
-rw-r--r--ext/pdo/tests/pdo_033.phpt44
-rw-r--r--ext/pdo/tests/pdo_034.phpt62
-rw-r--r--ext/pdo/tests/pdo_035.phpt22
-rw-r--r--ext/pdo/tests/pdo_036.phpt23
-rw-r--r--ext/pdo/tests/pdo_037.phpt19
-rw-r--r--ext/pdo/tests/pdo_test.inc84
-rw-r--r--ext/pdo/tests/pdorow.phpt12
-rw-r--r--ext/pdo/tests/pecl_bug_5217.phpt29
-rw-r--r--ext/pdo/tests/pecl_bug_5772.phpt29
-rw-r--r--ext/pdo/tests/pecl_bug_5809.phpt34
65 files changed, 4657 insertions, 0 deletions
diff --git a/ext/pdo/tests/bug47769.phpt b/ext/pdo/tests/bug47769.phpt
new file mode 100644
index 0000000..3b2f1e8
--- /dev/null
+++ b/ext/pdo/tests/bug47769.phpt
@@ -0,0 +1,37 @@
+--TEST--
+Bug #47769 (Strange extends PDO)
+--SKIPIF--
+<?php
+if (!extension_loaded("pdo_sqlite"))
+ die("skip: PDO_SQLite not available");
+?>
+--FILE--
+<?php
+
+class test extends PDO
+{
+ protected function isProtected() {
+ echo "this is a protected method.\n";
+ }
+ private function isPrivate() {
+ echo "this is a private method.\n";
+ }
+
+ public function quote($str, $paramtype = NULL) {
+ $this->isProtected();
+ $this->isPrivate();
+ print $str ."\n";
+ }
+}
+
+$test = new test('sqlite::memory:');
+$test->quote('foo');
+$test->isProtected();
+
+?>
+--EXPECTF--
+this is a protected method.
+this is a private method.
+foo
+
+Fatal error: Call to protected method test::isProtected() from context '' in %s on line %d
diff --git a/ext/pdo/tests/bug61292.phpt b/ext/pdo/tests/bug61292.phpt
new file mode 100644
index 0000000..2381fd1
--- /dev/null
+++ b/ext/pdo/tests/bug61292.phpt
@@ -0,0 +1,36 @@
+--TEST--
+Bug #61292 (Segfault while calling a method on an overloaded PDO object)
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+
+class Database_SQL extends PDO
+{
+ function __construct()
+ {
+ $options = array(PDO::ATTR_PERSISTENT => TRUE);
+ parent::__construct(getenv("PDOTEST_DSN"), getenv("PDOTEST_USER"), getenv("PDOTEST_PASS"), $options);
+ }
+
+ var $bar = array();
+
+ public function foo()
+ {
+ var_dump($this->bar);
+ }
+}
+
+(new Database_SQL)->foo();
+?>
+--EXPECTF--
+array(0) {
+}
diff --git a/ext/pdo/tests/bug_34630.phpt b/ext/pdo/tests/bug_34630.phpt
new file mode 100644
index 0000000..070217b
--- /dev/null
+++ b/ext/pdo/tests/bug_34630.phpt
@@ -0,0 +1,57 @@
+--TEST--
+PDO Common: Bug #34630 (inserting streams as LOBs)
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$driver = $db->getAttribute(PDO::ATTR_DRIVER_NAME);
+$is_oci = $driver == 'oci';
+
+if ($is_oci) {
+ $db->exec('CREATE TABLE test (id int NOT NULL PRIMARY KEY, val BLOB)');
+} else {
+ $db->exec('CREATE TABLE test (id int NOT NULL PRIMARY KEY, val VARCHAR(256))');
+}
+$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+
+$fp = tmpfile();
+fwrite($fp, "I am the LOB data");
+rewind($fp);
+
+if ($is_oci) {
+ /* oracle is a bit different; you need to initiate a transaction otherwise
+ * the empty blob will be committed implicitly when the statement is
+ * executed */
+ $db->beginTransaction();
+ $insert = $db->prepare("insert into test (id, val) values (1, EMPTY_BLOB()) RETURNING val INTO :blob");
+} else {
+ $insert = $db->prepare("insert into test (id, val) values (1, :blob)");
+}
+$insert->bindValue(':blob', $fp, PDO::PARAM_LOB);
+$insert->execute();
+$insert = null;
+
+$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true);
+var_dump($db->query("SELECT * from test")->fetchAll(PDO::FETCH_ASSOC));
+
+?>
+--EXPECT--
+array(1) {
+ [0]=>
+ array(2) {
+ ["id"]=>
+ string(1) "1"
+ ["val"]=>
+ string(17) "I am the LOB data"
+ }
+}
diff --git a/ext/pdo/tests/bug_34687.phpt b/ext/pdo/tests/bug_34687.phpt
new file mode 100644
index 0000000..dbb1471
--- /dev/null
+++ b/ext/pdo/tests/bug_34687.phpt
@@ -0,0 +1,32 @@
+--TEST--
+PDO Common: Bug #34687 (query doesn't return error information)
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
+$x = $db->query("UPDATE non_existent_pdo_test_table set foo = 'bar'");
+
+var_dump($x);
+$code = $db->errorCode();
+if ($code !== '00000' && strlen($code)) {
+ echo "OK: $code\n";
+} else {
+ echo "ERR: $code\n";
+ print_r($db->errorInfo());
+}
+
+?>
+--EXPECTF--
+bool(false)
+OK: %s
diff --git a/ext/pdo/tests/bug_35671.phpt b/ext/pdo/tests/bug_35671.phpt
new file mode 100644
index 0000000..8d1e114
--- /dev/null
+++ b/ext/pdo/tests/bug_35671.phpt
@@ -0,0 +1,45 @@
+--TEST--
+PDO Common: Bug #35671 (binding by name breakage)
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test (field1 VARCHAR(32), field2 VARCHAR(32), field3 VARCHAR(32))');
+$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+
+$insert = $db->prepare("insert into test (field1, field2, field3) values (:value1, :value2, :value3)");
+
+$parm = array(
+ ":value1" => 15,
+ ":value2" => 20,
+ ":value3" => 25
+);
+
+$insert->execute($parm);
+$insert = null;
+
+var_dump($db->query("SELECT * from test")->fetchAll(PDO::FETCH_ASSOC));
+
+?>
+--EXPECT--
+array(1) {
+ [0]=>
+ array(3) {
+ ["field1"]=>
+ string(2) "15"
+ ["field2"]=>
+ string(2) "20"
+ ["field3"]=>
+ string(2) "25"
+ }
+}
diff --git a/ext/pdo/tests/bug_36428.phpt b/ext/pdo/tests/bug_36428.phpt
new file mode 100644
index 0000000..703b9d4
--- /dev/null
+++ b/ext/pdo/tests/bug_36428.phpt
@@ -0,0 +1,33 @@
+--TEST--
+PDO Common: Bug #36428 (Incorrect error message for PDO::fetchAll())
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+if (!extension_loaded('simplexml')) die('skip SimpleXML not loaded');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+
+$db = PDOTest::factory();
+$db->exec("CREATE TABLE test (a VARCHAR(10))");
+$db->exec("INSERT INTO test (a) VALUES ('xyz')");
+$res = $db->query("SELECT a FROM test");
+var_dump($res->fetchAll(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, 'SimpleXMLElement', array('<root/>')));
+
+?>
+===DONE===
+--EXPECTF--
+array(1) {
+ [0]=>
+ object(SimpleXMLElement)#%d (1) {
+ ["a"]=>
+ string(3) "xyz"
+ }
+}
+===DONE===
diff --git a/ext/pdo/tests/bug_36798.phpt b/ext/pdo/tests/bug_36798.phpt
new file mode 100644
index 0000000..9da703e
--- /dev/null
+++ b/ext/pdo/tests/bug_36798.phpt
@@ -0,0 +1,39 @@
+--TEST--
+PDO Common: Bug #36798 (Error parsing named parameters with queries containing high-ascii chars)
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+
+if (!strncasecmp(getenv('PDOTEST_DSN'), 'oci', strlen('oci'))){
+ if (!strpos(strtolower(getenv('PDOTEST_DSN')), 'charset=we8mswin1252')) die('skip expected output valid for Oracle with WE8MSWIN1252 character set');
+
+}
+
+?>
+--FILE--
+<?php
+
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+@$db->exec("SET NAMES 'LATIN1'"); // needed for PostgreSQL
+$db->exec("CREATE TABLE test (id INTEGER)");
+$db->exec("INSERT INTO test (id) VALUES (1)");
+
+$stmt = $db->prepare("SELECT 'Ã' as test FROM test WHERE id = :id");
+$stmt->execute(array(":id" => 1));
+
+$row = $stmt->fetch(PDO::FETCH_NUM);
+var_dump( $row );
+
+?>
+--EXPECT--
+array(1) {
+ [0]=>
+ string(1) "Ã"
+}
diff --git a/ext/pdo/tests/bug_38253.phpt b/ext/pdo/tests/bug_38253.phpt
new file mode 100644
index 0000000..4453c3b
--- /dev/null
+++ b/ext/pdo/tests/bug_38253.phpt
@@ -0,0 +1,53 @@
+--TEST--
+PDO Common: Bug #38253 (PDO produces segfault with default fetch mode)
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$pdo = PDOTest::factory();
+
+$pdo->exec ("create table test (id integer primary key, n varchar(255))");
+$pdo->exec ("INSERT INTO test (id, n) VALUES (1, 'hi')");
+
+$pdo->setAttribute (PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_CLASS);
+$stmt = $pdo->prepare ("SELECT * FROM test");
+$stmt->execute();
+var_dump($stmt->fetchAll());
+
+$pdo = PDOTest::factory();
+
+if ($pdo->getAttribute(PDO::ATTR_DRIVER_NAME) == 'oci') {
+ $type = "clob";
+} else{
+ $type = "text";
+}
+
+$pdo->exec ("create table test2 (id integer primary key, n $type)");
+$pdo->exec ("INSERT INTO test2 (id, n) VALUES (1,'hi')");
+
+$pdo->setAttribute (PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_FUNC);
+$stmt = $pdo->prepare ("SELECT * FROM test2");
+$stmt->execute();
+var_dump($stmt->fetchAll());
+
+?>
+--EXPECTF--
+Warning: PDOStatement::fetchAll(): SQLSTATE[HY000]: General error: No fetch class specified in %s on line %d
+
+Warning: PDOStatement::fetchAll(): SQLSTATE[HY000]: General error%s on line %d
+array(0) {
+}
+
+Warning: PDOStatement::fetchAll(): SQLSTATE[HY000]: General error: No fetch function specified in %s on line %d
+
+Warning: PDOStatement::fetchAll(): SQLSTATE[HY000]: General error%s on line %d
+array(0) {
+}
diff --git a/ext/pdo/tests/bug_38394.phpt b/ext/pdo/tests/bug_38394.phpt
new file mode 100644
index 0000000..be990b3
--- /dev/null
+++ b/ext/pdo/tests/bug_38394.phpt
@@ -0,0 +1,51 @@
+--TEST--
+PDO Common: Bug #38394 (Prepared statement error stops subsequent statements)
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+if (!strncasecmp(getenv('PDOTEST_DSN'), 'sqlite2', strlen('sqlite2'))) die('skip not relevant for pdo_sqlite2 driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+
+$db = PDOTest::factory();
+$db->exec("CREATE TABLE test (a INT, b INT, c INT)");
+$s = $db->prepare("INSERT INTO test (a,b,c) VALUES (:a,:b,:c)");
+
+$s->execute(array('a' => 1, 'b' => 2, 'c' => 3));
+
+@$s->execute(array('a' => 5, 'b' => 6, 'c' => 7, 'd' => 8));
+
+$s->execute(array('a' => 9, 'b' => 10, 'c' => 11));
+
+var_dump($db->query("SELECT * FROM test")->fetchAll(PDO::FETCH_ASSOC));
+?>
+===DONE===
+--EXPECTF--
+array(2) {
+ [0]=>
+ array(3) {
+ ["a"]=>
+ string(1) "1"
+ ["b"]=>
+ string(1) "2"
+ ["c"]=>
+ string(1) "3"
+ }
+ [1]=>
+ array(3) {
+ ["a"]=>
+ string(1) "9"
+ ["b"]=>
+ string(2) "10"
+ ["c"]=>
+ string(2) "11"
+ }
+}
+===DONE===
diff --git a/ext/pdo/tests/bug_39398.phpt b/ext/pdo/tests/bug_39398.phpt
new file mode 100644
index 0000000..633771a
--- /dev/null
+++ b/ext/pdo/tests/bug_39398.phpt
@@ -0,0 +1,35 @@
+--TEST--
+PDO Common: Bug #39398 (Booleans are not automatically translated to integers)
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+
+$db = PDOTest::factory();
+$db->exec("CREATE TABLE test (test INT)");
+
+$boolean = 1;
+$stmt = $db->prepare('INSERT INTO test VALUES (:boolean)');
+$stmt->bindValue(':boolean', isset($boolean), PDO::PARAM_INT);
+$stmt->execute();
+
+var_dump($db->query("SELECT * FROM test")->fetchAll(PDO::FETCH_ASSOC));
+?>
+===DONE===
+--EXPECT--
+array(1) {
+ [0]=>
+ array(1) {
+ ["test"]=>
+ string(1) "1"
+ }
+}
+===DONE===
diff --git a/ext/pdo/tests/bug_39656.phpt b/ext/pdo/tests/bug_39656.phpt
new file mode 100644
index 0000000..7d113ef
--- /dev/null
+++ b/ext/pdo/tests/bug_39656.phpt
@@ -0,0 +1,51 @@
+--TEST--
+PDO Common: Bug #39656 (Crash when calling fetch() on a PDO statment object after closeCursor())
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+@$db->exec("DROP TABLE test");
+$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+
+$db->exec("CREATE TABLE test (id INTEGER NOT NULL PRIMARY KEY, usr VARCHAR( 256 ) NOT NULL)");
+$db->exec("INSERT INTO test (id, usr) VALUES (1, 'user')");
+
+$stmt = $db->prepare("SELECT * FROM test WHERE id = ?");
+$stmt->bindValue(1, 1, PDO::PARAM_INT );
+$stmt->execute();
+$row = $stmt->fetch();
+var_dump( $row );
+
+$stmt->execute();
+$stmt->closeCursor();
+$row = $stmt->fetch(); // this line will crash CLI
+var_dump( $row );
+
+@$db->exec("DROP TABLE test");
+echo "Done\n";
+?>
+--EXPECT--
+array(4) {
+ ["id"]=>
+ string(1) "1"
+ [0]=>
+ string(1) "1"
+ ["usr"]=>
+ string(4) "user"
+ [1]=>
+ string(4) "user"
+}
+bool(false)
+Done
+
diff --git a/ext/pdo/tests/bug_40285.phpt b/ext/pdo/tests/bug_40285.phpt
new file mode 100644
index 0000000..c0a5674
--- /dev/null
+++ b/ext/pdo/tests/bug_40285.phpt
@@ -0,0 +1,27 @@
+--TEST--
+PDO Common: Bug #40285 (The prepare parser goes into an infinite loop on ': or ":)
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test (field1 VARCHAR(32), field2 VARCHAR(32), field3 VARCHAR(32), field4 INT)');
+
+$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
+$s = $db->prepare("INSERT INTO test VALUES( ':id', 'name', 'section', 22)" );
+$s->execute();
+
+echo "Done\n";
+?>
+--EXPECT--
+Done
diff --git a/ext/pdo/tests/bug_42917.phpt b/ext/pdo/tests/bug_42917.phpt
new file mode 100644
index 0000000..d4b71f5
--- /dev/null
+++ b/ext/pdo/tests/bug_42917.phpt
@@ -0,0 +1,40 @@
+--TEST--
+PDO Common: Bug #42917 (PDO::FETCH_KEY_PAIR doesn't work with setFetchMode)
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec("CREATE TABLE test (a varchar(100), b varchar(100), c varchar(100))");
+
+for ($i = 0; $i < 5; $i++) {
+ $db->exec("INSERT INTO test (a,b,c) VALUES('test".$i."','".$i."','".$i."')");
+}
+
+$res = $db->query("SELECT a,b FROM test");
+$res->setFetchMode(PDO::FETCH_KEY_PAIR);
+var_dump($res->fetchAll());
+
+?>
+--EXPECT--
+array(5) {
+ ["test0"]=>
+ string(1) "0"
+ ["test1"]=>
+ string(1) "1"
+ ["test2"]=>
+ string(1) "2"
+ ["test3"]=>
+ string(1) "3"
+ ["test4"]=>
+ string(1) "4"
+}
diff --git a/ext/pdo/tests/bug_43130.phpt b/ext/pdo/tests/bug_43130.phpt
new file mode 100644
index 0000000..70f8887
--- /dev/null
+++ b/ext/pdo/tests/bug_43130.phpt
@@ -0,0 +1,40 @@
+--TEST--
+PDO Common: Bug #43130 (Bound parameters cannot have - in their name)
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+if (!strncasecmp(getenv('PDOTEST_DSN'), 'sqlite', strlen('sqlite'))) die('skip not relevant for sqlite driver');
+if (!strncasecmp(getenv('PDOTEST_DSN'), 'pgsql', strlen('pgsql'))) die('skip not relevant for pgsql driver');
+if (!strncasecmp(getenv('PDOTEST_DSN'), 'oci', strlen('oci'))) die('skip not relevant for oci driver - Hyphen is not legal for bind names in Oracle DB');
+if (!strncasecmp(getenv('PDOTEST_DSN'), 'firebird', strlen('firebird'))) die('skip not relevant for firebird driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+if ($db->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql')
+ $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1);
+
+$db->exec("CREATE TABLE test (a varchar(100), b varchar(100), c varchar(100))");
+
+for ($i = 0; $i < 5; $i++) {
+ $db->exec("INSERT INTO test (a,b,c) VALUES('test".$i."','".$i."','".$i."')");
+}
+
+$stmt = $db->prepare("SELECT a FROM test WHERE b=:id-value");
+$stmt->bindParam(':id-value', $id);
+$id = '1';
+$stmt->execute();
+var_dump($stmt->fetch(PDO::FETCH_COLUMN));
+?>
+--EXPECTF--
+Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: parameter was not defined in %s on line %d
+
+Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number in %s on line %d
+bool(false)
diff --git a/ext/pdo/tests/bug_43139.phpt b/ext/pdo/tests/bug_43139.phpt
new file mode 100644
index 0000000..87bfd4e
--- /dev/null
+++ b/ext/pdo/tests/bug_43139.phpt
@@ -0,0 +1,41 @@
+--TEST--
+PDO Common: Bug #43139 (PDO ignore ATTR_DEFAULT_FETCH_MODE in some cases with fetchAll())
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
+$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
+
+$from = '';
+if ($db->getAttribute(PDO::ATTR_DRIVER_NAME) == 'oci') {
+ $from = 'from dual';
+} else if ($db->getAttribute(PDO::ATTR_DRIVER_NAME) == 'firebird') {
+ $from = 'FROM RDB$DATABASE';
+}
+
+var_dump($db->query("select 0 as abc, 1 as xyz, 2 as def $from")->fetchAll(PDO::FETCH_GROUP));
+?>
+--EXPECT--
+array(1) {
+ [0]=>
+ array(1) {
+ [0]=>
+ array(2) {
+ ["xyz"]=>
+ string(1) "1"
+ ["def"]=>
+ string(1) "2"
+ }
+ }
+}
diff --git a/ext/pdo/tests/bug_43663.phpt b/ext/pdo/tests/bug_43663.phpt
new file mode 100644
index 0000000..f8e968f
--- /dev/null
+++ b/ext/pdo/tests/bug_43663.phpt
@@ -0,0 +1,31 @@
+--TEST--
+PDO Common: Bug #43663 (__call on classes derived from PDO)
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+if (!extension_loaded('pdo_sqlite')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+class test extends PDO{
+ function __call($name, array $args) {
+ echo "Called $name in ".__CLASS__."\n";
+ }
+ function foo() {
+ echo "Called foo in ".__CLASS__."\n";
+ }
+}
+
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+
+$a = new test('sqlite::memory:');
+$a->foo();
+$a->bar();
+--EXPECT--
+Called foo in test
+Called bar in test
diff --git a/ext/pdo/tests/bug_44159.phpt b/ext/pdo/tests/bug_44159.phpt
new file mode 100644
index 0000000..9f1961c
--- /dev/null
+++ b/ext/pdo/tests/bug_44159.phpt
@@ -0,0 +1,43 @@
+--TEST--
+Bug #44159 (Crash: $pdo->setAttribute(PDO::STATEMENT_ATTR_CLASS, NULL))
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip PDO not available');
+try {
+ $pdo = new PDO("sqlite:".__DIR__."/foo.db");
+} catch (Exception $e) {
+ die("skip PDP_SQLITE not available");
+}
+?>
+--FILE--
+<?php
+$pdo = new PDO("sqlite:".__DIR__."/foo.db");
+
+$attrs = array(PDO::ATTR_STATEMENT_CLASS, PDO::ATTR_STRINGIFY_FETCHES, PDO::NULL_TO_STRING);
+
+foreach ($attrs as $attr) {
+ var_dump($pdo->setAttribute($attr, NULL));
+ var_dump($pdo->setAttribute($attr, 1));
+ var_dump($pdo->setAttribute($attr, 'nonsense'));
+}
+
+@unlink(__DIR__."/foo.db");
+
+?>
+--EXPECTF--
+Warning: PDO::setAttribute(): SQLSTATE[HY000]: General error: PDO::ATTR_STATEMENT_CLASS requires format array(classname, array(ctor_args)); the classname must be a string specifying an existing class in %s on line %d
+bool(false)
+
+Warning: PDO::setAttribute(): SQLSTATE[HY000]: General error: PDO::ATTR_STATEMENT_CLASS requires format array(classname, array(ctor_args)); the classname must be a string specifying an existing class in %s on line %d
+bool(false)
+
+Warning: PDO::setAttribute(): SQLSTATE[HY000]: General error: PDO::ATTR_STATEMENT_CLASS requires format array(classname, array(ctor_args)); the classname must be a string specifying an existing class in %s on line %d
+bool(false)
+
+Warning: PDO::setAttribute(): SQLSTATE[HY000]: General error: attribute value must be an integer in %s on line %d
+bool(false)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
diff --git a/ext/pdo/tests/bug_44173.phpt b/ext/pdo/tests/bug_44173.phpt
new file mode 100644
index 0000000..f13abaa
--- /dev/null
+++ b/ext/pdo/tests/bug_44173.phpt
@@ -0,0 +1,78 @@
+--TEST--
+PDO Common: Bug #44173 (PDO->query() parameter parsing/checking needs an update)
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec("CREATE TABLE test (x int)");
+$db->exec("INSERT INTO test VALUES (1)");
+
+
+// Bug entry [1]
+$stmt = $db->query();
+var_dump($stmt);
+
+
+// Bug entry [2] -- 1 is PDO::FETCH_LAZY
+$stmt = $db->query("SELECT * FROM test", PDO::FETCH_LAZY, 0, 0);
+var_dump($stmt);
+
+
+// Bug entry [3]
+$stmt = $db->query("SELECT * FROM test", 'abc');
+var_dump($stmt);
+
+
+// Bug entry [4]
+$stmt = $db->query("SELECT * FROM test", PDO::FETCH_CLASS, 0, 0, 0);
+var_dump($stmt);
+
+
+// Bug entry [5]
+$stmt = $db->query("SELECT * FROM test", PDO::FETCH_INTO);
+var_dump($stmt);
+
+
+// Bug entry [6]
+$stmt = $db->query("SELECT * FROM test", PDO::FETCH_COLUMN);
+var_dump($stmt);
+
+
+// Bug entry [7]
+$stmt = $db->query("SELECT * FROM test", PDO::FETCH_CLASS);
+var_dump($stmt);
+
+
+?>
+--EXPECTF--
+Warning: PDO::query() expects at least 1 parameter, 0 given in %s
+bool(false)
+
+Warning: PDO::query(): SQLSTATE[HY000]: General error: fetch mode doesn't allow any extra arguments in %s
+bool(false)
+
+Warning: PDO::query(): SQLSTATE[HY000]: General error: mode must be an integer in %s
+bool(false)
+
+Warning: PDO::query(): SQLSTATE[HY000]: General error: too many arguments in %s
+bool(false)
+
+Warning: PDO::query(): SQLSTATE[HY000]: General error: fetch mode requires the object parameter in %s
+bool(false)
+
+Warning: PDO::query(): SQLSTATE[HY000]: General error: fetch mode requires the colno argument in %s
+bool(false)
+
+Warning: PDO::query(): SQLSTATE[HY000]: General error: fetch mode requires the classname argument in %s
+bool(false)
+
diff --git a/ext/pdo/tests/bug_44409.phpt b/ext/pdo/tests/bug_44409.phpt
new file mode 100644
index 0000000..fe24fdf
--- /dev/null
+++ b/ext/pdo/tests/bug_44409.phpt
@@ -0,0 +1,51 @@
+--TEST--
+PDO Common: Bug #44409 (PDO::FETCH_SERIALIZE calls __construct())
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec("CREATE TABLE test (dat varchar(100))");
+$db->exec("INSERT INTO test (dat) VALUES ('Data from DB')");
+
+class bug44409 implements Serializable
+{
+ public function __construct()
+ {
+ printf("Method called: %s()\n", __METHOD__);
+ }
+
+ public function serialize()
+ {
+ return "any data from serizalize()";
+ }
+
+ public function unserialize($dat)
+ {
+ printf("Method called: %s(%s)\n", __METHOD__, var_export($dat, true));
+ }
+}
+
+$stmt = $db->query("SELECT * FROM test");
+
+print_r($stmt->fetchAll(PDO::FETCH_CLASS|PDO::FETCH_SERIALIZE, "bug44409"));
+
+?>
+--EXPECT--
+Method called: bug44409::unserialize('Data from DB')
+Array
+(
+ [0] => bug44409 Object
+ (
+ )
+
+)
diff --git a/ext/pdo/tests/bug_44861.phpt b/ext/pdo/tests/bug_44861.phpt
new file mode 100644
index 0000000..cb8e657
--- /dev/null
+++ b/ext/pdo/tests/bug_44861.phpt
@@ -0,0 +1,106 @@
+--TEST--
+PDO Common: Bug #44861 (scrollable cursor don't work with pgsql)
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+$allowed = array('oci', 'pgsql');
+$ok = false;
+foreach ($allowed as $driver) {
+ if (!strncasecmp(getenv('PDOTEST_DSN'), $driver, strlen($driver))) {
+ $ok = true;
+ }
+}
+if (!$ok) {
+ die("skip Scrollable cursors not supported");
+}
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+
+if ($db->getAttribute(PDO::ATTR_DRIVER_NAME) == 'oci') {
+ $from = 'FROM DUAL';
+ $ob = '1';
+} else {
+ $from = '';
+ $ob = 'r';
+}
+
+$query = "SELECT 'row1' AS r $from UNION SELECT 'row2' $from UNION SELECT 'row3' $from UNION SELECT 'row4' $from ORDER BY $ob";
+$aParams = array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL);
+
+$res = $db->prepare($query, $aParams);
+$res->execute();
+var_dump($res->fetchColumn());
+var_dump($res->fetchColumn());
+var_dump($res->fetchColumn());
+var_dump($res->fetchColumn());
+var_dump($res->fetchColumn());
+
+var_dump($res->fetch(PDO::FETCH_NUM, PDO::FETCH_ORI_ABS, 3));
+var_dump($res->fetch(PDO::FETCH_NUM, PDO::FETCH_ORI_PRIOR));
+var_dump($res->fetch(PDO::FETCH_NUM, PDO::FETCH_ORI_FIRST));
+var_dump($res->fetch(PDO::FETCH_NUM, PDO::FETCH_ORI_LAST));
+var_dump($res->fetch(PDO::FETCH_NUM, PDO::FETCH_ORI_REL, -1));
+
+var_dump($res->fetchAll(PDO::FETCH_ASSOC));
+
+// Test binding params via emulated prepared query
+$res = $db->prepare("SELECT ? $from", $aParams);
+$res->execute(array("it's working"));
+var_dump($res->fetch(PDO::FETCH_NUM));
+
+
+// Test bug #48188, trying to execute again
+$res->execute(array("try again"));
+var_dump($res->fetchColumn());
+var_dump($res->fetchColumn());
+
+?>
+--EXPECT--
+string(4) "row1"
+string(4) "row2"
+string(4) "row3"
+string(4) "row4"
+bool(false)
+array(1) {
+ [0]=>
+ string(4) "row3"
+}
+array(1) {
+ [0]=>
+ string(4) "row2"
+}
+array(1) {
+ [0]=>
+ string(4) "row1"
+}
+array(1) {
+ [0]=>
+ string(4) "row4"
+}
+array(1) {
+ [0]=>
+ string(4) "row3"
+}
+array(1) {
+ [0]=>
+ array(1) {
+ ["r"]=>
+ string(4) "row4"
+ }
+}
+array(1) {
+ [0]=>
+ string(12) "it's working"
+}
+string(9) "try again"
+bool(false)
diff --git a/ext/pdo/tests/bug_50458.phpt b/ext/pdo/tests/bug_50458.phpt
new file mode 100644
index 0000000..3deb289
--- /dev/null
+++ b/ext/pdo/tests/bug_50458.phpt
@@ -0,0 +1,29 @@
+--TEST--
+PDO Common: Bug #50458 (PDO::FETCH_FUNC fails with Closures)
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+
+$db = PDOTest::factory();
+$db->exec("CREATE TABLE test (a VARCHAR(10))");
+$db->exec("INSERT INTO test (a) VALUES ('xyz')");
+$res = $db->query("SELECT a FROM test");
+var_dump($res->fetchAll(PDO::FETCH_FUNC, function($a) { return strtoupper($a); }));
+
+?>
+===DONE===
+--EXPECTF--
+array(1) {
+ [0]=>
+ string(3) "XYZ"
+}
+===DONE===
diff --git a/ext/pdo/tests/pdo.inc b/ext/pdo/tests/pdo.inc
new file mode 100644
index 0000000..8089236
--- /dev/null
+++ b/ext/pdo/tests/pdo.inc
@@ -0,0 +1,10 @@
+<?php
+
+function set_sql($name, $query)
+{
+ if (empty($GLOBALS['SQL'][$name]))
+ {
+ $GLOBALS['SQL'][$name] = $query;
+ }
+}
+?>
diff --git a/ext/pdo/tests/pdo_001.phpt b/ext/pdo/tests/pdo_001.phpt
new file mode 100644
index 0000000..3b79a09
--- /dev/null
+++ b/ext/pdo/tests/pdo_001.phpt
@@ -0,0 +1,50 @@
+--TEST--
+PDO Common: PDO::FETCH_ASSOC
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id int NOT NULL PRIMARY KEY, val VARCHAR(10))');
+$db->exec("INSERT INTO test VALUES(1, 'A')");
+$db->exec("INSERT INTO test VALUES(2, 'B')");
+$db->exec("INSERT INTO test VALUES(3, 'C')");
+
+$stmt = $db->prepare('SELECT * from test');
+$stmt->execute();
+
+var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
+?>
+--EXPECT--
+array(3) {
+ [0]=>
+ array(2) {
+ ["id"]=>
+ string(1) "1"
+ ["val"]=>
+ string(1) "A"
+ }
+ [1]=>
+ array(2) {
+ ["id"]=>
+ string(1) "2"
+ ["val"]=>
+ string(1) "B"
+ }
+ [2]=>
+ array(2) {
+ ["id"]=>
+ string(1) "3"
+ ["val"]=>
+ string(1) "C"
+ }
+}
diff --git a/ext/pdo/tests/pdo_002.phpt b/ext/pdo/tests/pdo_002.phpt
new file mode 100644
index 0000000..047fd59
--- /dev/null
+++ b/ext/pdo/tests/pdo_002.phpt
@@ -0,0 +1,50 @@
+--TEST--
+PDO Common: PDO::FETCH_NUM
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id int NOT NULL PRIMARY KEY, val VARCHAR(10))');
+$db->exec("INSERT INTO test VALUES(1, 'A')");
+$db->exec("INSERT INTO test VALUES(2, 'B')");
+$db->exec("INSERT INTO test VALUES(3, 'C')");
+
+$stmt = $db->prepare('SELECT * from test');
+$stmt->execute();
+
+var_dump($stmt->fetchAll(PDO::FETCH_NUM));
+?>
+--EXPECT--
+array(3) {
+ [0]=>
+ array(2) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "A"
+ }
+ [1]=>
+ array(2) {
+ [0]=>
+ string(1) "2"
+ [1]=>
+ string(1) "B"
+ }
+ [2]=>
+ array(2) {
+ [0]=>
+ string(1) "3"
+ [1]=>
+ string(1) "C"
+ }
+}
diff --git a/ext/pdo/tests/pdo_003.phpt b/ext/pdo/tests/pdo_003.phpt
new file mode 100644
index 0000000..ccd23c8
--- /dev/null
+++ b/ext/pdo/tests/pdo_003.phpt
@@ -0,0 +1,62 @@
+--TEST--
+PDO Common: PDO::FETCH_BOTH
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id int NOT NULL PRIMARY KEY, val VARCHAR(10))');
+$db->exec("INSERT INTO test VALUES(1, 'A')");
+$db->exec("INSERT INTO test VALUES(2, 'B')");
+$db->exec("INSERT INTO test VALUES(3, 'C')");
+
+$stmt = $db->prepare('SELECT * from test');
+$stmt->execute();
+
+var_dump($stmt->fetchAll(PDO::FETCH_BOTH));
+?>
+--EXPECT--
+array(3) {
+ [0]=>
+ array(4) {
+ ["id"]=>
+ string(1) "1"
+ [0]=>
+ string(1) "1"
+ ["val"]=>
+ string(1) "A"
+ [1]=>
+ string(1) "A"
+ }
+ [1]=>
+ array(4) {
+ ["id"]=>
+ string(1) "2"
+ [0]=>
+ string(1) "2"
+ ["val"]=>
+ string(1) "B"
+ [1]=>
+ string(1) "B"
+ }
+ [2]=>
+ array(4) {
+ ["id"]=>
+ string(1) "3"
+ [0]=>
+ string(1) "3"
+ ["val"]=>
+ string(1) "C"
+ [1]=>
+ string(1) "C"
+ }
+}
diff --git a/ext/pdo/tests/pdo_004.phpt b/ext/pdo/tests/pdo_004.phpt
new file mode 100644
index 0000000..933629e
--- /dev/null
+++ b/ext/pdo/tests/pdo_004.phpt
@@ -0,0 +1,50 @@
+--TEST--
+PDO Common: PDO::FETCH_OBJ
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id int NOT NULL PRIMARY KEY, val VARCHAR(10))');
+$db->exec("INSERT INTO test VALUES(1, 'A')");
+$db->exec("INSERT INTO test VALUES(2, 'B')");
+$db->exec("INSERT INTO test VALUES(3, 'C')");
+
+$stmt = $db->prepare('SELECT * from test');
+$stmt->execute();
+
+var_dump($stmt->fetchAll(PDO::FETCH_OBJ));
+?>
+--EXPECTF--
+array(3) {
+ [0]=>
+ object(stdClass)#%d (2) {
+ ["id"]=>
+ string(1) "1"
+ ["val"]=>
+ string(1) "A"
+ }
+ [1]=>
+ object(stdClass)#%d (2) {
+ ["id"]=>
+ string(1) "2"
+ ["val"]=>
+ string(1) "B"
+ }
+ [2]=>
+ object(stdClass)#%d (2) {
+ ["id"]=>
+ string(1) "3"
+ ["val"]=>
+ string(1) "C"
+ }
+}
diff --git a/ext/pdo/tests/pdo_005.phpt b/ext/pdo/tests/pdo_005.phpt
new file mode 100644
index 0000000..1ea558b
--- /dev/null
+++ b/ext/pdo/tests/pdo_005.phpt
@@ -0,0 +1,154 @@
+--TEST--
+PDO Common: PDO::FETCH_CLASS
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id int NOT NULL PRIMARY KEY, val VARCHAR(10), val2 VARCHAR(10))');
+$db->exec("INSERT INTO test VALUES(1, 'A', 'AA')");
+$db->exec("INSERT INTO test VALUES(2, 'B', 'BB')");
+$db->exec("INSERT INTO test VALUES(3, 'C', 'CC')");
+
+$stmt = $db->prepare('SELECT id, val, val2 from test');
+
+class TestBase
+{
+ public $id;
+ protected $val;
+ private $val2;
+}
+
+class TestDerived extends TestBase
+{
+ protected $row;
+
+ public function __construct(&$row)
+ {
+ echo __METHOD__ . "($row,{$this->id})\n";
+ $this->row = $row++;
+ }
+}
+
+$stmt->execute();
+var_dump($stmt->fetchAll(PDO::FETCH_CLASS));
+
+$stmt->execute();
+var_dump($stmt->fetchAll(PDO::FETCH_CLASS, 'TestBase'));
+
+$stmt->execute();
+var_dump($stmt->fetchAll(PDO::FETCH_CLASS, 'TestDerived', array(0)));
+
+?>
+--EXPECTF--
+array(3) {
+ [0]=>
+ object(stdClass)#%d (3) {
+ ["id"]=>
+ string(1) "1"
+ ["val"]=>
+ string(1) "A"
+ ["val2"]=>
+ string(2) "AA"
+ }
+ [1]=>
+ object(stdClass)#%d (3) {
+ ["id"]=>
+ string(1) "2"
+ ["val"]=>
+ string(1) "B"
+ ["val2"]=>
+ string(2) "BB"
+ }
+ [2]=>
+ object(stdClass)#%d (3) {
+ ["id"]=>
+ string(1) "3"
+ ["val"]=>
+ string(1) "C"
+ ["val2"]=>
+ string(2) "CC"
+ }
+}
+array(3) {
+ [0]=>
+ object(TestBase)#%d (3) {
+ ["id"]=>
+ string(1) "1"
+ ["val":protected]=>
+ string(1) "A"
+ ["val2":"TestBase":private]=>
+ string(2) "AA"
+ }
+ [1]=>
+ object(TestBase)#%d (3) {
+ ["id"]=>
+ string(1) "2"
+ ["val":protected]=>
+ string(1) "B"
+ ["val2":"TestBase":private]=>
+ string(2) "BB"
+ }
+ [2]=>
+ object(TestBase)#%d (3) {
+ ["id"]=>
+ string(1) "3"
+ ["val":protected]=>
+ string(1) "C"
+ ["val2":"TestBase":private]=>
+ string(2) "CC"
+ }
+}
+TestDerived::__construct(0,1)
+TestDerived::__construct(1,2)
+TestDerived::__construct(2,3)
+array(3) {
+ [0]=>
+ object(TestDerived)#%d (5) {
+ ["row":protected]=>
+ int(0)
+ ["id"]=>
+ string(1) "1"
+ ["val":protected]=>
+ string(1) "A"
+ ["val2":"TestBase":private]=>
+ NULL
+ ["val2"]=>
+ string(2) "AA"
+ }
+ [1]=>
+ object(TestDerived)#%d (5) {
+ ["row":protected]=>
+ int(1)
+ ["id"]=>
+ string(1) "2"
+ ["val":protected]=>
+ string(1) "B"
+ ["val2":"TestBase":private]=>
+ NULL
+ ["val2"]=>
+ string(2) "BB"
+ }
+ [2]=>
+ object(TestDerived)#%d (5) {
+ ["row":protected]=>
+ int(2)
+ ["id"]=>
+ string(1) "3"
+ ["val":protected]=>
+ string(1) "C"
+ ["val2":"TestBase":private]=>
+ NULL
+ ["val2"]=>
+ string(2) "CC"
+ }
+} \ No newline at end of file
diff --git a/ext/pdo/tests/pdo_006.phpt b/ext/pdo/tests/pdo_006.phpt
new file mode 100644
index 0000000..fc83301
--- /dev/null
+++ b/ext/pdo/tests/pdo_006.phpt
@@ -0,0 +1,77 @@
+--TEST--
+PDO Common: PDO::FETCH_GROUP
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id int NOT NULL PRIMARY KEY, val VARCHAR(10))');
+$db->exec("INSERT INTO test VALUES(1, 'A')");
+$db->exec("INSERT INTO test VALUES(2, 'A')");
+$db->exec("INSERT INTO test VALUES(3, 'C')");
+
+$stmt = $db->prepare('SELECT val, id from test');
+
+$stmt->execute();
+var_dump($stmt->fetchAll(PDO::FETCH_NUM|PDO::FETCH_GROUP));
+
+$stmt->execute();
+var_dump($stmt->fetchAll(PDO::FETCH_ASSOC|PDO::FETCH_GROUP));
+
+?>
+--EXPECT--
+array(2) {
+ ["A"]=>
+ array(2) {
+ [0]=>
+ array(1) {
+ [0]=>
+ string(1) "1"
+ }
+ [1]=>
+ array(1) {
+ [0]=>
+ string(1) "2"
+ }
+ }
+ ["C"]=>
+ array(1) {
+ [0]=>
+ array(1) {
+ [0]=>
+ string(1) "3"
+ }
+ }
+}
+array(2) {
+ ["A"]=>
+ array(2) {
+ [0]=>
+ array(1) {
+ ["id"]=>
+ string(1) "1"
+ }
+ [1]=>
+ array(1) {
+ ["id"]=>
+ string(1) "2"
+ }
+ }
+ ["C"]=>
+ array(1) {
+ [0]=>
+ array(1) {
+ ["id"]=>
+ string(1) "3"
+ }
+ }
+}
diff --git a/ext/pdo/tests/pdo_007.phpt b/ext/pdo/tests/pdo_007.phpt
new file mode 100644
index 0000000..291e863
--- /dev/null
+++ b/ext/pdo/tests/pdo_007.phpt
@@ -0,0 +1,65 @@
+--TEST--
+PDO Common: PDO::FETCH_UNIQUE
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id CHAR(1) NOT NULL PRIMARY KEY, val VARCHAR(10))');
+$db->exec("INSERT INTO test VALUES('A', 'A')");
+$db->exec("INSERT INTO test VALUES('B', 'A')");
+$db->exec("INSERT INTO test VALUES('C', 'C')");
+
+$stmt = $db->prepare('SELECT id, val from test');
+
+$stmt->execute();
+var_dump($stmt->fetchAll(PDO::FETCH_NUM|PDO::FETCH_UNIQUE));
+
+$stmt->execute();
+var_dump($stmt->fetchAll(PDO::FETCH_ASSOC|PDO::FETCH_UNIQUE));
+
+?>
+--EXPECT--
+array(3) {
+ ["A"]=>
+ array(1) {
+ [0]=>
+ string(1) "A"
+ }
+ ["B"]=>
+ array(1) {
+ [0]=>
+ string(1) "A"
+ }
+ ["C"]=>
+ array(1) {
+ [0]=>
+ string(1) "C"
+ }
+}
+array(3) {
+ ["A"]=>
+ array(1) {
+ ["val"]=>
+ string(1) "A"
+ }
+ ["B"]=>
+ array(1) {
+ ["val"]=>
+ string(1) "A"
+ }
+ ["C"]=>
+ array(1) {
+ ["val"]=>
+ string(1) "C"
+ }
+}
diff --git a/ext/pdo/tests/pdo_008.phpt b/ext/pdo/tests/pdo_008.phpt
new file mode 100644
index 0000000..3e9e12e
--- /dev/null
+++ b/ext/pdo/tests/pdo_008.phpt
@@ -0,0 +1,40 @@
+--TEST--
+PDO Common: PDO::FETCH_UNIQUE conflict
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id CHAR(1) NOT NULL PRIMARY KEY, val VARCHAR(10))');
+$db->exec("INSERT INTO test VALUES('A', 'A')");
+$db->exec("INSERT INTO test VALUES('B', 'A')");
+$db->exec("INSERT INTO test VALUES('C', 'C')");
+
+$stmt = $db->prepare('SELECT val, id from test');
+
+$stmt->execute();
+var_dump($stmt->fetchAll(PDO::FETCH_NUM|PDO::FETCH_UNIQUE));
+
+?>
+--EXPECT--
+array(2) {
+ ["A"]=>
+ array(1) {
+ [0]=>
+ string(1) "B"
+ }
+ ["C"]=>
+ array(1) {
+ [0]=>
+ string(1) "C"
+ }
+}
diff --git a/ext/pdo/tests/pdo_009.phpt b/ext/pdo/tests/pdo_009.phpt
new file mode 100644
index 0000000..0e21177
--- /dev/null
+++ b/ext/pdo/tests/pdo_009.phpt
@@ -0,0 +1,131 @@
+--TEST--
+PDO Common: PDO::FETCH_CLASSTYPE
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE classtypes(id int NOT NULL PRIMARY KEY, name VARCHAR(10) NOT NULL UNIQUE)');
+$db->exec('INSERT INTO classtypes VALUES(0, \'stdClass\')');
+$db->exec('INSERT INTO classtypes VALUES(1, \'Test1\')');
+$db->exec('INSERT INTO classtypes VALUES(2, \'Test2\')');
+$db->exec('CREATE TABLE test(id int NOT NULL PRIMARY KEY, classtype int, val VARCHAR(10))');
+$db->exec('INSERT INTO test VALUES(1, 0, \'A\')');
+$db->exec('INSERT INTO test VALUES(2, 1, \'B\')');
+$db->exec('INSERT INTO test VALUES(3, 2, \'C\')');
+$db->exec('INSERT INTO test VALUES(4, 3, \'D\')');
+
+$stmt = $db->prepare('SELECT classtypes.name, test.id AS id, test.val AS val FROM test LEFT JOIN classtypes ON test.classtype=classtypes.id');
+
+class Test1
+{
+ public function __construct()
+ {
+ echo __METHOD__ . "()\n";
+ }
+}
+
+class Test2
+{
+ public function __construct()
+ {
+ echo __METHOD__ . "()\n";
+ }
+}
+
+class Test3
+{
+ public function __construct()
+ {
+ echo __METHOD__ . "()\n";
+ }
+}
+
+$stmt->execute();
+var_dump($stmt->fetchAll(PDO::FETCH_NUM));
+
+$stmt->execute();
+var_dump($stmt->fetchAll(PDO::FETCH_CLASS|PDO::FETCH_CLASSTYPE, 'Test3'));
+
+?>
+--EXPECTF--
+array(4) {
+ [0]=>
+ array(3) {
+ [0]=>
+ string(8) "stdClass"
+ [1]=>
+ string(1) "1"
+ [2]=>
+ string(1) "A"
+ }
+ [1]=>
+ array(3) {
+ [0]=>
+ string(5) "Test1"
+ [1]=>
+ string(1) "2"
+ [2]=>
+ string(1) "B"
+ }
+ [2]=>
+ array(3) {
+ [0]=>
+ string(5) "Test2"
+ [1]=>
+ string(1) "3"
+ [2]=>
+ string(1) "C"
+ }
+ [3]=>
+ array(3) {
+ [0]=>
+ NULL
+ [1]=>
+ string(1) "4"
+ [2]=>
+ string(1) "D"
+ }
+}
+Test1::__construct()
+Test2::__construct()
+Test3::__construct()
+array(4) {
+ [0]=>
+ object(stdClass)#%d (2) {
+ ["id"]=>
+ string(1) "1"
+ ["val"]=>
+ string(1) "A"
+ }
+ [1]=>
+ object(Test1)#%d (2) {
+ ["id"]=>
+ string(1) "2"
+ ["val"]=>
+ string(1) "B"
+ }
+ [2]=>
+ object(Test2)#%d (2) {
+ ["id"]=>
+ string(1) "3"
+ ["val"]=>
+ string(1) "C"
+ }
+ [3]=>
+ object(Test3)#%d (2) {
+ ["id"]=>
+ string(1) "4"
+ ["val"]=>
+ string(1) "D"
+ }
+}
diff --git a/ext/pdo/tests/pdo_010.phpt b/ext/pdo/tests/pdo_010.phpt
new file mode 100644
index 0000000..812b868
--- /dev/null
+++ b/ext/pdo/tests/pdo_010.phpt
@@ -0,0 +1,119 @@
+--TEST--
+PDO Common: PDO::FETCH_CLASSTYPE and GROUP/UNIQUE
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE classtypes(id int NOT NULL PRIMARY KEY, name VARCHAR(10) NOT NULL UNIQUE)');
+$db->exec('INSERT INTO classtypes VALUES(0, \'stdClass\')');
+$db->exec('INSERT INTO classtypes VALUES(1, \'Test1\')');
+$db->exec('INSERT INTO classtypes VALUES(2, \'Test2\')');
+$db->exec('CREATE TABLE test(id int NOT NULL PRIMARY KEY, classtype int, val VARCHAR(10), grp VARCHAR(10))');
+$db->exec('INSERT INTO test VALUES(1, 0, \'A\', \'Group1\')');
+$db->exec('INSERT INTO test VALUES(2, 1, \'B\', \'Group1\')');
+$db->exec('INSERT INTO test VALUES(3, 2, \'C\', \'Group2\')');
+$db->exec('INSERT INTO test VALUES(4, 3, \'D\', \'Group2\')');
+
+$stmt = $db->prepare('SELECT classtypes.name, test.grp AS grp, test.id AS id, test.val AS val FROM test LEFT JOIN classtypes ON test.classtype=classtypes.id');
+
+class Test1
+{
+ public function __construct()
+ {
+ echo __METHOD__ . "()\n";
+ }
+}
+
+class Test2
+{
+ public function __construct()
+ {
+ echo __METHOD__ . "()\n";
+ }
+}
+
+class Test3
+{
+ public function __construct()
+ {
+ echo __METHOD__ . "()\n";
+ }
+}
+
+
+$stmt->execute();
+var_dump($stmt->fetchAll(PDO::FETCH_CLASS|PDO::FETCH_CLASSTYPE|PDO::FETCH_GROUP, 'Test3'));
+
+$stmt->execute();
+var_dump($stmt->fetchAll(PDO::FETCH_CLASS|PDO::FETCH_CLASSTYPE|PDO::FETCH_UNIQUE, 'Test3'));
+
+?>
+--EXPECTF--
+Test1::__construct()
+Test2::__construct()
+Test3::__construct()
+array(2) {
+ ["Group1"]=>
+ array(2) {
+ [0]=>
+ object(stdClass)#%d (2) {
+ ["id"]=>
+ string(1) "1"
+ ["val"]=>
+ string(1) "A"
+ }
+ [1]=>
+ object(Test1)#%d (2) {
+ ["id"]=>
+ string(1) "2"
+ ["val"]=>
+ string(1) "B"
+ }
+ }
+ ["Group2"]=>
+ array(2) {
+ [0]=>
+ object(Test2)#%d (2) {
+ ["id"]=>
+ string(1) "3"
+ ["val"]=>
+ string(1) "C"
+ }
+ [1]=>
+ object(Test3)#%d (2) {
+ ["id"]=>
+ string(1) "4"
+ ["val"]=>
+ string(1) "D"
+ }
+ }
+}
+Test1::__construct()
+Test2::__construct()
+Test3::__construct()
+array(2) {
+ ["Group1"]=>
+ object(Test1)#%d (2) {
+ ["id"]=>
+ string(1) "2"
+ ["val"]=>
+ string(1) "B"
+ }
+ ["Group2"]=>
+ object(Test3)#%d (2) {
+ ["id"]=>
+ string(1) "4"
+ ["val"]=>
+ string(1) "D"
+ }
+}
diff --git a/ext/pdo/tests/pdo_011.phpt b/ext/pdo/tests/pdo_011.phpt
new file mode 100644
index 0000000..4a24042
--- /dev/null
+++ b/ext/pdo/tests/pdo_011.phpt
@@ -0,0 +1,301 @@
+--TEST--
+PDO Common: PDO::FETCH_FUNC and statement overloading
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id int NOT NULL PRIMARY KEY, val VARCHAR(10), grp VARCHAR(10))');
+$db->exec('INSERT INTO test VALUES(1, \'A\', \'Group1\')');
+$db->exec('INSERT INTO test VALUES(2, \'B\', \'Group1\')');
+$db->exec('INSERT INTO test VALUES(3, \'C\', \'Group2\')');
+$db->exec('INSERT INTO test VALUES(4, \'D\', \'Group2\')');
+
+class DerivedStatement extends PDOStatement
+{
+ private function __construct($name, $db)
+ {
+ $this->name = $name;
+ echo __METHOD__ . "($name)\n";
+ }
+
+ function reTrieve($id, $val) {
+ echo __METHOD__ . "($id,$val)\n";
+ return array($id=>$val);
+ }
+}
+
+$select1 = $db->prepare('SELECT grp, id FROM test');
+$select2 = $db->prepare('SELECT id, val FROM test');
+$derived = $db->prepare('SELECT id, val FROM test', array(PDO::ATTR_STATEMENT_CLASS=>array('DerivedStatement', array('Overloaded', $db))));
+
+class Test1
+{
+ public function __construct($id, $val)
+ {
+ echo __METHOD__ . "($id,$val)\n";
+ $this->id = $id;
+ $this->val = $val;
+ }
+
+ static public function factory($id, $val)
+ {
+ echo __METHOD__ . "($id,$val)\n";
+ return new self($id, $val);
+ }
+}
+
+function test($id,$val='N/A')
+{
+ echo __METHOD__ . "($id,$val)\n";
+ return array($id=>$val);
+}
+
+$f = new Test1(0,0);
+
+$select1->execute();
+var_dump($select1->fetchAll(PDO::FETCH_FUNC|PDO::FETCH_GROUP, 'test'));
+
+$select2->execute();
+var_dump($select2->fetchAll(PDO::FETCH_FUNC, 'test'));
+
+$select2->execute();
+var_dump($select2->fetchAll(PDO::FETCH_FUNC, array('Test1','factory')));
+
+$select2->execute();
+var_dump($select2->fetchAll(PDO::FETCH_FUNC, array($f, 'factory')));
+
+var_dump(get_class($derived));
+$derived->execute();
+var_dump($derived->fetchAll(PDO::FETCH_FUNC, array($derived, 'retrieve')));
+$derived->execute();
+var_dump($derived->fetchAll(PDO::FETCH_FUNC, array($derived, 'reTrieve')));
+$derived->execute();
+var_dump($derived->fetchAll(PDO::FETCH_FUNC, array($derived, 'RETRIEVE')));
+
+?>
+--EXPECTF--
+DerivedStatement::__construct(Overloaded)
+Test1::__construct(0,0)
+test(1,N/A)
+test(2,N/A)
+test(3,N/A)
+test(4,N/A)
+array(2) {
+ ["Group1"]=>
+ array(2) {
+ [0]=>
+ array(1) {
+ [1]=>
+ string(3) "N/A"
+ }
+ [1]=>
+ array(1) {
+ [2]=>
+ string(3) "N/A"
+ }
+ }
+ ["Group2"]=>
+ array(2) {
+ [0]=>
+ array(1) {
+ [3]=>
+ string(3) "N/A"
+ }
+ [1]=>
+ array(1) {
+ [4]=>
+ string(3) "N/A"
+ }
+ }
+}
+test(1,A)
+test(2,B)
+test(3,C)
+test(4,D)
+array(4) {
+ [0]=>
+ array(1) {
+ [1]=>
+ string(1) "A"
+ }
+ [1]=>
+ array(1) {
+ [2]=>
+ string(1) "B"
+ }
+ [2]=>
+ array(1) {
+ [3]=>
+ string(1) "C"
+ }
+ [3]=>
+ array(1) {
+ [4]=>
+ string(1) "D"
+ }
+}
+Test1::factory(1,A)
+Test1::__construct(1,A)
+Test1::factory(2,B)
+Test1::__construct(2,B)
+Test1::factory(3,C)
+Test1::__construct(3,C)
+Test1::factory(4,D)
+Test1::__construct(4,D)
+array(4) {
+ [0]=>
+ object(Test1)#%d (2) {
+ ["id"]=>
+ string(1) "1"
+ ["val"]=>
+ string(1) "A"
+ }
+ [1]=>
+ object(Test1)#%d (2) {
+ ["id"]=>
+ string(1) "2"
+ ["val"]=>
+ string(1) "B"
+ }
+ [2]=>
+ object(Test1)#%d (2) {
+ ["id"]=>
+ string(1) "3"
+ ["val"]=>
+ string(1) "C"
+ }
+ [3]=>
+ object(Test1)#%d (2) {
+ ["id"]=>
+ string(1) "4"
+ ["val"]=>
+ string(1) "D"
+ }
+}
+Test1::factory(1,A)
+Test1::__construct(1,A)
+Test1::factory(2,B)
+Test1::__construct(2,B)
+Test1::factory(3,C)
+Test1::__construct(3,C)
+Test1::factory(4,D)
+Test1::__construct(4,D)
+array(4) {
+ [0]=>
+ object(Test1)#%d (2) {
+ ["id"]=>
+ string(1) "1"
+ ["val"]=>
+ string(1) "A"
+ }
+ [1]=>
+ object(Test1)#%d (2) {
+ ["id"]=>
+ string(1) "2"
+ ["val"]=>
+ string(1) "B"
+ }
+ [2]=>
+ object(Test1)#%d (2) {
+ ["id"]=>
+ string(1) "3"
+ ["val"]=>
+ string(1) "C"
+ }
+ [3]=>
+ object(Test1)#%d (2) {
+ ["id"]=>
+ string(1) "4"
+ ["val"]=>
+ string(1) "D"
+ }
+}
+string(16) "DerivedStatement"
+DerivedStatement::reTrieve(1,A)
+DerivedStatement::reTrieve(2,B)
+DerivedStatement::reTrieve(3,C)
+DerivedStatement::reTrieve(4,D)
+array(4) {
+ [0]=>
+ array(1) {
+ [1]=>
+ string(1) "A"
+ }
+ [1]=>
+ array(1) {
+ [2]=>
+ string(1) "B"
+ }
+ [2]=>
+ array(1) {
+ [3]=>
+ string(1) "C"
+ }
+ [3]=>
+ array(1) {
+ [4]=>
+ string(1) "D"
+ }
+}
+DerivedStatement::reTrieve(1,A)
+DerivedStatement::reTrieve(2,B)
+DerivedStatement::reTrieve(3,C)
+DerivedStatement::reTrieve(4,D)
+array(4) {
+ [0]=>
+ array(1) {
+ [1]=>
+ string(1) "A"
+ }
+ [1]=>
+ array(1) {
+ [2]=>
+ string(1) "B"
+ }
+ [2]=>
+ array(1) {
+ [3]=>
+ string(1) "C"
+ }
+ [3]=>
+ array(1) {
+ [4]=>
+ string(1) "D"
+ }
+}
+DerivedStatement::reTrieve(1,A)
+DerivedStatement::reTrieve(2,B)
+DerivedStatement::reTrieve(3,C)
+DerivedStatement::reTrieve(4,D)
+array(4) {
+ [0]=>
+ array(1) {
+ [1]=>
+ string(1) "A"
+ }
+ [1]=>
+ array(1) {
+ [2]=>
+ string(1) "B"
+ }
+ [2]=>
+ array(1) {
+ [3]=>
+ string(1) "C"
+ }
+ [3]=>
+ array(1) {
+ [4]=>
+ string(1) "D"
+ }
+}
diff --git a/ext/pdo/tests/pdo_012.phpt b/ext/pdo/tests/pdo_012.phpt
new file mode 100644
index 0000000..471c397
--- /dev/null
+++ b/ext/pdo/tests/pdo_012.phpt
@@ -0,0 +1,98 @@
+--TEST--
+PDO Common: PDOStatement::setFetchMode
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id int NOT NULL PRIMARY KEY, val VARCHAR(10), grp VARCHAR(10))');
+$db->exec('INSERT INTO test VALUES(1, \'A\', \'Group1\')');
+$db->exec('INSERT INTO test VALUES(2, \'B\', \'Group2\')');
+
+$SELECT = 'SELECT val, grp FROM test';
+
+$stmt = $db->query($SELECT, PDO::FETCH_NUM);
+var_dump($stmt->fetchAll());
+
+class Test
+{
+ function __construct($name = 'N/A')
+ {
+ echo __METHOD__ . "($name)\n";
+ }
+}
+
+unset($stmt);
+
+$stmt = $db->query($SELECT, PDO::FETCH_CLASS, 'Test');
+var_dump($stmt->fetchAll());
+
+unset($stmt);
+
+$stmt = $db->query($SELECT, PDO::FETCH_NUM);
+$stmt->setFetchMode(PDO::FETCH_CLASS, 'Test', array('Changed'));
+var_dump($stmt->fetchAll());
+
+?>
+--EXPECTF--
+array(2) {
+ [0]=>
+ array(2) {
+ [0]=>
+ string(1) "A"
+ [1]=>
+ string(6) "Group1"
+ }
+ [1]=>
+ array(2) {
+ [0]=>
+ string(1) "B"
+ [1]=>
+ string(6) "Group2"
+ }
+}
+Test::__construct(N/A)
+Test::__construct(N/A)
+array(2) {
+ [0]=>
+ object(Test)#%d (2) {
+ ["val"]=>
+ string(1) "A"
+ ["grp"]=>
+ string(6) "Group1"
+ }
+ [1]=>
+ object(Test)#%d (2) {
+ ["val"]=>
+ string(1) "B"
+ ["grp"]=>
+ string(6) "Group2"
+ }
+}
+Test::__construct(Changed)
+Test::__construct(Changed)
+array(2) {
+ [0]=>
+ object(Test)#%d (2) {
+ ["val"]=>
+ string(1) "A"
+ ["grp"]=>
+ string(6) "Group1"
+ }
+ [1]=>
+ object(Test)#%d (2) {
+ ["val"]=>
+ string(1) "B"
+ ["grp"]=>
+ string(6) "Group2"
+ }
+}
diff --git a/ext/pdo/tests/pdo_013.phpt b/ext/pdo/tests/pdo_013.phpt
new file mode 100644
index 0000000..009c7e2
--- /dev/null
+++ b/ext/pdo/tests/pdo_013.phpt
@@ -0,0 +1,96 @@
+--TEST--
+PDO Common: PDOStatement iterator
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id int NOT NULL PRIMARY KEY, val VARCHAR(10), grp VARCHAR(10))');
+$db->exec('INSERT INTO test VALUES(1, \'A\', \'Group1\')');
+$db->exec('INSERT INTO test VALUES(2, \'B\', \'Group2\')');
+
+$SELECT = 'SELECT val, grp FROM test';
+
+$stmt = $db->prepare($SELECT);
+
+$stmt->execute();
+$stmt->setFetchMode(PDO::FETCH_NUM);
+foreach ($stmt as $data)
+{
+ var_dump($data);
+}
+
+class Test
+{
+ function __construct($name = 'N/A')
+ {
+ echo __METHOD__ . "($name)\n";
+ }
+}
+
+unset($stmt);
+
+foreach ($db->query($SELECT, PDO::FETCH_CLASS, 'Test') as $data)
+{
+ var_dump($data);
+}
+
+unset($stmt);
+
+$stmt = $db->query($SELECT, PDO::FETCH_CLASS, 'Test', array('WOW'));
+
+foreach($stmt as $data)
+{
+ var_dump($data);
+}
+?>
+--EXPECTF--
+array(2) {
+ [0]=>
+ string(1) "A"
+ [1]=>
+ string(6) "Group1"
+}
+array(2) {
+ [0]=>
+ string(1) "B"
+ [1]=>
+ string(6) "Group2"
+}
+Test::__construct(N/A)
+object(Test)#%d (2) {
+ ["val"]=>
+ string(1) "A"
+ ["grp"]=>
+ string(6) "Group1"
+}
+Test::__construct(N/A)
+object(Test)#%d (2) {
+ ["val"]=>
+ string(1) "B"
+ ["grp"]=>
+ string(6) "Group2"
+}
+Test::__construct(WOW)
+object(Test)#%d (2) {
+ ["val"]=>
+ string(1) "A"
+ ["grp"]=>
+ string(6) "Group1"
+}
+Test::__construct(WOW)
+object(Test)#%d (2) {
+ ["val"]=>
+ string(1) "B"
+ ["grp"]=>
+ string(6) "Group2"
+}
diff --git a/ext/pdo/tests/pdo_014.phpt b/ext/pdo/tests/pdo_014.phpt
new file mode 100644
index 0000000..794fdae
--- /dev/null
+++ b/ext/pdo/tests/pdo_014.phpt
@@ -0,0 +1,102 @@
+--TEST--
+PDO Common: PDOStatement SPL iterator
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+if (!extension_loaded('SPL')) die('skip SPL not available');
+if (!class_exists('IteratorIterator', false)) die('skip IteratorIterator class not present');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id int NOT NULL PRIMARY KEY, val VARCHAR(10), grp VARCHAR(10))');
+$db->exec('INSERT INTO test VALUES(1, \'A\', \'Group1\')');
+$db->exec('INSERT INTO test VALUES(2, \'B\', \'Group2\')');
+$SELECT = 'SELECT val, grp FROM test';
+
+class Test
+{
+ function __construct($name = 'N/A')
+ {
+ echo __METHOD__ . "($name)\n";
+ }
+}
+
+$stmt = $db->query($SELECT, PDO::FETCH_CLASS, 'Test', array('WOW'));
+
+$it = new IteratorIterator($stmt); /* check if we can convert that thing */
+
+/*** HINT: If YOU plan to do so remember not to call rewind() -> see below ***/
+
+foreach($it as $data)
+{
+ var_dump($data);
+}
+
+$it->next(); /* must be allowed */
+var_dump($it->current()); /* must return NULL */
+var_dump($it->valid()); /* must return false */
+
+class PDOStatementAggregate extends PDOStatement implements IteratorAggregate
+{
+ private function __construct()
+ {
+ echo __METHOD__ . "\n";
+ $this->setFetchMode(PDO::FETCH_NUM);
+ /* default fetch mode is BOTH, so we see if the ctor can overwrite that */
+ }
+
+ function getIterator()
+ {
+ echo __METHOD__ . "\n";
+ $this->execute();
+ return new IteratorIterator($this, 'PDOStatement');
+ }
+}
+
+$stmt = $db->prepare($SELECT, array(PDO::ATTR_STATEMENT_CLASS=>array('PDOStatementAggregate')));
+
+foreach($stmt as $data)
+{
+ var_dump($data);
+}
+
+?>
+--EXPECTF--
+Test::__construct(WOW)
+object(Test)#4 (2) {
+ ["val"]=>
+ string(1) "A"
+ ["grp"]=>
+ string(6) "Group1"
+}
+Test::__construct(WOW)
+object(Test)#6 (2) {
+ ["val"]=>
+ string(1) "B"
+ ["grp"]=>
+ string(6) "Group2"
+}
+NULL
+bool(false)
+PDOStatementAggregate::__construct
+PDOStatementAggregate::getIterator
+array(2) {
+ [0]=>
+ string(1) "A"
+ [1]=>
+ string(6) "Group1"
+}
+array(2) {
+ [0]=>
+ string(1) "B"
+ [1]=>
+ string(6) "Group2"
+}
diff --git a/ext/pdo/tests/pdo_015.phpt b/ext/pdo/tests/pdo_015.phpt
new file mode 100644
index 0000000..aea292b
--- /dev/null
+++ b/ext/pdo/tests/pdo_015.phpt
@@ -0,0 +1,100 @@
+--TEST--
+PDO Common: PDO::FETCH_COLUMN
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id int NOT NULL PRIMARY KEY, val VARCHAR(10), val2 VARCHAR(20))');
+$db->exec('INSERT INTO test VALUES(1, \'A\', \'A2\')');
+$db->exec('INSERT INTO test VALUES(2, \'A\', \'B2\')');
+
+$select1 = $db->prepare('SELECT id, val, val2 FROM test');
+$select2 = $db->prepare('SELECT val, val2 FROM test');
+
+$select1->execute();
+var_dump($select1->fetchAll(PDO::FETCH_COLUMN));
+$select1->execute();
+var_dump($select1->fetchAll(PDO::FETCH_COLUMN, 2));
+$select1->execute();
+var_dump($select1->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_GROUP));
+$select1->execute();
+var_dump($select1->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_UNIQUE));
+$select1->execute();
+var_dump($select1->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_UNIQUE, 0));
+$select1->execute();
+var_dump($select1->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_UNIQUE, 1));
+$select1->execute();
+var_dump($select1->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_UNIQUE, 2));
+
+$select2->execute();
+var_dump($select2->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_GROUP));
+
+?>
+--EXPECT--
+array(2) {
+ [0]=>
+ string(1) "1"
+ [1]=>
+ string(1) "2"
+}
+array(2) {
+ [0]=>
+ string(2) "A2"
+ [1]=>
+ string(2) "B2"
+}
+array(2) {
+ [1]=>
+ array(1) {
+ [0]=>
+ string(1) "A"
+ }
+ [2]=>
+ array(1) {
+ [0]=>
+ string(1) "A"
+ }
+}
+array(2) {
+ [1]=>
+ string(1) "A"
+ [2]=>
+ string(1) "A"
+}
+array(2) {
+ [1]=>
+ string(1) "1"
+ [2]=>
+ string(1) "2"
+}
+array(2) {
+ [1]=>
+ string(1) "A"
+ [2]=>
+ string(1) "A"
+}
+array(2) {
+ [1]=>
+ string(2) "A2"
+ [2]=>
+ string(2) "B2"
+}
+array(1) {
+ ["A"]=>
+ array(2) {
+ [0]=>
+ string(2) "A2"
+ [1]=>
+ string(2) "B2"
+ }
+}
diff --git a/ext/pdo/tests/pdo_016.phpt b/ext/pdo/tests/pdo_016.phpt
new file mode 100644
index 0000000..12c9517
--- /dev/null
+++ b/ext/pdo/tests/pdo_016.phpt
@@ -0,0 +1,204 @@
+--TEST--
+PDO Common: PDO::FETCH_BOUND
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+if (!strncasecmp(getenv('PDOTEST_DSN'), 'oci', strlen('oci'))) die('skip not relevant for oci driver - cannot reexecute after closing cursors without reparse');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+if ($db->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') {
+ $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
+}
+
+$db->exec('CREATE TABLE test(idx int NOT NULL PRIMARY KEY, txt VARCHAR(20))');
+$db->exec('INSERT INTO test VALUES(0, \'String0\')');
+$db->exec('INSERT INTO test VALUES(1, \'String1\')');
+$db->exec('INSERT INTO test VALUES(2, \'String2\')');
+
+$stmt1 = $db->prepare('SELECT COUNT(idx) FROM test');
+$stmt2 = $db->prepare('SELECT idx, txt FROM test ORDER by idx');
+
+$stmt1->execute();
+var_dump($stmt1->fetchColumn());
+$stmt1 = null;
+
+$stmt2->execute();
+$cont = $stmt2->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_UNIQUE);
+var_dump($cont);
+
+echo "===WHILE===\n";
+
+$stmt2->bindColumn('idx', $idx);
+$stmt2->bindColumn('txt', $txt);
+$stmt2->execute();
+
+while($stmt2->fetch(PDO::FETCH_BOUND)) {
+ var_dump(array($idx=>$txt));
+}
+
+echo "===ALONE===\n";
+
+$stmt3 = $db->prepare('SELECT txt FROM test WHERE idx=:inp');
+$stmt3->bindParam(':inp', $idx); /* by foreign name */
+
+$stmt4 = $db->prepare('SELECT idx FROM test WHERE txt=:txt');
+$stmt4->bindParam(':txt', $txt); /* using same name */
+
+foreach($cont as $idx => $txt)
+{
+ var_dump(array($idx=>$txt));
+ var_dump($stmt3->execute());
+
+ if ($idx == 0) {
+ /* portability-wise, you may only bindColumn()s
+ * after execute() has been called at least once */
+ $stmt3->bindColumn('txt', $col1);
+ }
+ var_dump($stmt3->fetch(PDO::FETCH_BOUND));
+ $stmt3->closeCursor();
+
+ var_dump($stmt4->execute());
+ if ($idx == 0) {
+ /* portability-wise, you may only bindColumn()s
+ * after execute() has been called at least once */
+ $stmt4->bindColumn('idx', $col2);
+ }
+ var_dump($stmt4->fetch(PDO::FETCH_BOUND));
+ $stmt4->closeCursor();
+ var_dump(array($col2=>$col1));
+}
+
+echo "===REBIND/SAME===\n";
+
+$stmt4->bindColumn('idx', $col1);
+
+foreach($cont as $idx => $txt)
+{
+ var_dump(array($idx=>$txt));
+ var_dump($stmt3->execute());
+ var_dump($stmt3->fetch(PDO::FETCH_BOUND));
+ $stmt3->closeCursor();
+ var_dump($col1);
+ var_dump($stmt4->execute());
+ var_dump($stmt4->fetch(PDO::FETCH_BOUND));
+ $stmt4->closeCursor();
+ var_dump($col1);
+}
+
+echo "===REBIND/CONFLICT===\n";
+
+$stmt2->bindColumn('idx', $col1);
+$stmt2->bindColumn('txt', $col1);
+$stmt2->execute();
+
+while($stmt2->fetch(PDO::FETCH_BOUND))
+{
+ var_dump($col1);
+}
+
+
+?>
+--EXPECT--
+string(1) "3"
+array(3) {
+ [0]=>
+ string(7) "String0"
+ [1]=>
+ string(7) "String1"
+ [2]=>
+ string(7) "String2"
+}
+===WHILE===
+array(1) {
+ [0]=>
+ string(7) "String0"
+}
+array(1) {
+ [1]=>
+ string(7) "String1"
+}
+array(1) {
+ [2]=>
+ string(7) "String2"
+}
+===ALONE===
+array(1) {
+ [0]=>
+ string(7) "String0"
+}
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+array(1) {
+ [0]=>
+ string(7) "String0"
+}
+array(1) {
+ [1]=>
+ string(7) "String1"
+}
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+array(1) {
+ [1]=>
+ string(7) "String1"
+}
+array(1) {
+ [2]=>
+ string(7) "String2"
+}
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+array(1) {
+ [2]=>
+ string(7) "String2"
+}
+===REBIND/SAME===
+array(1) {
+ [0]=>
+ string(7) "String0"
+}
+bool(true)
+bool(true)
+string(7) "String0"
+bool(true)
+bool(true)
+string(1) "0"
+array(1) {
+ [1]=>
+ string(7) "String1"
+}
+bool(true)
+bool(true)
+string(7) "String1"
+bool(true)
+bool(true)
+string(1) "1"
+array(1) {
+ [2]=>
+ string(7) "String2"
+}
+bool(true)
+bool(true)
+string(7) "String2"
+bool(true)
+bool(true)
+string(1) "2"
+===REBIND/CONFLICT===
+string(7) "String0"
+string(7) "String1"
+string(7) "String2"
diff --git a/ext/pdo/tests/pdo_016a.phpt b/ext/pdo/tests/pdo_016a.phpt
new file mode 100644
index 0000000..72f4b42
--- /dev/null
+++ b/ext/pdo/tests/pdo_016a.phpt
@@ -0,0 +1,204 @@
+--TEST--
+PDO Common: PDO::FETCH_BOUND w/o :
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+if (!strncasecmp(getenv('PDOTEST_DSN'), 'oci', strlen('oci'))) die('skip not relevant for oci driver - cannot reexecute after closing cursors without reparse');
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+if ($db->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') {
+ $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
+}
+
+$db->exec('CREATE TABLE test(idx int NOT NULL PRIMARY KEY, txt VARCHAR(20))');
+$db->exec('INSERT INTO test VALUES(0, \'String0\')');
+$db->exec('INSERT INTO test VALUES(1, \'String1\')');
+$db->exec('INSERT INTO test VALUES(2, \'String2\')');
+
+$stmt1 = $db->prepare('SELECT COUNT(idx) FROM test');
+$stmt2 = $db->prepare('SELECT idx, txt FROM test ORDER by idx');
+
+$stmt1->execute();
+var_dump($stmt1->fetchColumn());
+$stmt1 = null;
+
+$stmt2->execute();
+$cont = $stmt2->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_UNIQUE);
+var_dump($cont);
+
+echo "===WHILE===\n";
+
+$stmt2->bindColumn('idx', $idx);
+$stmt2->bindColumn('txt', $txt);
+$stmt2->execute();
+
+while($stmt2->fetch(PDO::FETCH_BOUND)) {
+ var_dump(array($idx=>$txt));
+}
+
+echo "===ALONE===\n";
+
+$stmt3 = $db->prepare('SELECT txt FROM test WHERE idx=:inp');
+$stmt3->bindParam('inp', $idx); /* by foreign name */
+
+$stmt4 = $db->prepare('SELECT idx FROM test WHERE txt=:txt');
+$stmt4->bindParam('txt', $txt); /* using same name */
+
+foreach($cont as $idx => $txt)
+{
+ var_dump(array($idx=>$txt));
+ var_dump($stmt3->execute());
+
+ if ($idx == 0) {
+ /* portability-wise, you may only bindColumn()s
+ * after execute() has been called at least once */
+ $stmt3->bindColumn('txt', $col1);
+ }
+ var_dump($stmt3->fetch(PDO::FETCH_BOUND));
+ $stmt3->closeCursor();
+
+ var_dump($stmt4->execute());
+ if ($idx == 0) {
+ /* portability-wise, you may only bindColumn()s
+ * after execute() has been called at least once */
+ $stmt4->bindColumn('idx', $col2);
+ }
+ var_dump($stmt4->fetch(PDO::FETCH_BOUND));
+ $stmt4->closeCursor();
+ var_dump(array($col2=>$col1));
+}
+
+echo "===REBIND/SAME===\n";
+
+$stmt4->bindColumn('idx', $col1);
+
+foreach($cont as $idx => $txt)
+{
+ var_dump(array($idx=>$txt));
+ var_dump($stmt3->execute());
+ var_dump($stmt3->fetch(PDO::FETCH_BOUND));
+ $stmt3->closeCursor();
+ var_dump($col1);
+ var_dump($stmt4->execute());
+ var_dump($stmt4->fetch(PDO::FETCH_BOUND));
+ $stmt4->closeCursor();
+ var_dump($col1);
+}
+
+echo "===REBIND/CONFLICT===\n";
+
+$stmt2->bindColumn('idx', $col1);
+$stmt2->bindColumn('txt', $col1);
+$stmt2->execute();
+
+while($stmt2->fetch(PDO::FETCH_BOUND))
+{
+ var_dump($col1);
+}
+
+
+?>
+--EXPECT--
+string(1) "3"
+array(3) {
+ [0]=>
+ string(7) "String0"
+ [1]=>
+ string(7) "String1"
+ [2]=>
+ string(7) "String2"
+}
+===WHILE===
+array(1) {
+ [0]=>
+ string(7) "String0"
+}
+array(1) {
+ [1]=>
+ string(7) "String1"
+}
+array(1) {
+ [2]=>
+ string(7) "String2"
+}
+===ALONE===
+array(1) {
+ [0]=>
+ string(7) "String0"
+}
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+array(1) {
+ [0]=>
+ string(7) "String0"
+}
+array(1) {
+ [1]=>
+ string(7) "String1"
+}
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+array(1) {
+ [1]=>
+ string(7) "String1"
+}
+array(1) {
+ [2]=>
+ string(7) "String2"
+}
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+array(1) {
+ [2]=>
+ string(7) "String2"
+}
+===REBIND/SAME===
+array(1) {
+ [0]=>
+ string(7) "String0"
+}
+bool(true)
+bool(true)
+string(7) "String0"
+bool(true)
+bool(true)
+string(1) "0"
+array(1) {
+ [1]=>
+ string(7) "String1"
+}
+bool(true)
+bool(true)
+string(7) "String1"
+bool(true)
+bool(true)
+string(1) "1"
+array(1) {
+ [2]=>
+ string(7) "String2"
+}
+bool(true)
+bool(true)
+string(7) "String2"
+bool(true)
+bool(true)
+string(1) "2"
+===REBIND/CONFLICT===
+string(7) "String0"
+string(7) "String1"
+string(7) "String2"
diff --git a/ext/pdo/tests/pdo_017.phpt b/ext/pdo/tests/pdo_017.phpt
new file mode 100644
index 0000000..31ee88b
--- /dev/null
+++ b/ext/pdo/tests/pdo_017.phpt
@@ -0,0 +1,74 @@
+--TEST--
+PDO Common: transactions
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+
+$db = PDOTest::factory();
+try {
+ $db->beginTransaction();
+} catch (PDOException $e) {
+ die('skip no working transactions: ' . $e->getMessage());
+}
+
+if ($db->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') {
+ require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
+ if (false === MySQLPDOTest::detect_transactional_mysql_engine($db)) {
+ die('skip your mysql configuration does not support working transactions');
+ }
+}
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+if ($db->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') {
+ require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
+ $suf = ' ENGINE=' . MySQLPDOTest::detect_transactional_mysql_engine($db);
+} else {
+ $suf = '';
+}
+
+$db->exec('CREATE TABLE test(id INT NOT NULL PRIMARY KEY, val VARCHAR(10))'.$suf);
+$db->exec("INSERT INTO test VALUES(1, 'A')");
+$db->exec("INSERT INTO test VALUES(2, 'B')");
+$db->exec("INSERT INTO test VALUES(3, 'C')");
+$delete = $db->prepare('DELETE FROM test');
+
+function countRows($action) {
+ global $db;
+ $select = $db->prepare('SELECT COUNT(*) FROM test');
+ $select->execute();
+ $res = $select->fetchColumn();
+ return "Counted $res rows after $action.\n";
+}
+
+echo countRows('insert');
+
+$db->beginTransaction();
+$delete->execute();
+echo countRows('delete');
+$db->rollBack();
+
+echo countRows('rollback');
+
+$db->beginTransaction();
+$delete->execute();
+echo countRows('delete');
+$db->commit();
+
+echo countRows('commit');
+
+?>
+--EXPECT--
+Counted 3 rows after insert.
+Counted 0 rows after delete.
+Counted 3 rows after rollback.
+Counted 0 rows after delete.
+Counted 0 rows after commit.
diff --git a/ext/pdo/tests/pdo_018.phpt b/ext/pdo/tests/pdo_018.phpt
new file mode 100644
index 0000000..7f27ce3
--- /dev/null
+++ b/ext/pdo/tests/pdo_018.phpt
@@ -0,0 +1,276 @@
+--TEST--
+PDO Common: serializing
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+if (!interface_exists('Serializable')) die('skip no Serializable interface');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+class TestBase implements Serializable
+{
+ public $BasePub = 'Public';
+ protected $BasePro = 'Protected';
+ private $BasePri = 'Private';
+
+ function serialize()
+ {
+ $serialized = array();
+ foreach($this as $prop => $val) {
+ $serialized[$prop] = $val;
+ }
+ $serialized = serialize($serialized);
+ echo __METHOD__ . "() = '$serialized'\n";
+ return $serialized;
+ }
+
+ function unserialize($serialized)
+ {
+ echo __METHOD__ . "($serialized)\n";
+ foreach(unserialize($serialized) as $prop => $val) {
+ $this->$prop = '#'.$val;
+ }
+ return true;
+ }
+}
+
+class TestDerived extends TestBase
+{
+ public $BasePub = 'DerivedPublic';
+ protected $BasePro = 'DerivdeProtected';
+ public $DerivedPub = 'Public';
+ protected $DerivedPro = 'Protected';
+ private $DerivedPri = 'Private';
+
+ function serialize()
+ {
+ echo __METHOD__ . "()\n";
+ return TestBase::serialize();
+ }
+
+ function unserialize($serialized)
+ {
+ echo __METHOD__ . "()\n";
+ return TestBase::unserialize($serialized);
+ }
+}
+
+class TestLeaf extends TestDerived
+{
+}
+
+$db->exec('CREATE TABLE classtypes(id int NOT NULL PRIMARY KEY, name VARCHAR(20) NOT NULL UNIQUE)');
+$db->exec('INSERT INTO classtypes VALUES(0, \'stdClass\')');
+$db->exec('INSERT INTO classtypes VALUES(1, \'TestBase\')');
+$db->exec('INSERT INTO classtypes VALUES(2, \'TestDerived\')');
+$db->exec('CREATE TABLE test(id int NOT NULL PRIMARY KEY, classtype int, val VARCHAR(255))');
+
+$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+
+var_dump($db->query('SELECT COUNT(*) FROM classtypes')->fetchColumn());
+var_dump($db->query('SELECT id, name FROM classtypes ORDER by id')->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_UNIQUE));
+
+$objs = array();
+$objs[0] = new stdClass;
+$objs[1] = new TestBase;
+$objs[2] = new TestDerived;
+$objs[3] = new TestLeaf;
+
+$stmt = $db->prepare('SELECT id FROM classtypes WHERE name=:cname');
+$stmt->bindParam(':cname', $cname);
+
+$ctypes = array();
+
+foreach($objs as $obj)
+{
+ $cname = get_class($obj);
+ $ctype = NULL; /* set default for non stored class name */
+ $stmt->execute();
+ $stmt->bindColumn('id', $ctype);
+ $stmt->fetch(PDO::FETCH_BOUND);
+ $ctypes[$cname] = $ctype;
+}
+
+echo "===TYPES===\n";
+var_dump($ctypes);
+
+unset($stmt);
+
+echo "===INSERT===\n";
+$stmt = $db->prepare('INSERT INTO test VALUES(:id, :classtype, :val)');
+$stmt->bindParam(':id', $idx);
+$stmt->bindParam(':classtype', $ctype);
+$stmt->bindParam(':val', $val);
+
+foreach($objs as $idx => $obj)
+{
+ $ctype = $ctypes[get_class($obj)];
+ if (method_exists($obj, 'serialize'))
+ {
+ $val = $obj->serialize();
+ }
+ else
+ {
+ $val = '';
+ }
+ $stmt->execute();
+}
+
+unset($stmt);
+
+echo "===DATA===\n";
+$res = $db->query('SELECT test.val FROM test')->fetchAll(PDO::FETCH_COLUMN);
+
+// For Oracle map NULL to empty string so the test doesn't diff
+if ($db->getAttribute(PDO::ATTR_DRIVER_NAME) == 'oci' && $res[0] === null) {
+ $res[0] = "";
+}
+var_dump($res);
+
+echo "===FAILURE===\n";
+try
+{
+ $db->query('SELECT classtypes.name AS name, test.val AS val FROM test LEFT JOIN classtypes ON test.classtype=classtypes.id')->fetchAll(PDO::FETCH_CLASS|PDO::FETCH_CLASSTYPE|PDO::FETCH_SERIALIZE, 'TestLeaf', array());
+}
+catch (PDOException $e)
+{
+ echo 'Exception:';
+ echo $e->getMessage()."\n";
+}
+
+echo "===COUNT===\n";
+var_dump($db->query('SELECT COUNT(*) FROM test LEFT JOIN classtypes ON test.classtype=classtypes.id WHERE (classtypes.id IS NULL OR classtypes.id > 0)')->fetchColumn());
+
+echo "===DATABASE===\n";
+$stmt = $db->prepare('SELECT classtypes.name AS name, test.val AS val FROM test LEFT JOIN classtypes ON test.classtype=classtypes.id WHERE (classtypes.id IS NULL OR classtypes.id > 0)');
+
+$stmt->execute();
+var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
+
+echo "===FETCHCLASS===\n";
+$stmt->execute();
+var_dump($stmt->fetchAll(PDO::FETCH_CLASS|PDO::FETCH_CLASSTYPE|PDO::FETCH_SERIALIZE, 'TestLeaf'));
+
+
+?>
+--EXPECTF--
+string(1) "3"
+array(3) {
+ [0]=>
+ string(8) "stdClass"
+ [1]=>
+ string(8) "TestBase"
+ [2]=>
+ string(11) "TestDerived"
+}
+===TYPES===
+array(4) {
+ ["stdClass"]=>
+ string(1) "0"
+ ["TestBase"]=>
+ string(1) "1"
+ ["TestDerived"]=>
+ string(1) "2"
+ ["TestLeaf"]=>
+ NULL
+}
+===INSERT===
+TestBase::serialize() = 'a:3:{s:7:"BasePub";s:6:"Public";s:7:"BasePro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}'
+TestDerived::serialize()
+TestBase::serialize() = 'a:5:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}'
+TestDerived::serialize()
+TestBase::serialize() = 'a:5:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}'
+===DATA===
+array(4) {
+ [0]=>
+ string(0) ""
+ [1]=>
+ string(91) "a:3:{s:7:"BasePub";s:6:"Public";s:7:"BasePro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}"
+ [2]=>
+ string(172) "a:5:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}"
+ [3]=>
+ string(172) "a:5:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}"
+}
+===FAILURE===
+Exception:SQLSTATE[HY000]: General error: cannot unserialize class
+===COUNT===
+string(1) "3"
+===DATABASE===
+array(3) {
+ [0]=>
+ array(2) {
+ ["name"]=>
+ string(8) "TestBase"
+ ["val"]=>
+ string(91) "a:3:{s:7:"BasePub";s:6:"Public";s:7:"BasePro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}"
+ }
+ [1]=>
+ array(2) {
+ ["name"]=>
+ string(11) "TestDerived"
+ ["val"]=>
+ string(172) "a:5:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}"
+ }
+ [2]=>
+ array(2) {
+ ["name"]=>
+ NULL
+ ["val"]=>
+ string(172) "a:5:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";s:7:"BasePri";s:7:"Private";}"
+ }
+}
+===FETCHCLASS===
+TestBase::unserialize(a:3:{s:7:"BasePub";s:6:"Public";s:7:"BasePro";s:9:"Protected";s:7:"BasePri";s:7:"Private";})
+TestDerived::unserialize()
+TestBase::unserialize(a:5:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";s:7:"BasePri";s:7:"Private";})
+TestDerived::unserialize()
+TestBase::unserialize(a:5:{s:7:"BasePub";s:13:"DerivedPublic";s:7:"BasePro";s:16:"DerivdeProtected";s:10:"DerivedPub";s:6:"Public";s:10:"DerivedPro";s:9:"Protected";s:7:"BasePri";s:7:"Private";})
+array(3) {
+ [0]=>
+ object(TestBase)#%d (3) {
+ ["BasePub"]=>
+ string(7) "#Public"
+ ["BasePro":protected]=>
+ string(10) "#Protected"
+ ["BasePri":"TestBase":private]=>
+ string(8) "#Private"
+ }
+ [1]=>
+ object(TestDerived)#%d (6) {
+ ["BasePub"]=>
+ string(14) "#DerivedPublic"
+ ["BasePro":protected]=>
+ string(17) "#DerivdeProtected"
+ ["DerivedPub"]=>
+ string(7) "#Public"
+ ["DerivedPro":protected]=>
+ string(10) "#Protected"
+ ["DerivedPri":"TestDerived":private]=>
+ string(7) "Private"
+ ["BasePri":"TestBase":private]=>
+ string(8) "#Private"
+ }
+ [2]=>
+ object(TestLeaf)#%d (6) {
+ ["BasePub"]=>
+ string(14) "#DerivedPublic"
+ ["BasePro":protected]=>
+ string(17) "#DerivdeProtected"
+ ["DerivedPub"]=>
+ string(7) "#Public"
+ ["DerivedPro":protected]=>
+ string(10) "#Protected"
+ ["DerivedPri":"TestDerived":private]=>
+ string(7) "Private"
+ ["BasePri":"TestBase":private]=>
+ string(8) "#Private"
+ }
+}
diff --git a/ext/pdo/tests/pdo_019.phpt b/ext/pdo/tests/pdo_019.phpt
new file mode 100644
index 0000000..f6d75bb
--- /dev/null
+++ b/ext/pdo/tests/pdo_019.phpt
@@ -0,0 +1,71 @@
+--TEST--
+PDO Common: fetch() and while()
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(idx int NOT NULL PRIMARY KEY, txt VARCHAR(20))');
+$db->exec('INSERT INTO test VALUES(0, \'String0\')');
+$db->exec('INSERT INTO test VALUES(1, \'String1\')');
+$db->exec('INSERT INTO test VALUES(2, \'String2\')');
+$db->exec('INSERT INTO test VALUES(3, \'String3\')');
+
+
+var_dump($db->query('SELECT COUNT(*) FROM test')->fetchColumn());
+
+$stmt = $db->prepare('SELECT idx, txt FROM test ORDER by idx');
+
+$stmt->execute();
+$cont = $stmt->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_UNIQUE);
+var_dump($cont);
+
+echo "===WHILE===\n";
+
+$stmt->bindColumn('idx', $idx);
+$stmt->bindColumn('txt', $txt);
+$stmt->execute();
+
+while($stmt->fetch(PDO::FETCH_BOUND)) {
+ var_dump(array($idx=>$txt));
+}
+
+?>
+--EXPECT--
+string(1) "4"
+array(4) {
+ [0]=>
+ string(7) "String0"
+ [1]=>
+ string(7) "String1"
+ [2]=>
+ string(7) "String2"
+ [3]=>
+ string(7) "String3"
+}
+===WHILE===
+array(1) {
+ [0]=>
+ string(7) "String0"
+}
+array(1) {
+ [1]=>
+ string(7) "String1"
+}
+array(1) {
+ [2]=>
+ string(7) "String2"
+}
+array(1) {
+ [3]=>
+ string(7) "String3"
+}
diff --git a/ext/pdo/tests/pdo_020.phpt b/ext/pdo/tests/pdo_020.phpt
new file mode 100644
index 0000000..dc7e4d1
--- /dev/null
+++ b/ext/pdo/tests/pdo_020.phpt
@@ -0,0 +1,34 @@
+--TEST--
+PDO Common: PDOStatement::columnCount
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id INT NOT NULL PRIMARY KEY, val VARCHAR(10), val2 VARCHAR(16))');
+$db->exec("INSERT INTO test VALUES(1, 'A', 'A')");
+$db->exec("INSERT INTO test VALUES(2, 'B', 'B')");
+$db->exec("INSERT INTO test VALUES(3, 'C', 'C')");
+
+foreach (array('SELECT id, val FROM test', 'SELECT id, val, val2 FROM test', 'SELECT COUNT(*) FROM test') as $sql) {
+
+ $stmt = $db->query($sql);
+ $res = $stmt->columnCount();
+ echo "Counted $res columns after $sql.\n";
+ $stmt = null;
+}
+
+?>
+--EXPECT--
+Counted 2 columns after SELECT id, val FROM test.
+Counted 3 columns after SELECT id, val, val2 FROM test.
+Counted 1 columns after SELECT COUNT(*) FROM test.
diff --git a/ext/pdo/tests/pdo_021.phpt b/ext/pdo/tests/pdo_021.phpt
new file mode 100644
index 0000000..fb25fc5
--- /dev/null
+++ b/ext/pdo/tests/pdo_021.phpt
@@ -0,0 +1,59 @@
+--TEST--
+PDO Common: PDOStatement::execute with parameters
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+if ($db->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') {
+ $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
+}
+
+$db->exec('CREATE TABLE test(id INT NOT NULL PRIMARY KEY, val VARCHAR(10), val2 VARCHAR(16))');
+
+$select = $db->prepare('SELECT COUNT(id) FROM test');
+
+$data = array(
+ array('10', 'Abc', 'zxy'),
+ array('20', 'Def', 'wvu'),
+ array('30', 'Ghi', 'tsr'),
+ array('40', 'Jkl', 'qpo'),
+ array('50', 'Mno', 'nml'),
+ array('60', 'Pqr', 'kji'),
+);
+
+
+// Insert using question mark placeholders
+$stmt = $db->prepare("INSERT INTO test VALUES(?, ?, ?)");
+foreach ($data as $row) {
+ $stmt->execute($row);
+}
+$select->execute();
+$num = $select->fetchColumn();
+echo 'There are ' . $num . " rows in the table.\n";
+
+// Insert using named parameters
+$stmt2 = $db->prepare("INSERT INTO test VALUES(:first, :second, :third)");
+foreach ($data as $row) {
+ $stmt2->execute(array(':first'=>($row[0] + 5), ':second'=>$row[1],
+ ':third'=>$row[2]));
+}
+
+$select->execute();
+$num = $select->fetchColumn();
+echo 'There are ' . $num . " rows in the table.\n";
+
+
+?>
+--EXPECT--
+There are 6 rows in the table.
+There are 12 rows in the table.
diff --git a/ext/pdo/tests/pdo_022.phpt b/ext/pdo/tests/pdo_022.phpt
new file mode 100644
index 0000000..daec14f
--- /dev/null
+++ b/ext/pdo/tests/pdo_022.phpt
@@ -0,0 +1,62 @@
+--TEST--
+PDO Common: PDOStatement::getColumnMeta
+--SKIPIF--
+<?php # vim:ft=php
+die('skip this feature is not yet finalized, no test makes sense');
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+/*
+ * Note well: meta information is a nightmare to handle portably.
+ * it's not really PDOs job.
+ * We've not yet defined exactly what makes sense for getColumnMeta,
+ * so no tests make any sense to anyone. When they do, we can enable
+ * this test file.
+ * TODO: filter out driver dependent components from this common core
+ * test file.
+ */
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id INT NOT NULL PRIMARY KEY, val VARCHAR(10), val2 VARCHAR(16))');
+$db->exec('insert2', "INSERT INTO test VALUES(:first, :second, :third)");
+
+$data = array(
+ array('10', 'Abc', 'zxy'),
+ array('20', 'Def', 'wvu'),
+ array('30', 'Ghi', 'tsr'),
+ array('40', 'Jkl', 'qpo'),
+ array('50', 'Mno', 'nml'),
+ array('60', 'Pqr', 'kji'),
+);
+
+
+// Insert using question mark placeholders
+$stmt = $db->prepare("INSERT INTO test VALUES(?, ?, ?)");
+foreach ($data as $row) {
+ $stmt->execute($row);
+}
+
+// Retrieve column metadata for a result set returned by explicit SELECT
+$select = $db->query('SELECT id, val, val2 FROM test');
+$meta = $select->getColumnMeta(0);
+var_dump($meta);
+$meta = $select->getColumnMeta(1);
+var_dump($meta);
+$meta = $select->getColumnMeta(2);
+var_dump($meta);
+
+// Retrieve column metadata for a result set returned by a function
+$select = $db->query('SELECT COUNT(*) FROM test');
+$meta = $select->getColumnMeta(0);
+var_dump($meta);
+
+?>
+--EXPECT--
+The unexpected!
diff --git a/ext/pdo/tests/pdo_023.phpt b/ext/pdo/tests/pdo_023.phpt
new file mode 100644
index 0000000..564bcf8
--- /dev/null
+++ b/ext/pdo/tests/pdo_023.phpt
@@ -0,0 +1,112 @@
+--TEST--
+PDO Common: extending PDO
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+
+class PDOStatementX extends PDOStatement
+{
+ public $test1 = 1;
+
+ protected function __construct()
+ {
+ $this->test2 = 2;
+ $this->test2 = 22;
+ echo __METHOD__ . "()\n";
+ }
+
+ function __destruct()
+ {
+ echo __METHOD__ . "()\n";
+ }
+}
+
+class PDODatabaseX extends PDO
+{
+ public $test1 = 1;
+
+ function __destruct()
+ {
+ echo __METHOD__ . "()\n";
+ }
+
+ function test()
+ {
+ $this->test2 = 2;
+ var_dump($this->test1);
+ var_dump($this->test2);
+ $this->test2 = 22;
+ }
+
+ function query($sql)
+ {
+ echo __METHOD__ . "()\n";
+ $stmt = parent::prepare($sql, array(PDO::ATTR_STATEMENT_CLASS=>array('PDOStatementx')));
+ $stmt->execute();
+ return $stmt;
+ }
+}
+
+$db = PDOTest::factory('PDODatabaseX');
+$db->test();
+var_dump($db);
+
+$db->query('CREATE TABLE test(id INT NOT NULL PRIMARY KEY, val VARCHAR(10))');
+$db->query('INSERT INTO test VALUES(0, \'A\')');
+$db->query('INSERT INTO test VALUES(1, \'B\')');
+
+
+$stmt = $db->query('SELECT val, id FROM test');
+var_dump($stmt);
+var_dump($stmt->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_UNIQUE));
+
+$stmt = NULL;
+$db = NULL;
+
+
+?>
+--EXPECTF--
+int(1)
+int(2)
+object(PDODatabaseX)#%d (2) {
+ ["test1"]=>
+ int(1)
+ ["test2"]=>
+ int(22)
+}
+PDODatabaseX::query()
+PDOStatementX::__construct()
+PDOStatementX::__destruct()
+PDODatabaseX::query()
+PDOStatementX::__construct()
+PDOStatementX::__destruct()
+PDODatabaseX::query()
+PDOStatementX::__construct()
+PDOStatementX::__destruct()
+PDODatabaseX::query()
+PDOStatementX::__construct()
+object(PDOStatementX)#%d (3) {
+ ["test1"]=>
+ int(1)
+ ["queryString"]=>
+ string(24) "SELECT val, id FROM test"
+ ["test2"]=>
+ int(22)
+}
+array(2) {
+ ["A"]=>
+ string(1) "0"
+ ["B"]=>
+ string(1) "1"
+}
+PDOStatementX::__destruct()
+PDODatabaseX::__destruct()
diff --git a/ext/pdo/tests/pdo_024.phpt b/ext/pdo/tests/pdo_024.phpt
new file mode 100644
index 0000000..1b4f841
--- /dev/null
+++ b/ext/pdo/tests/pdo_024.phpt
@@ -0,0 +1,35 @@
+--TEST--
+PDO Common: assert that bindParam does not modify parameter
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec('create table test (id int, name varchar(10))');
+
+$stmt = $db->prepare('insert into test (id, name) values(0, :name)');
+$name = NULL;
+$before_bind = $name;
+$stmt->bindParam(':name', $name);
+if ($name !== $before_bind) {
+ echo "bind: fail\n";
+} else {
+ echo "bind: success\n";
+}
+var_dump($stmt->execute());
+var_dump($db->query('select name from test where id=0')->fetchColumn());
+
+?>
+--EXPECT--
+bind: success
+bool(true)
+NULL
diff --git a/ext/pdo/tests/pdo_025.phpt b/ext/pdo/tests/pdo_025.phpt
new file mode 100644
index 0000000..d16d8dd
--- /dev/null
+++ b/ext/pdo/tests/pdo_025.phpt
@@ -0,0 +1,113 @@
+--TEST--
+PDO Common: PDO::FETCH_INTO
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id INT NOT NULL PRIMARY KEY, val VARCHAR(10), val2 VARCHAR(16))');
+
+$data = array(
+ array('10', 'Abc', 'zxy'),
+ array('20', 'Def', 'wvu'),
+ array('30', 'Ghi', 'tsr'),
+ array('40', 'Jkl', 'qpo'),
+ array('50', 'Mno', 'nml'),
+ array('60', 'Pqr', 'kji'),
+);
+
+
+// Insert using question mark placeholders
+$stmt = $db->prepare("INSERT INTO test VALUES(?, ?, ?)");
+foreach ($data as $row) {
+ $stmt->execute($row);
+}
+
+class Test {
+ public $id, $val, $val2;
+}
+
+$stmt = $db->prepare('SELECT * FROM test');
+$stmt->setFetchMode(PDO::FETCH_INTO, new Test);
+$stmt->execute();
+
+foreach($stmt as $obj) {
+ var_dump($obj);
+}
+
+echo "===FAIL===\n";
+
+class Fail {
+ protected $id;
+ public $val, $val2;
+}
+
+$stmt->setFetchMode(PDO::FETCH_INTO, new Fail);
+$stmt->execute();
+
+foreach($stmt as $obj) {
+ var_dump($obj);
+}
+
+?>
+--EXPECTF--
+object(Test)#%d (3) {
+ ["id"]=>
+ string(2) "10"
+ ["val"]=>
+ string(3) "Abc"
+ ["val2"]=>
+ string(3) "zxy"
+}
+object(Test)#%d (3) {
+ ["id"]=>
+ string(2) "20"
+ ["val"]=>
+ string(3) "Def"
+ ["val2"]=>
+ string(3) "wvu"
+}
+object(Test)#%d (3) {
+ ["id"]=>
+ string(2) "30"
+ ["val"]=>
+ string(3) "Ghi"
+ ["val2"]=>
+ string(3) "tsr"
+}
+object(Test)#%d (3) {
+ ["id"]=>
+ string(2) "40"
+ ["val"]=>
+ string(3) "Jkl"
+ ["val2"]=>
+ string(3) "qpo"
+}
+object(Test)#%d (3) {
+ ["id"]=>
+ string(2) "50"
+ ["val"]=>
+ string(3) "Mno"
+ ["val2"]=>
+ string(3) "nml"
+}
+object(Test)#%d (3) {
+ ["id"]=>
+ string(2) "60"
+ ["val"]=>
+ string(3) "Pqr"
+ ["val2"]=>
+ string(3) "kji"
+}
+===FAIL===
+
+Fatal error: Cannot access protected property Fail::$id in %spdo_025.php on line %d%A
diff --git a/ext/pdo/tests/pdo_026.phpt b/ext/pdo/tests/pdo_026.phpt
new file mode 100644
index 0000000..d993f32
--- /dev/null
+++ b/ext/pdo/tests/pdo_026.phpt
@@ -0,0 +1,111 @@
+--TEST--
+PDO Common: extending PDO (2)
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+
+$data = array(
+ array('10', 'Abc', 'zxy'),
+ array('20', 'Def', 'wvu'),
+ array('30', 'Ghi', 'tsr'),
+);
+
+class PDOStatementX extends PDOStatement
+{
+ public $dbh;
+
+ protected function __construct($dbh)
+ {
+ $this->dbh = $dbh;
+ echo __METHOD__ . "()\n";
+ }
+
+ function __destruct()
+ {
+ echo __METHOD__ . "()\n";
+ }
+}
+
+class PDODatabase extends PDO
+{
+ function __destruct()
+ {
+ echo __METHOD__ . "()\n";
+ }
+
+ function query($sql)
+ {
+ echo __METHOD__ . "()\n";
+ $stmt = $this->prepare($sql, array(PDO::ATTR_STATEMENT_CLASS=>array('PDOStatementx', array($this))));
+ $stmt->setFetchMode(PDO::FETCH_ASSOC);
+ $stmt->execute();
+ return $stmt;
+ }
+}
+
+$db = PDOTest::factory('PDODatabase');
+var_dump(get_class($db));
+
+$db->exec('CREATE TABLE test(id INT NOT NULL PRIMARY KEY, val VARCHAR(10), val2 VARCHAR(16))');
+
+$stmt = $db->prepare("INSERT INTO test VALUES(?, ?, ?)");
+var_dump(get_class($stmt));
+foreach ($data as $row) {
+ $stmt->execute($row);
+}
+
+unset($stmt);
+
+$stmt = $db->query('SELECT * FROM test');
+var_dump(get_class($stmt));
+var_dump(get_class($stmt->dbh));
+
+foreach($stmt as $obj) {
+ var_dump($obj);
+}
+
+echo "===DONE===\n";
+?>
+--EXPECT--
+string(11) "PDODatabase"
+string(12) "PDOStatement"
+PDODatabase::query()
+PDOStatementX::__construct()
+string(13) "PDOStatementX"
+string(11) "PDODatabase"
+array(3) {
+ ["id"]=>
+ string(2) "10"
+ ["val"]=>
+ string(3) "Abc"
+ ["val2"]=>
+ string(3) "zxy"
+}
+array(3) {
+ ["id"]=>
+ string(2) "20"
+ ["val"]=>
+ string(3) "Def"
+ ["val2"]=>
+ string(3) "wvu"
+}
+array(3) {
+ ["id"]=>
+ string(2) "30"
+ ["val"]=>
+ string(3) "Ghi"
+ ["val2"]=>
+ string(3) "tsr"
+}
+===DONE===
+PDOStatementX::__destruct()
+PDODatabase::__destruct()
diff --git a/ext/pdo/tests/pdo_027.phpt b/ext/pdo/tests/pdo_027.phpt
new file mode 100644
index 0000000..1d9990d
--- /dev/null
+++ b/ext/pdo/tests/pdo_027.phpt
@@ -0,0 +1,29 @@
+--TEST--
+PDO Common: PDO::FETCH_LAZY
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec('create table test (id int, name varchar(10))');
+$db->exec("INSERT INTO test (id,name) VALUES(1,'test1')");
+$db->exec("INSERT INTO test (id,name) VALUES(2,'test2')");
+
+foreach ($db->query("SELECT * FROM test", PDO::FETCH_LAZY) as $v) {
+ echo "lazy: " . $v->id.$v->name."\n";
+}
+echo "End\n";
+?>
+--EXPECT--
+lazy: 1test1
+lazy: 2test2
+End
diff --git a/ext/pdo/tests/pdo_028.phpt b/ext/pdo/tests/pdo_028.phpt
new file mode 100644
index 0000000..0d1058d
--- /dev/null
+++ b/ext/pdo/tests/pdo_028.phpt
@@ -0,0 +1,45 @@
+--TEST--
+PDO Common: bindValue
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id int NOT NULL PRIMARY KEY, val1 VARCHAR(10), val2 VARCHAR(10), val3 VARCHAR(10))');
+$stmt = $db->prepare('INSERT INTO test values (1, ?, ?, ?)');
+
+$data = array("one", "two", "three");
+
+foreach ($data as $i => $v) {
+ $stmt->bindValue($i+1, $v);
+}
+$stmt->execute();
+
+$stmt = $db->prepare('SELECT * from test');
+$stmt->execute();
+
+var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
+?>
+--EXPECT--
+array(1) {
+ [0]=>
+ array(4) {
+ ["id"]=>
+ string(1) "1"
+ ["val1"]=>
+ string(3) "one"
+ ["val2"]=>
+ string(3) "two"
+ ["val3"]=>
+ string(5) "three"
+ }
+}
diff --git a/ext/pdo/tests/pdo_029.phpt b/ext/pdo/tests/pdo_029.phpt
new file mode 100644
index 0000000..f3dc1f2
--- /dev/null
+++ b/ext/pdo/tests/pdo_029.phpt
@@ -0,0 +1,125 @@
+--TEST--
+PDO Common: extending PDO (3)
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+
+$data = array(
+ array('10', 'Abc', 'zxy'),
+ array('20', 'Def', 'wvu'),
+ array('30', 'Ghi', 'tsr'),
+);
+
+class PDOStatementX extends PDOStatement
+{
+ public $dbh;
+
+ protected function __construct($dbh)
+ {
+ $this->dbh = $dbh;
+ echo __METHOD__ . "()\n";
+ }
+
+ function __destruct()
+ {
+ echo __METHOD__ . "()\n";
+ }
+
+ function execute($params = array())
+ {
+ echo __METHOD__ . "()\n";
+ parent::execute();
+ }
+}
+
+class PDODatabase extends PDO
+{
+ function __destruct()
+ {
+ echo __METHOD__ . "()\n";
+ }
+
+ function query($sql)
+ {
+ echo __METHOD__ . "()\n";
+ $stmt = $this->prepare($sql, array(PDO::ATTR_STATEMENT_CLASS=>array('PDOStatementx', array($this))));
+ $stmt->setFetchMode(PDO::FETCH_ASSOC);
+ $stmt->execute();
+ return $stmt;
+ }
+}
+
+$db = PDOTest::factory('PDODatabase');
+var_dump(get_class($db));
+
+$db->exec('CREATE TABLE test(id INT NOT NULL PRIMARY KEY, val VARCHAR(10), val2 VARCHAR(16))');
+
+$stmt = $db->prepare("INSERT INTO test VALUES(?, ?, ?)");
+var_dump(get_class($stmt));
+foreach ($data as $row) {
+ $stmt->execute($row);
+}
+
+unset($stmt);
+
+echo "===QUERY===\n";
+
+$stmt = $db->query('SELECT * FROM test');
+var_dump(get_class($stmt));
+var_dump(get_class($stmt->dbh));
+
+echo "===FOREACH===\n";
+
+foreach($stmt as $obj) {
+ var_dump($obj);
+}
+
+echo "===DONE===\n";
+exit(0);
+?>
+--EXPECT--
+string(11) "PDODatabase"
+string(12) "PDOStatement"
+===QUERY===
+PDODatabase::query()
+PDOStatementX::__construct()
+PDOStatementX::execute()
+string(13) "PDOStatementX"
+string(11) "PDODatabase"
+===FOREACH===
+array(3) {
+ ["id"]=>
+ string(2) "10"
+ ["val"]=>
+ string(3) "Abc"
+ ["val2"]=>
+ string(3) "zxy"
+}
+array(3) {
+ ["id"]=>
+ string(2) "20"
+ ["val"]=>
+ string(3) "Def"
+ ["val2"]=>
+ string(3) "wvu"
+}
+array(3) {
+ ["id"]=>
+ string(2) "30"
+ ["val"]=>
+ string(3) "Ghi"
+ ["val2"]=>
+ string(3) "tsr"
+}
+===DONE===
+PDOStatementX::__destruct()
+PDODatabase::__destruct()
diff --git a/ext/pdo/tests/pdo_030.phpt b/ext/pdo/tests/pdo_030.phpt
new file mode 100644
index 0000000..243e94a
--- /dev/null
+++ b/ext/pdo/tests/pdo_030.phpt
@@ -0,0 +1,139 @@
+--TEST--
+PDO Common: extending PDO (4)
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+
+$data = array(
+ array('10', 'Abc', 'zxy'),
+ array('20', 'Def', 'wvu'),
+ array('30', 'Ghi', 'tsr'),
+);
+
+class PDOStatementX extends PDOStatement
+{
+ public $dbh;
+
+ protected function __construct($dbh)
+ {
+ $this->dbh = $dbh;
+ $this->setFetchMode(PDO::FETCH_ASSOC);
+ echo __METHOD__ . "()\n";
+ }
+
+ function __destruct()
+ {
+ echo __METHOD__ . "()\n";
+ }
+
+ function execute($params = array())
+ {
+ echo __METHOD__ . "()\n";
+ parent::execute();
+ }
+}
+
+class PDODatabase extends PDO
+{
+ function __destruct()
+ {
+ echo __METHOD__ . "()\n";
+ }
+
+ function query($sql)
+ {
+ echo __METHOD__ . "()\n";
+ return parent::query($sql);
+ }
+}
+
+$db = PDOTest::factory('PDODatabase');
+var_dump(get_class($db));
+
+$db->exec('CREATE TABLE test(id INT NOT NULL PRIMARY KEY, val VARCHAR(10), val2 VARCHAR(16))');
+
+$stmt = $db->prepare("INSERT INTO test VALUES(?, ?, ?)");
+var_dump(get_class($stmt));
+foreach ($data as $row) {
+ $stmt->execute($row);
+}
+
+unset($stmt);
+
+echo "===QUERY===\n";
+
+var_dump($db->getAttribute(PDO::ATTR_STATEMENT_CLASS));
+$db->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('PDOStatementx', array($db)));
+var_dump($db->getAttribute(PDO::ATTR_STATEMENT_CLASS));
+$stmt = $db->query('SELECT * FROM test');
+var_dump(get_class($stmt));
+var_dump(get_class($stmt->dbh));
+
+echo "===FOREACH===\n";
+
+foreach($stmt as $obj) {
+ var_dump($obj);
+}
+
+echo "===DONE===\n";
+exit(0);
+?>
+--EXPECTF--
+string(11) "PDODatabase"
+string(12) "PDOStatement"
+===QUERY===
+array(1) {
+ [0]=>
+ string(12) "PDOStatement"
+}
+array(2) {
+ [0]=>
+ string(13) "PDOStatementX"
+ [1]=>
+ array(1) {
+ [0]=>
+ object(PDODatabase)#%d (0) {
+ }
+ }
+}
+PDODatabase::query()
+PDOStatementX::__construct()
+string(13) "PDOStatementX"
+string(11) "PDODatabase"
+===FOREACH===
+array(3) {
+ ["id"]=>
+ string(2) "10"
+ ["val"]=>
+ string(3) "Abc"
+ ["val2"]=>
+ string(3) "zxy"
+}
+array(3) {
+ ["id"]=>
+ string(2) "20"
+ ["val"]=>
+ string(3) "Def"
+ ["val2"]=>
+ string(3) "wvu"
+}
+array(3) {
+ ["id"]=>
+ string(2) "30"
+ ["val"]=>
+ string(3) "Ghi"
+ ["val2"]=>
+ string(3) "tsr"
+}
+===DONE===
+PDOStatementX::__destruct()
+PDODatabase::__destruct()
diff --git a/ext/pdo/tests/pdo_031.phpt b/ext/pdo/tests/pdo_031.phpt
new file mode 100644
index 0000000..9065ce9
--- /dev/null
+++ b/ext/pdo/tests/pdo_031.phpt
@@ -0,0 +1,63 @@
+--TEST--
+PDO Common: PDOStatement SPL iterator
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+if (!extension_loaded('SPL')) die('skip SPL not available');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+if (!class_exists('RecursiveArrayIterator', false)) die('skip Class RecursiveArrayIterator missing');
+if (!class_exists('RecursiveTreeIterator', false) && !file_exists(getenv('REDIR_TEST_DIR').'../../spl/examples/recursivetreeiterator.inc')) die('skip Class RecursiveTreeIterator missing');
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+if (!class_exists('RecursiveTreeIterator', false)) require_once(getenv('REDIR_TEST_DIR').'../../spl/examples/recursivetreeiterator.inc');
+
+$data = array(
+ array('10', 'Abc', 'zxy'),
+ array('20', 'Def', 'wvu'),
+ array('30', 'Ghi', 'tsr'),
+);
+
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id INT NOT NULL PRIMARY KEY, val VARCHAR(10), val2 VARCHAR(16))');
+
+$stmt = $db->prepare("INSERT INTO test VALUES(?, ?, ?)");
+foreach ($data as $row) {
+ $stmt->execute($row);
+}
+
+unset($stmt);
+
+echo "===QUERY===\n";
+
+$stmt = $db->query('SELECT * FROM test');
+
+foreach(new RecursiveTreeIterator(new RecursiveArrayIterator($stmt->fetchAll(PDO::FETCH_ASSOC)), RecursiveTreeIterator::BYPASS_KEY) as $c=>$v)
+{
+ echo "$v [$c]\n";
+}
+
+echo "===DONE===\n";
+exit(0);
+?>
+--EXPECT--
+===QUERY===
+|-Array [0]
+| |-10 [id]
+| |-Abc [val]
+| \-zxy [val2]
+|-Array [1]
+| |-20 [id]
+| |-Def [val]
+| \-wvu [val2]
+\-Array [2]
+ |-30 [id]
+ |-Ghi [val]
+ \-tsr [val2]
+===DONE===
diff --git a/ext/pdo/tests/pdo_032.phpt b/ext/pdo/tests/pdo_032.phpt
new file mode 100644
index 0000000..aed6dd3
--- /dev/null
+++ b/ext/pdo/tests/pdo_032.phpt
@@ -0,0 +1,83 @@
+--TEST--
+PDO Common: PDO::ATTR_CASE
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test(id int NOT NULL PRIMARY KEY, val VARCHAR(10))');
+$db->exec("INSERT INTO test VALUES(1, 'A')");
+$db->exec("INSERT INTO test VALUES(2, 'B')");
+$db->exec("INSERT INTO test VALUES(3, 'C')");
+
+// Lower case columns
+$db->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
+$stmt = $db->prepare('SELECT * from test');
+$stmt->execute();
+var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
+$stmt->closeCursor();
+
+// Upper case columns
+$db->setAttribute(PDO::ATTR_CASE, PDO::CASE_UPPER);
+$stmt = $db->prepare('SELECT * from test');
+$stmt->execute();
+var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
+$stmt->closeCursor();
+
+?>
+--EXPECT--
+array(3) {
+ [0]=>
+ array(2) {
+ ["id"]=>
+ string(1) "1"
+ ["val"]=>
+ string(1) "A"
+ }
+ [1]=>
+ array(2) {
+ ["id"]=>
+ string(1) "2"
+ ["val"]=>
+ string(1) "B"
+ }
+ [2]=>
+ array(2) {
+ ["id"]=>
+ string(1) "3"
+ ["val"]=>
+ string(1) "C"
+ }
+}
+array(3) {
+ [0]=>
+ array(2) {
+ ["ID"]=>
+ string(1) "1"
+ ["VAL"]=>
+ string(1) "A"
+ }
+ [1]=>
+ array(2) {
+ ["ID"]=>
+ string(1) "2"
+ ["VAL"]=>
+ string(1) "B"
+ }
+ [2]=>
+ array(2) {
+ ["ID"]=>
+ string(1) "3"
+ ["VAL"]=>
+ string(1) "C"
+ }
+}
diff --git a/ext/pdo/tests/pdo_033.phpt b/ext/pdo/tests/pdo_033.phpt
new file mode 100644
index 0000000..6f78be6
--- /dev/null
+++ b/ext/pdo/tests/pdo_033.phpt
@@ -0,0 +1,44 @@
+--TEST--
+PDO Common: PDO::quote()
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$unquoted = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+
+$quoted = $db->quote($unquoted);
+
+$len = strlen($unquoted);
+
+@$db->exec("DROP TABLE test");
+
+$db->query("CREATE TABLE test (t char($len))");
+$db->query("INSERT INTO test (t) VALUES($quoted)");
+
+$stmt = $db->prepare('SELECT * from test');
+$stmt->execute();
+
+print_r($stmt->fetchAll(PDO::FETCH_ASSOC));
+
+$db->exec("DROP TABLE test");
+
+?>
+--EXPECT--
+Array
+(
+ [0] => Array
+ (
+ [t] => !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
+ )
+
+)
diff --git a/ext/pdo/tests/pdo_034.phpt b/ext/pdo/tests/pdo_034.phpt
new file mode 100644
index 0000000..3803c2f
--- /dev/null
+++ b/ext/pdo/tests/pdo_034.phpt
@@ -0,0 +1,62 @@
+--TEST--
+PDO Common: PDO::FETCH_KEY_PAIR fetch mode test
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec("CREATE TABLE test (a varchar(100), b varchar(100), c varchar(100))");
+
+for ($i = 0; $i < 5; $i++) {
+ $db->exec("INSERT INTO test (a,b,c) VALUES('test".$i."','".$i."','".$i."')");
+}
+
+var_dump($db->query("SELECT a,b FROM test")->fetch(PDO::FETCH_KEY_PAIR));
+var_dump($db->query("SELECT a,b FROM test")->fetchAll(PDO::FETCH_KEY_PAIR));
+var_dump($db->query("SELECT * FROM test")->fetch(PDO::FETCH_KEY_PAIR));
+var_dump($db->query("SELECT a,a FROM test")->fetchAll(PDO::FETCH_KEY_PAIR));
+
+?>
+--EXPECTF--
+array(1) {
+ ["test0"]=>
+ string(1) "0"
+}
+array(5) {
+ ["test0"]=>
+ string(1) "0"
+ ["test1"]=>
+ string(1) "1"
+ ["test2"]=>
+ string(1) "2"
+ ["test3"]=>
+ string(1) "3"
+ ["test4"]=>
+ string(1) "4"
+}
+
+Warning: PDOStatement::fetch(): SQLSTATE[HY000]: General error: PDO::FETCH_KEY_PAIR fetch mode requires the result set to contain extactly 2 columns. in %spdo_034.php on line %d
+
+Warning: PDOStatement::fetch(): SQLSTATE[HY000]: General error%spdo_034.php on line %d
+bool(false)
+array(5) {
+ ["test0"]=>
+ string(5) "test0"
+ ["test1"]=>
+ string(5) "test1"
+ ["test2"]=>
+ string(5) "test2"
+ ["test3"]=>
+ string(5) "test3"
+ ["test4"]=>
+ string(5) "test4"
+}
diff --git a/ext/pdo/tests/pdo_035.phpt b/ext/pdo/tests/pdo_035.phpt
new file mode 100644
index 0000000..c35c504
--- /dev/null
+++ b/ext/pdo/tests/pdo_035.phpt
@@ -0,0 +1,22 @@
+--TEST--
+PDO Common: PDORow + get_parent_class()
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo_sqlite')) die ("skip Need PDO_SQlite support");
+?>
+--FILE--
+<?php
+$db = new PDO('sqlite::memory:');
+$db->exec('CREATE TABLE test (id int)');
+$db->exec('INSERT INTO test VALUES (23)');
+
+$stmt = $db->prepare('SELECT id FROM test');
+$stmt->execute();
+$result = $stmt->fetch(PDO::FETCH_LAZY);
+
+echo get_class($result), "\n";
+var_dump(get_parent_class($result));
+?>
+--EXPECT--
+PDORow
+bool(false)
diff --git a/ext/pdo/tests/pdo_036.phpt b/ext/pdo/tests/pdo_036.phpt
new file mode 100644
index 0000000..94006c9
--- /dev/null
+++ b/ext/pdo/tests/pdo_036.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Testing PDORow and PDOStatement instances with Reflection
+--SKIPIF--
+<?php if (!extension_loaded('pdo')) die('skip'); ?>
+--FILE--
+<?php
+
+$instance = new reflectionclass('pdorow');
+$x = $instance->newInstance();
+var_dump($x);
+
+$instance = new reflectionclass('pdostatement');
+$x = $instance->newInstance();
+var_dump($x);
+
+?>
+--EXPECTF--
+object(PDORow)#%d (0) {
+}
+object(PDOStatement)#%d (1) {
+ [%u|b%"queryString"]=>
+ NULL
+}
diff --git a/ext/pdo/tests/pdo_037.phpt b/ext/pdo/tests/pdo_037.phpt
new file mode 100644
index 0000000..a0ead4b
--- /dev/null
+++ b/ext/pdo/tests/pdo_037.phpt
@@ -0,0 +1,19 @@
+--TEST--
+Crash when calling a method of a class that inherits PDOStatement
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo')) die('skip');
+?>
+--FILE--
+<?php
+
+class MyStatement extends PDOStatement
+{
+}
+
+$obj = new MyStatement;
+var_dump($obj->foo());
+
+?>
+--EXPECTF--
+Fatal error: Call to undefined method MyStatement::foo() in %s on line %d
diff --git a/ext/pdo/tests/pdo_test.inc b/ext/pdo/tests/pdo_test.inc
new file mode 100644
index 0000000..443c8dd
--- /dev/null
+++ b/ext/pdo/tests/pdo_test.inc
@@ -0,0 +1,84 @@
+<?php
+# PDO test framework utilities
+
+if (getenv('PDOTEST_DSN') === false) {
+ $common = '';
+ $append = false;
+ foreach(file(dirname($_SERVER['PHP_SELF']).'/common.phpt') as $line) {
+ if ($append) {
+ $common .= $line;
+ } elseif (trim($line) == '--REDIRECTTEST--') {
+ $append = true;
+ }
+ }
+ $conf = eval($common);
+ foreach($conf['ENV'] as $n=>$v) putenv("$n=$v");
+}
+
+class PDOTest {
+ // create an instance of the PDO driver, based on
+ // the current environment
+ static function factory($classname = 'PDO', $drop_test_tables = true) {
+ $dsn = getenv('PDOTEST_DSN');
+ $user = getenv('PDOTEST_USER');
+ $pass = getenv('PDOTEST_PASS');
+ $attr = getenv('PDOTEST_ATTR');
+ if (is_string($attr) && strlen($attr)) {
+ $attr = unserialize($attr);
+ } else {
+ $attr = null;
+ }
+
+ if ($user === false) $user = NULL;
+ if ($pass === false) $pass = NULL;
+
+ $db = new $classname($dsn, $user, $pass, $attr);
+
+ if (!$db) {
+ die("Could not create PDO object (DSN=$dsn, user=$user)\n");
+ }
+
+ // clean up any crufty test tables we might have left behind
+ // on a previous run
+ static $test_tables = array(
+ 'test',
+ 'test2',
+ 'classtypes'
+ );
+ if ($drop_test_tables) {
+ foreach ($test_tables as $table) {
+ $db->exec("DROP TABLE $table");
+ }
+ }
+
+ $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
+ $db->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
+ $db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true);
+ return $db;
+ }
+
+ static function skip() {
+ try {
+ $db = PDOTest::factory();
+ } catch (PDOException $e) {
+ die("skip " . $e->getMessage());
+ }
+ }
+
+ static function test_factory($file) {
+ $config = self::get_config($file);
+ foreach ($config['ENV'] as $k => $v) {
+ putenv("$k=$v");
+ }
+ return self::factory();
+ }
+
+ static function get_config($file) {
+ $data = file_get_contents($file);
+ $data = preg_replace('/^.*--REDIRECTTEST--/s', '', $data);
+ $config = eval($data);
+
+ return $config;
+ }
+}
+?>
diff --git a/ext/pdo/tests/pdorow.phpt b/ext/pdo/tests/pdorow.phpt
new file mode 100644
index 0000000..bcfd8ff
--- /dev/null
+++ b/ext/pdo/tests/pdorow.phpt
@@ -0,0 +1,12 @@
+--TEST--
+Trying instantiate a PDORow object manually
+--SKIPIF--
+<?php if (!extension_loaded('pdo')) die('skip'); ?>
+--FILE--
+<?php
+
+new PDORow;
+
+?>
+--EXPECTF--
+Fatal error: PDORow::__construct(): You should not create a PDOStatement manually in %s on line %d
diff --git a/ext/pdo/tests/pecl_bug_5217.phpt b/ext/pdo/tests/pecl_bug_5217.phpt
new file mode 100644
index 0000000..34de925
--- /dev/null
+++ b/ext/pdo/tests/pecl_bug_5217.phpt
@@ -0,0 +1,29 @@
+--TEST--
+PDO Common: PECL Bug #5217 (serialize/unserialze safety)
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+try {
+ $ser = serialize($db);
+ debug_zval_dump($ser);
+ $db = unserialize($ser);
+ $db->exec('CREATE TABLE test (id int NOT NULL PRIMARY KEY, val VARCHAR(10))');
+} catch (Exception $e) {
+ echo "Safely caught " . $e->getMessage() . "\n";
+}
+
+echo "PHP Didn't crash!\n";
+?>
+--EXPECT--
+Safely caught You cannot serialize or unserialize PDO instances
+PHP Didn't crash!
diff --git a/ext/pdo/tests/pecl_bug_5772.phpt b/ext/pdo/tests/pecl_bug_5772.phpt
new file mode 100644
index 0000000..e38c894
--- /dev/null
+++ b/ext/pdo/tests/pecl_bug_5772.phpt
@@ -0,0 +1,29 @@
+--TEST--
+PDO Common: PECL Bug #5772 (PDO::FETCH_FUNC breaks on mixed case func name)
+--SKIPIF--
+<?php # vim:ft=php:
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec("CREATE TABLE test (id int NOT NULL, PRIMARY KEY (id))");
+$db->exec("INSERT INTO test (id) VALUES (1)");
+
+function heLLO($row) {
+ return $row;
+}
+
+foreach ($db->query("SELECT * FROM test")->fetchAll(PDO::FETCH_FUNC, 'heLLO') as $row) {
+ var_dump($row);
+}
+
+--EXPECT--
+string(1) "1"
diff --git a/ext/pdo/tests/pecl_bug_5809.phpt b/ext/pdo/tests/pecl_bug_5809.phpt
new file mode 100644
index 0000000..bb41281
--- /dev/null
+++ b/ext/pdo/tests/pecl_bug_5809.phpt
@@ -0,0 +1,34 @@
+--TEST--
+PDO Common: PECL Bug #5809 (PDOStatement::execute(array()) changes param)
+--SKIPIF--
+<?php # vim:ft=php:
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec("CREATE TABLE test (id int NOT NULL, PRIMARY KEY (id))");
+$db->exec("INSERT INTO test (id) VALUES (1)");
+
+$values = array(1);
+var_dump($values);
+$stmt = $db->prepare('SELECT * FROM test WHERE id = ?');
+$stmt->execute($values);
+var_dump($values);
+
+--EXPECT--
+array(1) {
+ [0]=>
+ int(1)
+}
+array(1) {
+ [0]=>
+ int(1)
+}