1--TEST-- 2PDO MySQL Bug #38546 (bindParam incorrect processing of bool types) 3--SKIPIF-- 4<?php 5if (!extension_loaded('pdo') || !extension_loaded('pdo_mysql')) die('skip not loaded'); 6require dirname(__FILE__) . '/config.inc'; 7require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc'; 8PDOTest::skip(); 9?> 10--FILE-- 11<?php 12require dirname(__FILE__) . '/config.inc'; 13require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc'; 14$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt'); 15 16$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 17 18// To test error cases. 19$db->exec("SET sql_mode='STRICT_TRANS_TABLES'"); 20 21$db->exec("DROP TABLE IF EXISTS test"); 22 23$query = "CREATE TABLE test( 24 uid MEDIUMINT UNSIGNED NOT NULL, 25 some_bool_1 BOOL NOT NULL, 26 some_bool_2 BOOL NOT NULL, 27 some_int TINYINT NOT NULL 28 )"; 29$db->exec($query); 30 31$st = $db->prepare("INSERT INTO test (uid, some_bool_1, some_bool_2, some_int) VALUES (?, ?, ?, ?)"); 32 33$values = [ 34 'uid' => 6, 35 'some_bool_1' => false, 36 'some_bool_2' => true, 37 'some_int' => -23 38]; 39$st->bindParam(1, $values['uid'], PDO::PARAM_INT); 40$st->bindParam(2, $values['some_bool_1'], PDO::PARAM_BOOL); 41$st->bindParam(3, $values['some_bool_2'], PDO::PARAM_BOOL); 42$st->bindParam(4, $values['some_int'], PDO::PARAM_INT); 43 44$result = $st->execute(); 45 46if ($result === false) { 47 var_dump($st->errorInfo()); 48} else { 49 print("ok insert\n"); 50} 51 52foreach ($db->query('SELECT * from test') as $row) { 53 print_r($row); 54} 55 56$st = $db->prepare("UPDATE test SET some_bool_1=?, some_bool_2=?, some_int=? WHERE uid=?"); 57 58$values = [ 59 'uid' => 6, 60 'some_bool_1' => (bool) 1, 61 'some_bool_2' => (bool) 0, 62 'some_int' => 1, 63]; 64 65$st->bindParam(1, $values['some_bool_1'], PDO::PARAM_BOOL); 66$st->bindParam(2, $values['some_bool_2'], PDO::PARAM_BOOL); 67$st->bindParam(3, $values['some_int'], PDO::PARAM_INT); 68$st->bindParam(4, $values['uid'], PDO::PARAM_INT); 69 70$result = $st->execute(); 71 72if ($result === false) { 73 var_dump($st->errorInfo()); 74} else { 75 print("ok prepare 1\n"); 76} 77 78foreach ($db->query('SELECT * from test') as $row) { 79 print_r($row); 80} 81 82$st = $db->prepare("UPDATE test SET some_bool_1=?, some_bool_2=?, some_int=? WHERE uid=?"); 83 84$values = [ 85 'uid' => 6, 86 'some_bool_1' => (bool) 0, 87 'some_bool_2' => (bool) 1, 88 'some_int' => 2, 89]; 90 91$st->bindParam(1, $values['some_bool_1'], PDO::PARAM_BOOL); 92$st->bindParam(2, $values['some_bool_2'], PDO::PARAM_BOOL); 93$st->bindParam(3, $values['some_int'], PDO::PARAM_INT); 94$st->bindParam(4, $values['uid'], PDO::PARAM_INT); 95 96$result = $st->execute(); 97 98if ($result === false) { 99 var_dump($st->errorInfo()); 100} else { 101 print("ok prepare 2\n"); 102} 103 104foreach ($db->query('SELECT * from test') as $row) { 105 print_r($row); 106} 107 108// String true and false should fail 109$st = $db->prepare("UPDATE test SET some_bool_1=?, some_bool_2=?, some_int=? WHERE uid=?"); 110 111$values = [ 112 'uid' => 6, 113 'some_bool_1' => 'true', 114 'some_bool_2' => 'false', 115 'some_int' => 3, 116]; 117 118$st->bindParam(1, $values['some_bool_1'], PDO::PARAM_BOOL); 119$st->bindParam(2, $values['some_bool_2'], PDO::PARAM_BOOL); 120$st->bindParam(3, $values['some_int'], PDO::PARAM_INT); 121$st->bindParam(4, $values['uid'], PDO::PARAM_INT); 122 123$result = $st->execute(); 124 125if ($result === false) { 126 var_dump($st->errorInfo()); 127} else { 128 print("ok prepare 3\n"); 129} 130 131foreach ($db->query('SELECT * from test') as $row) { 132 print_r($row); 133} 134 135// Null should not be treated as false 136$st = $db->prepare("UPDATE test SET some_bool_1=?, some_bool_2=?, some_int=? WHERE uid=?"); 137 138$values = [ 139 'uid' => 6, 140 'some_bool_1' => true, 141 'some_bool_2' => null, 142 'some_int' => 4, 143]; 144 145$st->bindParam(1, $values['some_bool_1'], PDO::PARAM_BOOL); 146$st->bindParam(2, $values['some_bool_2'], PDO::PARAM_BOOL); 147$st->bindParam(3, $values['some_int'], PDO::PARAM_INT); 148$st->bindParam(4, $values['uid'], PDO::PARAM_INT); 149 150$result = $st->execute(); 151 152if ($result === false) { 153 var_dump($st->errorInfo()); 154} else { 155 print("ok prepare 4\n"); 156} 157 158foreach ($db->query('SELECT * from test') as $row) { 159 print_r($row); 160} 161 162// Integers converted correctly 163$st = $db->prepare("UPDATE test SET some_bool_1=?, some_bool_2=?, some_int=? WHERE uid=?"); 164 165$values = [ 166 'uid' => 6, 167 'some_bool_1' => 256, 168 'some_bool_2' => 0, 169 'some_int' => 5, 170]; 171 172$st->bindParam(1, $values['some_bool_1'], PDO::PARAM_BOOL); 173$st->bindParam(2, $values['some_bool_2'], PDO::PARAM_BOOL); 174$st->bindParam(3, $values['some_int'], PDO::PARAM_INT); 175$st->bindParam(4, $values['uid'], PDO::PARAM_INT); 176 177$result = $st->execute(); 178 179if ($result === false) { 180 var_dump($st->errorInfo()); 181} else { 182 print("ok prepare 5\n"); 183} 184 185foreach ($db->query('SELECT * from test') as $row) { 186 print_r($row); 187} 188 189?> 190--CLEAN-- 191<?php 192require dirname(__FILE__) . '/mysql_pdo_test.inc'; 193MySQLPDOTest::dropTestTable(); 194?> 195--EXPECTF-- 196ok insert 197Array 198( 199 [uid] => 6 200 [0] => 6 201 [some_bool_1] => 0 202 [1] => 0 203 [some_bool_2] => 1 204 [2] => 1 205 [some_int] => -23 206 [3] => -23 207) 208ok prepare 1 209Array 210( 211 [uid] => 6 212 [0] => 6 213 [some_bool_1] => 1 214 [1] => 1 215 [some_bool_2] => 0 216 [2] => 0 217 [some_int] => 1 218 [3] => 1 219) 220ok prepare 2 221Array 222( 223 [uid] => 6 224 [0] => 6 225 [some_bool_1] => 0 226 [1] => 0 227 [some_bool_2] => 1 228 [2] => 1 229 [some_int] => 2 230 [3] => 2 231) 232 233Warning: PDOStatement::execute(): SQLSTATE[%s]: %s: 1366 Incorrect integer value: 'true' for column %s at row 1 in %s 234array(3) { 235 [0]=> 236 string(5) "%s" 237 [1]=> 238 int(1366) 239 [2]=> 240 string(%d) "Incorrect integer value: 'true' for column %s at row 1" 241} 242Array 243( 244 [uid] => 6 245 [0] => 6 246 [some_bool_1] => 0 247 [1] => 0 248 [some_bool_2] => 1 249 [2] => 1 250 [some_int] => 2 251 [3] => 2 252) 253 254Warning: PDOStatement::execute(): SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'some_bool_2' cannot be null in %s 255array(3) { 256 [0]=> 257 string(5) "23000" 258 [1]=> 259 int(1048) 260 [2]=> 261 string(35) "Column 'some_bool_2' cannot be null" 262} 263Array 264( 265 [uid] => 6 266 [0] => 6 267 [some_bool_1] => 0 268 [1] => 0 269 [some_bool_2] => 1 270 [2] => 1 271 [some_int] => 2 272 [3] => 2 273) 274ok prepare 5 275Array 276( 277 [uid] => 6 278 [0] => 6 279 [some_bool_1] => 1 280 [1] => 1 281 [some_bool_2] => 0 282 [2] => 0 283 [some_int] => 5 284 [3] => 5 285) 286