Description:
If you set SQL_ATTR_MAX_ROWS (which sets stmt->stmt_options.max_rows) and have a statement with a leading space such as " select 1", then the ODBC driver ends up stripping characters from the end of the query, which then fails or returns wrong results since the last x characters are lopped off, where x is however many spaces were added at the front.
It is due to this code (see the XXX comments):
SQLRETURN do_query(STMT FAR *stmt,char *query)
{
int error= SQL_ERROR;
DBUG_ENTER("do_query");
if (!query)
DBUG_RETURN_STATUS(error); /* Probably error from insert_param */
if (stmt->stmt_options.max_rows && stmt->stmt_options.max_rows !=
(SQLINTEGER) ~0L)
{
/* Add limit to select statement */
char *pos,*tmp_buffer;
for (pos= query; isspace(*pos) ; pos++) ;
if (!myodbc_casecmp(pos,"select",6))
{
uint length= strlen(pos); // XXX NOTE: allocate space for string starting with pos
if ((tmp_buffer= my_malloc(length+30,MYF(0))))
{
memcpy(tmp_buffer,query,length); // XXX NOTE: copy starting from query
sprintf(tmp_buffer+length," limit %lu",stmt->stmt_options.max_rows);
if (query != stmt->query)
my_free((gptr) query,MYF(0));
query= tmp_buffer;
}
}
}
How to repeat:
see description
Suggested fix:
--- /home/marcs/dist/MyODBC-3.51.09.orig/driver/execute.c Thu Aug 12 09:02:42 2004
+++ /home/marcs/dist/MyODBC-3.51.09/driver/execute.c Sat Nov 13 21:14:22 2004
@@ -65,7 +65,8 @@
for (pos= query; isspace(*pos) ; pos++) ;
if (!myodbc_casecmp(pos,"select",6))
{
- uint length= strlen(pos);
+ uint length= strlen(query);
if ((tmp_buffer= my_malloc(length+30,MYF(0))))
{
memcpy(tmp_buffer,query,length);