1--TEST-- 2PDO PgSQL Bug #33876 (PDO misquotes/miscasts bool(false)) 3--SKIPIF-- 4<?php 5if (!extension_loaded('pdo') || !extension_loaded('pdo_pgsql')) 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__) . '/../../../ext/pdo/tests/pdo_test.inc'; 13$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt'); 14$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); 15 16$db->exec("SET LC_MESSAGES='C'"); 17$db->exec('CREATE TABLE test (foo varchar(5) NOT NULL, bar bool NOT NULL)'); 18$db->exec("INSERT INTO test VALUES('false','f')"); 19$db->exec("INSERT INTO test VALUES('true', 't')"); 20 21$res = $db->prepare('SELECT foo from test where bar = ?'); 22 23# this is the portable approach to binding a bool 24$res->bindValue(1, false, PDO::PARAM_BOOL); 25if (!$res->execute()) 26 print_r($res->errorInfo()); 27else 28 print_r($res->fetchAll(PDO::FETCH_ASSOC)); 29 30# this is the portable approach to binding a bool 31$res->bindValue(1, true, PDO::PARAM_BOOL); 32if (!$res->execute()) 33 print_r($res->errorInfo()); 34else 35 print_r($res->fetchAll(PDO::FETCH_ASSOC)); 36 37 38# true gets cast to string (because the implied default is string) 39# true-as-string is 1, so this "works" 40if (!$res->execute(array(true))) 41 print_r($res->errorInfo()); 42else 43 print_r($res->fetchAll(PDO::FETCH_ASSOC)); 44 45# Expected to fail; unless told otherwise, PDO assumes string inputs 46# false -> "" as string, which pgsql doesn't like 47if (!$res->execute(array(false))) 48 print_r($res->errorInfo()); 49else 50 print_r($res->fetchAll(PDO::FETCH_ASSOC)); 51 52# And now using emulator prepares 53echo "EMUL\n"; 54 55 56$res = $db->prepare('SELECT foo from test where bar = ?', array( 57 PDO::ATTR_EMULATE_PREPARES => true)); 58 59# this is the portable approach to binding a bool 60$res->bindValue(1, false, PDO::PARAM_BOOL); 61if (!$res->execute()) 62 print_r($res->errorInfo()); 63else 64 print_r($res->fetchAll(PDO::FETCH_ASSOC)); 65 66# this is the portable approach to binding a bool 67$res->bindValue(1, true, PDO::PARAM_BOOL); 68if (!$res->execute()) 69 print_r($res->errorInfo()); 70else 71 print_r($res->fetchAll(PDO::FETCH_ASSOC)); 72 73 74# true gets cast to string (because the implied default is string) 75# true-as-string is 1, so this "works" 76if (!$res->execute(array(true))) 77 print_r($res->errorInfo()); 78else 79 print_r($res->fetchAll(PDO::FETCH_ASSOC)); 80 81# Expected to fail; unless told otherwise, PDO assumes string inputs 82# false -> "" as string, which pgsql doesn't like 83if (!$res->execute(array(false))) { 84 $err = $res->errorInfo(); 85 // Strip additional lines outputted by recent PgSQL versions 86 $err[2] = trim(current(explode("\n", $err[2]))); 87 print_r($err); 88} else { 89 print_r($res->fetchAll(PDO::FETCH_ASSOC)); 90} 91 92 93 94--EXPECT-- 95Array 96( 97 [0] => Array 98 ( 99 [foo] => false 100 ) 101 102) 103Array 104( 105 [0] => Array 106 ( 107 [foo] => true 108 ) 109 110) 111Array 112( 113 [0] => Array 114 ( 115 [foo] => true 116 ) 117 118) 119Array 120( 121 [0] => 22P02 122 [1] => 7 123 [2] => ERROR: invalid input syntax for type boolean: "" 124) 125EMUL 126Array 127( 128 [0] => Array 129 ( 130 [foo] => false 131 ) 132 133) 134Array 135( 136 [0] => Array 137 ( 138 [foo] => true 139 ) 140 141) 142Array 143( 144 [0] => Array 145 ( 146 [foo] => true 147 ) 148 149) 150Array 151( 152 [0] => 22P02 153 [1] => 7 154 [2] => ERROR: invalid input syntax for type boolean: "" 155) 156