Bug #6609 SQL_ATTR_MAX_ROWS and leading spaces in query result in truncating end of query
Submitted: 14 Nov 2004 5:20 Modified: 13 Feb 2007 22:47
Reporter: marc slemko Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / ODBC Severity:S2 (Serious)
Version:3.51.09 OS:Linux (Linux)
Assigned to: Jim Winstead CPU Architecture:Any

[14 Nov 2004 5:20] marc slemko
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);
[13 Feb 2007 22:47] Jim Winstead
Fixed in the C/ODBC 3.51 repository, and will be fixed in the next release (probably 3.51.14).

Thanks for the bug report, and sorry that it has taken so long for the fix to be included.