--- /dev/null
+--TEST--
+PDO MySQL Bug #38546 (bindParam incorrect processing of bool types)
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo') || !extension_loaded('pdo_mysql')) die('skip not loaded');
+require dirname(__FILE__) . '/config.inc';
+require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+require dirname(__FILE__) . '/config.inc';
+require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
+$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
+
+$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
+
+$db->exec("DROP TABLE IF EXISTS test");
+
+$query = "CREATE TABLE test(
+ uid MEDIUMINT UNSIGNED NOT NULL,
+ some_bool_1 BOOL NOT NULL,
+ some_bool_2 BOOL NOT NULL,
+ some_int TINYINT NOT NULL
+ )";
+$db->exec($query);
+
+$st = $db->prepare("INSERT INTO test (uid, some_bool_1, some_bool_2, some_int) VALUES (?, ?, ?, ?)");
+
+$values = [
+ 'uid' => 6,
+ 'some_bool_1' => false,
+ 'some_bool_2' => true,
+ 'some_int' => -23
+];
+$st->bindParam(1, $values['uid'], PDO::PARAM_INT);
+$st->bindParam(2, $values['some_bool_1'], PDO::PARAM_BOOL);
+$st->bindParam(3, $values['some_bool_2'], PDO::PARAM_BOOL);
+$st->bindParam(4, $values['some_int'], PDO::PARAM_INT);
+
+$result = $st->execute();
+
+if ($result === false) {
+ var_dump($st->errorInfo());
+} else {
+ print("ok insert\n");
+}
+
+foreach ($db->query('SELECT * from test') as $row) {
+ print_r($row);
+}
+
+$st = $db->prepare("UPDATE test SET some_bool_1=?, some_bool_2=?, some_int=? WHERE uid=?");
+
+$values = [
+ 'uid' => 6,
+ 'some_bool_1' => (bool) 1,
+ 'some_bool_2' => (bool) 0,
+ 'some_int' => 1,
+];
+
+$st->bindParam(1, $values['some_bool_1'], PDO::PARAM_BOOL);
+$st->bindParam(2, $values['some_bool_2'], PDO::PARAM_BOOL);
+$st->bindParam(3, $values['some_int'], PDO::PARAM_INT);
+$st->bindParam(4, $values['uid'], PDO::PARAM_INT);
+
+$result = $st->execute();
+
+if ($result === false) {
+ var_dump($st->errorInfo());
+} else {
+ print("ok prepare 1\n");
+}
+
+foreach ($db->query('SELECT * from test') as $row) {
+ print_r($row);
+}
+
+$st = $db->prepare("UPDATE test SET some_bool_1=?, some_bool_2=?, some_int=? WHERE uid=?");
+
+$values = [
+ 'uid' => 6,
+ 'some_bool_1' => (bool) 0,
+ 'some_bool_2' => (bool) 1,
+ 'some_int' => 2,
+];
+
+$st->bindParam(1, $values['some_bool_1'], PDO::PARAM_BOOL);
+$st->bindParam(2, $values['some_bool_2'], PDO::PARAM_BOOL);
+$st->bindParam(3, $values['some_int'], PDO::PARAM_INT);
+$st->bindParam(4, $values['uid'], PDO::PARAM_INT);
+
+$result = $st->execute();
+
+if ($result === false) {
+ var_dump($st->errorInfo());
+} else {
+ print("ok prepare 2\n");
+}
+
+foreach ($db->query('SELECT * from test') as $row) {
+ print_r($row);
+}
+
+// String true and false should fail
+$st = $db->prepare("UPDATE test SET some_bool_1=?, some_bool_2=?, some_int=? WHERE uid=?");
+
+$values = [
+ 'uid' => 6,
+ 'some_bool_1' => 'true',
+ 'some_bool_2' => 'false',
+ 'some_int' => 3,
+];
+
+$st->bindParam(1, $values['some_bool_1'], PDO::PARAM_BOOL);
+$st->bindParam(2, $values['some_bool_2'], PDO::PARAM_BOOL);
+$st->bindParam(3, $values['some_int'], PDO::PARAM_INT);
+$st->bindParam(4, $values['uid'], PDO::PARAM_INT);
+
+$result = $st->execute();
+
+if ($result === false) {
+ var_dump($st->errorInfo());
+} else {
+ print("ok prepare 3\n");
+}
+
+foreach ($db->query('SELECT * from test') as $row) {
+ print_r($row);
+}
+
+// Null should not be treated as false
+$st = $db->prepare("UPDATE test SET some_bool_1=?, some_bool_2=?, some_int=? WHERE uid=?");
+
+$values = [
+ 'uid' => 6,
+ 'some_bool_1' => true,
+ 'some_bool_2' => null,
+ 'some_int' => 4,
+];
+
+$st->bindParam(1, $values['some_bool_1'], PDO::PARAM_BOOL);
+$st->bindParam(2, $values['some_bool_2'], PDO::PARAM_BOOL);
+$st->bindParam(3, $values['some_int'], PDO::PARAM_INT);
+$st->bindParam(4, $values['uid'], PDO::PARAM_INT);
+
+$result = $st->execute();
+
+if ($result === false) {
+ var_dump($st->errorInfo());
+} else {
+ print("ok prepare 4\n");
+}
+
+foreach ($db->query('SELECT * from test') as $row) {
+ print_r($row);
+}
+
+// Integers converted correctly
+$st = $db->prepare("UPDATE test SET some_bool_1=?, some_bool_2=?, some_int=? WHERE uid=?");
+
+$values = [
+ 'uid' => 6,
+ 'some_bool_1' => 256,
+ 'some_bool_2' => 0,
+ 'some_int' => 5,
+];
+
+$st->bindParam(1, $values['some_bool_1'], PDO::PARAM_BOOL);
+$st->bindParam(2, $values['some_bool_2'], PDO::PARAM_BOOL);
+$st->bindParam(3, $values['some_int'], PDO::PARAM_INT);
+$st->bindParam(4, $values['uid'], PDO::PARAM_INT);
+
+$result = $st->execute();
+
+if ($result === false) {
+ var_dump($st->errorInfo());
+} else {
+ print("ok prepare 5\n");
+}
+
+foreach ($db->query('SELECT * from test') as $row) {
+ print_r($row);
+}
+
+?>
+--CLEAN--
+<?php
+require dirname(__FILE__) . '/mysql_pdo_test.inc';
+MySQLPDOTest::dropTestTable();
+?>
+--EXPECTF--
+ok insert
+Array
+(
+ [uid] => 6
+ [0] => 6
+ [some_bool_1] => 0
+ [1] => 0
+ [some_bool_2] => 1
+ [2] => 1
+ [some_int] => -23
+ [3] => -23
+)
+ok prepare 1
+Array
+(
+ [uid] => 6
+ [0] => 6
+ [some_bool_1] => 1
+ [1] => 1
+ [some_bool_2] => 0
+ [2] => 0
+ [some_int] => 1
+ [3] => 1
+)
+ok prepare 2
+Array
+(
+ [uid] => 6
+ [0] => 6
+ [some_bool_1] => 0
+ [1] => 0
+ [some_bool_2] => 1
+ [2] => 1
+ [some_int] => 2
+ [3] => 2
+)
+
+Warning: PDOStatement::execute(): SQLSTATE[HY000]: General error: 1366 Incorrect integer value: 'true' for column 'some_bool_1' at row 1 in %s
+array(3) {
+ [0]=>
+ string(5) "HY000"
+ [1]=>
+ int(1366)
+ [2]=>
+ string(65) "Incorrect integer value: 'true' for column 'some_bool_1' at row 1"
+}
+Array
+(
+ [uid] => 6
+ [0] => 6
+ [some_bool_1] => 0
+ [1] => 0
+ [some_bool_2] => 1
+ [2] => 1
+ [some_int] => 2
+ [3] => 2
+)
+
+Warning: PDOStatement::execute(): SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'some_bool_2' cannot be null in %s
+array(3) {
+ [0]=>
+ string(5) "23000"
+ [1]=>
+ int(1048)
+ [2]=>
+ string(35) "Column 'some_bool_2' cannot be null"
+}
+Array
+(
+ [uid] => 6
+ [0] => 6
+ [some_bool_1] => 0
+ [1] => 0
+ [some_bool_2] => 1
+ [2] => 1
+ [some_int] => 2
+ [3] => 2
+)
+ok prepare 5
+Array
+(
+ [uid] => 6
+ [0] => 6
+ [some_bool_1] => 1
+ [1] => 1
+ [some_bool_2] => 0
+ [2] => 0
+ [some_int] => 5
+ [3] => 5
+)
\ No newline at end of file