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--EXPECT-- 92Array 93( 94 [0] => Array 95 ( 96 [foo] => false 97 ) 98 99) 100Array 101( 102 [0] => Array 103 ( 104 [foo] => true 105 ) 106 107) 108Array 109( 110 [0] => Array 111 ( 112 [foo] => true 113 ) 114 115) 116Array 117( 118 [0] => 22P02 119 [1] => 7 120 [2] => ERROR: invalid input syntax for type boolean: "" 121) 122EMUL 123Array 124( 125 [0] => Array 126 ( 127 [foo] => false 128 ) 129 130) 131Array 132( 133 [0] => Array 134 ( 135 [foo] => true 136 ) 137 138) 139Array 140( 141 [0] => Array 142 ( 143 [foo] => true 144 ) 145 146) 147Array 148( 149 [0] => 22P02 150 [1] => 7 151 [2] => ERROR: invalid input syntax for type boolean: "" 152) 153