Bug #22001 Prepared Statements unusable with unbuffered queries, mysql_stmt_refetch needed
| Submitted: | 4 Sep 2006 16:07 | ||
|---|---|---|---|
| Reporter: | Domas Mituzas | Email Updates: | |
| Status: | Verified | Impact on me: | |
| Category: | MySQL Server: Prepared statements | Severity: | S4 (Feature request) |
| Version: | 5.0, 5.1, etc | OS: | |
| Assigned to: | CPU Architecture: | Any |
[4 Sep 2006 16:07]
Domas Mituzas
[4 Sep 2006 16:51]
Andrey Hristov
I propose adding a function - mysql_stmt_refetch
===== libmysql.c 1.258 vs edited =====
--- 1.258/libmysql/libmysql.c 2006-09-04 18:49:29 +02:00
+++ edited/libmysql.c 2006-09-04 18:18:10 +02:00
@@ -4556,6 +4556,36 @@ int STDCALL mysql_stmt_fetch(MYSQL_STMT
}
else
{
+ stmt->last_row= row;
+ /* This is to know in mysql_stmt_fetch_column that data was fetched */
+ stmt->state= MYSQL_STMT_FETCH_DONE;
+ }
+ DBUG_RETURN(rc);
+}
+
+
+/*
+ Fetch and return row data to bound buffers, if any
+*/
+
+int STDCALL mysql_stmt_refetch(MYSQL_STMT *stmt)
+{
+ int rc;
+ uchar *row;
+ DBUG_ENTER("mysql_stmt_refetch");
+
+ if (!stmt->last_row)
+ DBUG_RETURN(0);
+
+ if (((rc= stmt_fetch_row(stmt, stmt->last_row)) &&
+ rc != MYSQL_DATA_TRUNCATED))
+ {
+ stmt->state= MYSQL_STMT_PREPARE_DONE; /* XXX: this is buggy */
+ stmt->read_row_func= (rc == MYSQL_NO_DATA) ?
+ stmt_read_row_no_data : stmt_read_row_no_result_set;
+ }
+ else
+ {
/* This is to know in mysql_stmt_fetch_column that data was fetched */
stmt->state= MYSQL_STMT_FETCH_DONE;
}
===== mysql.h 1.164 vs edited =====
--- 1.164/include/mysql.h 2006-09-04 18:50:11 +02:00
+++ edited/mysql.h 2006-09-04 15:54:58 +02:00
@@ -718,6 +718,7 @@ typedef struct st_mysql_stmt
metadata fields when doing mysql_stmt_store_result.
*/
my_bool update_max_length;
+ unsigned char *last_row;
} MYSQL_STMT;
enum enum_stmt_attr_type
@@ -780,6 +781,7 @@ int STDCALL mysql_stmt_prepare(MYSQL_STM
unsigned long length);
int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt);
int STDCALL mysql_stmt_fetch(MYSQL_STMT *stmt);
+int STDCALL mysql_stmt_refetch(MYSQL_STMT *stmt);
int STDCALL mysql_stmt_fetch_column(MYSQL_STMT *stmt, MYSQL_BIND *bind,
unsigned int column,
unsigned long offset);
[4 Sep 2006 16:54]
Andrey Hristov
After the call to mysql_stmt_fetch() which had failed with truncation error, the length of the column has been updated in the BIND structure. Hence, one can realloc the buffer and call mysql_stmt_refetch() like:
if (ret == MYSQL_DATA_TRUNCATED) {
for (i = 0; i < stmt->result.var_cnt; i++) {
if (stmt->stmt->bind[i].error && stmt->stmt->bind[i].buffer_length) {
stmt->result.buf[i].val= erealloc(stmt->result.buf[i].val, stmt->result.buf[i].buflen);
}
}
if (MYSQL_DATA_TRUNCATED == mysql_stmt_refetch(stmt->stmt)) {
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Serious extension error. Please contact the developers");
RETURN_FALSE;
}
}
Portions of this website are copyright © 2001, 2002 The PHP Group
Page generated in 0.051 sec. using MySQL 8.4.7-u6-cloud
Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the
respective copyright holders.
It is not reviewed in advance
by Oracle and does not necessarily represent the opinion of
Oracle or any other party.