|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2009-07-14 23:19 UTC] 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" PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Mon Nov 17 23:00:01 2025 UTC |
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) {Are you using a 32bit os? If you turn on statement logging you should see an insert that looks like: INSERT INTO a VALUES('2147483648.000000')