]> granicus.if.org Git - php/commitdiff
Fix for bug #49357 (MySQLi extension fails to recognize POINT (spatial) colums).
authorUlf Wendel <uw@php.net>
Fri, 11 Sep 2009 13:38:47 +0000 (13:38 +0000)
committerUlf Wendel <uw@php.net>
Fri, 11 Sep 2009 13:38:47 +0000 (13:38 +0000)
Do yourself a favour and use mysqlnd. mysqlnd has no isuses here.

If you insist on using the MySQL Client Library (libmysql) I strongly recommend to use mysqli_stmt_store_result() when fetching geometry data using prepared statements. When streaming data, which is the default for prepared statements, ext/mysqli will have to make a guess on the size of the result buffer it needs. The guess is based on a length reported by the MySQL CLient Library (libmysql). The MySQL Client Library reports 4GB (!) for a POINT - a conservative and safe guess. Consequently, ext/mysqli will try to allocate 4GB of RAM. The true (maximum) size of the column is not available before buffering the result on the client using mysqli_stmt_store_result(). If you call mysqli_stmt_store_result(), the result buffers will not get bigger than needed. However, store_result()/buffering is usually not what you want when you ask for prepared statements.

ext/mysqli/mysqli_api.c
ext/mysqli/tests/mysqli_stmt_fetch_geom.phpt

index 7d367e670c05597a4c0682f8691083a976101aac..72301d3fa910a44b7a585bbbcabd2d4e385c0052 100644 (file)
@@ -370,6 +370,7 @@ mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval ***args, unsigned int argc,
                        case MYSQL_TYPE_LONG_BLOB:
                        case MYSQL_TYPE_TIMESTAMP:
                        case MYSQL_TYPE_DECIMAL:
+                       case MYSQL_TYPE_GEOMETRY:
 #ifdef FIELD_TYPE_NEWDECIMAL
                        case MYSQL_TYPE_NEWDECIMAL:
 #endif
@@ -2346,7 +2347,8 @@ PHP_FUNCTION(mysqli_stmt_store_result)
                for (i = mysql_stmt_field_count(stmt->stmt) - 1; i >=0; --i) {
                        if (stmt->stmt->fields && (stmt->stmt->fields[i].type == MYSQL_TYPE_BLOB ||
                                stmt->stmt->fields[i].type == MYSQL_TYPE_MEDIUM_BLOB ||
-                               stmt->stmt->fields[i].type == MYSQL_TYPE_LONG_BLOB))
+                               stmt->stmt->fields[i].type == MYSQL_TYPE_LONG_BLOB ||
+                               stmt->stmt->fields[i].type == MYSQL_TYPE_GEOMETRY))
                        {
                                my_bool tmp=1;
                                mysql_stmt_attr_set(stmt->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &tmp);
index 7d7ef79f30b910a16ceab7a71b7f630f2b583403..fc9cc64a7fc325627aeb7a3379530f8ed9cccc3b 100644 (file)
@@ -45,7 +45,7 @@ mysqli_stmt_fetch - geometry / spatial types
                        return false;
                }
 
-               if (!mysqli_stmt_execute($stmt)) {
+               if (!mysqli_stmt_execute($stmt) || !mysqli_stmt_store_result($stmt)) {
                        printf("[%04d] [%d] %s\n", $offset + 8, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
                        mysqli_stmt_close($stmt);
                        return false;
@@ -65,7 +65,7 @@ mysqli_stmt_fetch - geometry / spatial types
 
                $num = 0;
                $rows = array();
-               while (true === mysqli_stmt_fetch($stmt)) {
+               while (true === @mysqli_stmt_fetch($stmt)) {
                        $rows[] = array('id' => $id, 'label' => $bind_res);
                        $num++;
                }