ID:               48924
 User updated by:  mark dot kirkwood at catalyst dot net dot nz
 Reported By:      mark dot kirkwood at catalyst dot net dot nz
 Status:           Open
 Bug Type:         PDO related
 Operating System: Ubuntu x86 (32 bit)
 PHP Version:      5.2CVS-2009-07-14 (CVS)
 New Comment:

Re: my footnote for Mysql - actually it does *not* elicit a similar
error with strict mode on.Sorry, my confusion.


Previous Comments:
------------------------------------------------------------------------

[2009-07-14 23:23:05] mark dot kirkwood at catalyst dot net dot nz

Patch - merging the change from 6.0 to 5.2 (or 5.3 for that matter):
*** ext/pdo/pdo_stmt.c.orig 2009-07-14 18:07:23.000000000 +1200
--- ext/pdo/pdo_stmt.c  2009-07-15 11:20:58.000000000 +1200
***************
*** 327,339 ****
    }

    if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_STR &&
param->max_value_len <= 0 && ! ZVAL_IS_NULL(param->parameter)) {
!       if (Z_TYPE_P(param->parameter) == IS_DOUBLE) {
!           char *p;
!           int len = spprintf(&p, 0, "%F",
Z_DVAL_P(param->parameter));
!           ZVAL_STRINGL(param->parameter, p, len, 0);
!       } else {
!           convert_to_string(param->parameter);
!       }
    } else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_INT &&
Z_TYPE_P(param->parameter) == IS_BOOL) {
        convert_to_long(param->parameter);
    } else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_BOOL &&
Z_TYPE_P(param->parameter) == IS_LONG) {
--- 327,333 ----
    }

    if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_STR &&
param->max_value_len <= 0 && ! ZVAL_IS_NULL(param->parameter)) {
!       convert_to_string(param->parameter);
    } else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_INT &&
Z_TYPE_P(param->parameter) == IS_BOOL) {
        convert_to_long(param->parameter);
    } else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_BOOL &&
Z_TYPE_P(param->parameter) == IS_LONG) {

------------------------------------------------------------------------

[2009-07-14 23:19:11] mark dot kirkwood at catalyst dot net dot nz

Description:
------------
PDO performs conversions to string of various parameters. However for
an integer > PHP_INT_MAX PHP has already converted it to a float before
PDO sees it. This catches out Postgres [1] when inserting such a value
because the conversion leaves trailing .0000... on the value.

Now this issue seems to have been fixed in PHP 6.0. The actual fix
looks to be very simple (I'll attach a patch in a separate comment). The
affected file is: 

ext/pdo/pdo_stmt.c

function:
really_register_bound_param

I think we can just call convert_to_string without any special casing
for IS_DOUBLE, as convert_to_string handles them ok itself.

[1] but will catch Mysql too if have STRICT_ALL_TABLES or similar
enabled.

Reproduce code:
---------------
 /* table a has desc (id bigint) */
 $sql = "INSERT INTO a VALUES (?)";
 $stmt = $dbh->prepare($sql,array(PDO::ATTR_EMULATE_PREPARES =>
true));
 $id = PHP_INT_MAX + 1;
 var_dump($id);
 $stmt->execute(array($id));


Expected result:
----------------
integer 2147483648 inserted into the table 'a'. 

Actual result:
--------------
PDOException: SQLSTATE[22P02]: Invalid text representation: 7 ERROR: 
invalid input syntax for integer: "2147483648.000000"


------------------------------------------------------------------------


-- 
Edit this bug report at http://bugs.php.net/?id=48924&edit=1

Reply via email to