ID: 33876 Updated by: [EMAIL PROTECTED] Reported By: php at sagi dot org -Status: Assigned +Status: Closed Bug Type: PDO related Operating System: Linux PHP Version: 5CVS-2005-07-27 (dev) Assigned To: wez New Comment:
This issue has been resolved on the tip of the 5.1 branch. There was a bug, but your script was still technically "wrong". By default, PDO treats all data as strings, so the bool was being cast to string, which proved to be incompatible with the bool that pgsql expected. You need to tell PDO when you're binding booleans (or any type that might be ambiguous to the driver); you can do this using either PDOStatement::bindParam() or PDOStatement::bindValue(): $res->bindValue(1, false, PDO_PARAM_BOOL); $res->execute(); You can view the test case for the bug here: http://viewcvs.php.net/viewcvs.cgi/php-src/ext/pdo_pgsql/tests/Attic/bug_33876.phpt?rev=1.1.2.1 Previous Comments: ------------------------------------------------------------------------ [2005-09-02 08:44:54] jam at zoidtechnologies dot com the problem boils down to this: php casts a boolean with value False to "". pgsql requires booleans to have either a "t" or "f" value, and doesn't know what to do about an empty string being used as a boolean value. unfortunately the sql standard to which pgsql attempts to adhere is not clear on this issue and in fact marks the boolean type as "optional". there are two possible fixes for this: (1) use a ternary operator in the php script-- when handling a boolean value, explicitly set the variable to be used in the query data to either 't' or 'f': $foo = $bar ? 't' : 'f'; (2) add a check into PDO such that when it is connected to a pgsql database and it is handling a boolean type, make sure that False is changed to 'f'. ------------------------------------------------------------------------ [2005-08-08 07:11:06] php dot net at sharpdreams dot com I "fixed" this by binding the parameters as integers: $bool = false; $st = $db->prepare( "insert into foo ( bar ) values ( :bar )" ); $st->bindParam( ":bar", $boo, PDO_PARAM_INT ); $st->execute(); Add the following to your pgsql: -- begin CREATE OR REPLACE FUNCTION int_to_bool(int4) RETURNS bool AS $BODY$ select case when $1 <> 0 then TRUE else FALSE end; $BODY$ LANGUAGE 'sql' VOLATILE; CREATE CAST (int4 AS bool) WITH FUNCTION int_to_bool(int4) AS ASSIGNMENT; -- end PDO converts true/false to 1/0 which pass into the cast function. Couldn't get an implicit ''::bool cast working. e.g., CREATE OR REPLACE FUNCTION text_to_bool(text) RETURNS bool AS $BODY$ select case when $1 <> '' then TRUE else FALSE end; $BODY$ LANGUAGE 'sql' VOLATILE; CREATE CAST (text AS bool) WITH FUNCTION text_to_bool(text) AS ASSIGNMENT; And then doing "select ''::bool;" didn't work. Doin "select ''::text::bool" did work, though, so you could factor that into your PDO statements, too: insert into foo(bar) values(:bar::text); which will call the above cast ('' -> text -> bool). ------------------------------------------------------------------------ [2005-07-27 17:15:10] php at sagi dot org For what it's worth, its seems like the pgsql _client_ library that my installation is compiled against is v7.4.7, even though the server is running v8.0. So I guess it never used native prepared statements and the workaround that you suggested had no affect - they're already disabled. ------------------------------------------------------------------------ [2005-07-27 16:40:54] php at sagi dot org Nope, still get the same exception and the same query is being executed according to the server log. Still using the same php5-200507261230 snapshot. The exact code: $res = $db->prepare( 'SELECT id,name,trial FROM shops WHERE trial = ?', array(PDO_PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT => true) ); $res->execute(array(false)); And the result: Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[22P02]: Invalid text representation: 7 ERROR: invalid input syntax for type boolean: ""' in /home/shopy/dev/tmp/test.php:12 Stack trace: #0 /home/shopy/dev/tmp/test.php(12): PDOStatement->execute(Array) #1 {main} thrown in /home/shopy/dev/tmp/test.php on line 12 ------------------------------------------------------------------------ [2005-07-27 16:25:22] [EMAIL PROTECTED] Try this as a workaround for now: $res = $db->prepare('SELECT ...', array( PDO_PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT => true )); You can blame the pretty poor native prepared statement API in pgsql for this one; it just doesn't tell PDO anything about the parameter types so it can't make an informed decision about how to treat the parameters. ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at http://bugs.php.net/33876 -- Edit this bug report at http://bugs.php.net/?id=33876&edit=1