List:Commits« Previous MessageNext Message »
From:konstantin Date:June 22 2007 4:08pm
Subject:bk commit into 5.1 tree (kostja:1.2559)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of kostja. When kostja does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-06-22 20:08:42+04:00, kostja@bodhi.(none) +19 -0
  Technology preview: make the parser independent of the query cache.
  Never refer to non-preprocessed query after parsing.

  sql/ha_ndbcluster_binlog.cc@stripped, 2007-06-22 20:08:38+04:00, kostja@bodhi.(none) +2 -4
    Do not assign thd->query, it's done in mysql_parse.

  sql/item.cc@stripped, 2007-06-22 20:08:38+04:00, kostja@bodhi.(none) +1 -1
    Use size_t to avoid casts.

  sql/item.h@stripped, 2007-06-22 20:08:38+04:00, kostja@bodhi.(none) +2 -2
    Use size_t to avoid casts.

  sql/log_event.cc@stripped, 2007-06-22 20:08:38+04:00, kostja@bodhi.(none) +5 -11
    Do not assign thd->query, it's don in mysql_parse

  sql/mysql_priv.h@stripped, 2007-06-22 20:08:38+04:00, kostja@bodhi.(none) +6 -0
    Implement a utility function lex_string_set

  sql/slave.cc@stripped, 2007-06-22 20:08:38+04:00, kostja@bodhi.(none) +10 -21
    Do not assign thd->query, it's done in mysql_parse.

  sql/sp_head.cc@stripped, 2007-06-22 20:08:38+04:00, kostja@bodhi.(none) +48 -45
    Rewrite subst_spvars to not assign thd->query and not use alloc_query

  sql/sql_cache.cc@stripped, 2007-06-22 20:08:38+04:00, kostja@bodhi.(none) +1 -1
    const char * is better than char *.

  sql/sql_cache.h@stripped, 2007-06-22 20:08:39+04:00, kostja@bodhi.(none) +1 -1
    char * -> const char *

  sql/sql_class.h@stripped, 2007-06-22 20:08:39+04:00, kostja@bodhi.(none) +13 -4
    thd->query is now const char *
    implement THD::set_query

  sql/sql_db.cc@stripped, 2007-06-22 20:08:39+04:00, kostja@bodhi.(none) +1 -1
    thd->query is const char *

  sql/sql_insert.cc@stripped, 2007-06-22 20:08:39+04:00, kostja@bodhi.(none) +3 -3
    thd->query is const char *

  sql/sql_lex.cc@stripped, 2007-06-22 20:08:39+04:00, kostja@bodhi.(none) +25 -16
    Fix coding style. Rename Lex_input_stream::end_of_query to
    Lex_input_stream::end

  sql/sql_lex.h@stripped, 2007-06-22 20:08:39+04:00, kostja@bodhi.(none) +42 -26
    Coding style. Implement Lip::get_cpp_sql(), Lip::get_cpp_sql_length()

  sql/sql_parse.cc@stripped, 2007-06-22 20:08:39+04:00, kostja@bodhi.(none) +9 -83
    Ditch it.

  sql/sql_prepare.cc@stripped, 2007-06-22 20:08:39+04:00, kostja@bodhi.(none) +14 -26
    alloc_query is no more.

  sql/sql_yacc.yy@stripped, 2007-06-22 20:08:39+04:00, kostja@bodhi.(none) +2 -1
    Fix Item_param constructor to work with the cpp buffer.

  storage/innobase/include/trx0trx.h@stripped, 2007-06-22 20:08:39+04:00, kostja@bodhi.(none) +1 -1
    thd->query is const char *

  storage/myisam/ha_myisam.cc@stripped, 2007-06-22 20:08:39+04:00, kostja@bodhi.(none) +1 -1
    thd->query is const char *

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	kostja
# Host:	bodhi.(none)
# Root:	/opt/local/work/mysql-5.1-alloc_query-4-ditch-it

--- 1.221/storage/myisam/ha_myisam.cc	2007-05-24 15:11:20 +04:00
+++ 1.222/storage/myisam/ha_myisam.cc	2007-06-22 20:08:39 +04:00
@@ -1551,7 +1551,7 @@ bool ha_myisam::check_and_repair(THD *th
 {
   int error=0;
   int marked_crashed;
-  char *old_query;
+  const char *old_query;
   uint old_query_length;
   HA_CHECK_OPT check_opt;
   DBUG_ENTER("ha_myisam::check_and_repair");

--- 1.270/sql/item.cc	2007-06-05 19:31:40 +04:00
+++ 1.271/sql/item.cc	2007-06-22 20:08:38 +04:00
@@ -2348,7 +2348,7 @@ default_set_param_func(Item_param *param
 }
 
 
-Item_param::Item_param(unsigned pos_in_query_arg) :
+Item_param::Item_param(size_t pos_in_query_arg) :
   strict_type(FALSE),
   state(NO_VALUE),
   item_result_type(STRING_RESULT),

--- 1.246/sql/item.h	2007-06-12 01:57:12 +04:00
+++ 1.247/sql/item.h	2007-06-22 20:08:38 +04:00
@@ -1521,9 +1521,9 @@ public:
     Offset of placeholder inside statement text. Used to create
     no-placeholders version of this statement for the binary log.
   */
-  uint pos_in_query;
+  size_t pos_in_query;
 
-  Item_param(uint pos_in_query_arg);
+  Item_param(size_t pos_in_query_arg);
 
   enum Item_result result_type () const { return item_result_type; }
   enum Type type() const { return item_type; }

--- 1.281/sql/log_event.cc	2007-06-05 19:31:41 +04:00
+++ 1.282/sql/log_event.cc	2007-06-22 20:08:38 +04:00
@@ -1976,13 +1976,10 @@ int Query_log_event::do_apply_event(RELA
   if (rpl_filter->db_ok(thd->db))
   {
     thd->set_time((time_t)when);
-    thd->query_length= q_len_arg;
-    thd->query= (char*)query_arg;
     VOID(pthread_mutex_lock(&LOCK_thread_count));
     thd->query_id = next_query_id();
     VOID(pthread_mutex_unlock(&LOCK_thread_count));
     thd->variables.pseudo_thread_id= thread_id;		// for temp tables
-    DBUG_PRINT("query",("%s",thd->query));
 
     if (ignored_error_code((expected_error= error_code)) ||
 	!check_expected_error(thd,rli,expected_error))
@@ -2074,8 +2071,7 @@ int Query_log_event::do_apply_event(RELA
       
       /* Execute the query (note that we bypass dispatch_command()) */
       const char* found_semicolon= NULL;
-      mysql_parse(thd, thd->query, thd->query_length, &found_semicolon);
-
+      mysql_parse(thd, query_arg, q_len_arg, &found_semicolon);
     }
     else
     {
@@ -2086,7 +2082,7 @@ int Query_log_event::do_apply_event(RELA
         we exit gracefully; otherwise we warn about the bad error and tell DBA
         to check/fix it.
       */
-      if (mysql_test_parse_for_slave(thd, thd->query, thd->query_length))
+      if (mysql_test_parse_for_slave(thd, (char*) query_arg, q_len_arg))
         clear_all_errors(thd, const_cast<RELAY_LOG_INFO*>(rli)); /* Can ignore query */
       else
       {
@@ -2096,7 +2092,7 @@ Query partially completed on the master 
 and was aborted. There is a chance that your master is inconsistent at this \
 point. If you are sure that your master is ok, run this query manually on the \
 slave and then restart the slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; \
-START SLAVE; . Query: '%s'", expected_error, thd->query);
+START SLAVE; . Query: '%s'", expected_error, query_arg);
         thd->query_error= 1;
       }
       goto end;
@@ -3336,8 +3332,7 @@ int Load_log_event::do_apply_event(NET* 
       print_query(FALSE, load_data_query, &end, (char **)&thd->lex->fname_start,
                   (char **)&thd->lex->fname_end);
       *end= 0;
-      thd->query_length= end - load_data_query;
-      thd->query= load_data_query;
+      thd->set_query(load_data_query, end - load_data_query);
 
       if (sql_ex.opt_flags & REPLACE_FLAG)
       {
@@ -3446,8 +3441,7 @@ error:
   VOID(pthread_mutex_lock(&LOCK_thread_count));
   thd->catalog= 0;
   thd->set_db(NULL, 0);                   /* will free the current database */
-  thd->query= 0;
-  thd->query_length= 0;
+  thd->set_query(NULL, 0);
   VOID(pthread_mutex_unlock(&LOCK_thread_count));
   close_thread_tables(thd);
   if (thd->query_error)

--- 1.521/sql/mysql_priv.h	2007-06-16 17:52:46 +04:00
+++ 1.522/sql/mysql_priv.h	2007-06-22 20:08:38 +04:00
@@ -2155,6 +2155,12 @@ inline void lex_string_set(LEX_STRING *l
   lex_str->length= strlen(c_str);
 }
 
+inline void lex_string_set(LEX_STRING *lex_str, const char *str, size_t length)
+{
+  lex_str->str= (char *) str;
+  lex_str->length= length;
+}
+
 #endif /* MYSQL_SERVER */
 #endif /* MYSQL_CLIENT */
 

--- 1.309/sql/slave.cc	2007-05-31 18:45:16 +04:00
+++ 1.310/sql/slave.cc	2007-06-22 20:08:38 +04:00
@@ -915,7 +915,7 @@ static int create_table_from_dump(THD* t
                                   const char* table_name, bool overwrite)
 {
   ulong packet_len;
-  char *query, *save_db;
+  char *save_db;
   uint32 save_db_length;
   Vio* save_vio;
   HA_CHECK_OPT check_opt;
@@ -943,16 +943,6 @@ static int create_table_from_dump(THD* t
     DBUG_RETURN(1);
   }
   thd->command = COM_TABLE_DUMP;
-  thd->query_length= packet_len;
-  /* Note that we should not set thd->query until the area is initalized */
-  if (!(query = thd->strmake((char*) net->read_pos, packet_len)))
-  {
-    sql_print_error("create_table_from_dump: out of memory");
-    my_message(ER_GET_ERRNO, "Out of memory", MYF(0));
-    DBUG_RETURN(1);
-  }
-  thd->query= query;
-  thd->query_error = 0;
   thd->net.no_send_ok = 1;
 
   bzero((char*) &tables,sizeof(tables));
@@ -973,12 +963,10 @@ static int create_table_from_dump(THD* t
   // save old db in case we are creating in a different database
   save_db = thd->db;
   save_db_length= thd->db_length;
-  thd->db = (char*)db;
-  DBUG_ASSERT(thd->db != 0);
-  thd->db_length= strlen(thd->db);
-  mysql_parse(thd, thd->query, packet_len, &found_semicolon); // run create table
-  thd->db = save_db;            // leave things the way the were before
-  thd->db_length= save_db_length;
+  DBUG_ASSERT(db != 0);
+  thd->reset_db((char*) db, strlen(db));
+  mysql_parse(thd, (char*) net->read_pos, packet_len, &found_semicolon); // run create table
+  thd->reset_db(save_db, save_db_length);  // leave things the way the were before
   thd->options = save_options;
 
   if (thd->query_error)
@@ -2206,8 +2194,8 @@ err:
   sql_print_information("Slave I/O thread exiting, read up to log '%s', position %s",
                   IO_RPL_LOG_NAME, llstr(mi->master_log_pos,llbuff));
   VOID(pthread_mutex_lock(&LOCK_thread_count));
-  thd->query = thd->db = 0; // extra safety
-  thd->query_length= thd->db_length= 0;
+  thd->set_db(NULL, 0);
+  thd->set_query(NULL, 0);
   VOID(pthread_mutex_unlock(&LOCK_thread_count));
   if (mysql)
   {
@@ -2479,8 +2467,9 @@ the slave SQL thread with \"SLAVE START\
     should already have done these assignments (each event which sets these
     variables is supposed to set them to 0 before terminating)).
   */
-  thd->query= thd->db= thd->catalog= 0;
-  thd->query_length= thd->db_length= 0;
+  thd->catalog= NULL;
+  thd->set_db(NULL, 0);
+  thd->set_query(NULL, 0);
   VOID(pthread_mutex_unlock(&LOCK_thread_count));
   thd->proc_info = "Waiting for slave mutex on exit";
   pthread_mutex_lock(&rli->run_lock);

--- 1.114/sql/sql_cache.cc	2007-06-16 17:52:46 +04:00
+++ 1.115/sql/sql_cache.cc	2007-06-22 20:08:38 +04:00
@@ -990,7 +990,7 @@ end:
 */
 
 int
-Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
+Query_cache::send_result_to_client(THD *thd, const char *sql, uint query_length)
 {
   ulonglong engine_data;
   Query_cache_query *query;

--- 1.369/sql/sql_class.h	2007-06-16 17:52:46 +04:00
+++ 1.370/sql/sql_class.h	2007-06-22 20:08:39 +04:00
@@ -611,9 +611,11 @@ public:
   LEX_STRING name; /* name for named prepared statements */
   LEX *lex;                                     // parse tree descriptor
   /*
-    Points to the query associated with this statement. It's const, but
-    we need to declare it char * because all table handlers are written
-    in C and need to point to it.
+    Points to the query associated with this statement.
+    This is NULL when a statement has just been created.
+    It's reset to point to the query if parsing was successful.
+    Memory for the pointer is allocated in the statement mem_root.
+    When execution of a statement is done, it's reset to NULL.
 
     Note that (A) if we set query = NULL, we must at the same time set
     query_length = 0, and protect the whole operation with the
@@ -632,11 +634,18 @@ public:
     This printing is needed at least in SHOW PROCESSLIST and SHOW INNODB
     STATUS.
   */
-  char *query;
+  const char *query;
   uint32 query_length;                          // current query length
   Server_side_cursor *cursor;
 
 public:
+  void set_query(const char *query_arg, size_t query_length_arg)
+  {
+    /* Avoid races with SHOW PROCESSLIST */
+    query_length= 0;
+    query= (char*) query_arg;
+    query_length= query_length_arg;
+  }
 
   /* This constructor is called for backup statements */
   Statement() {}

--- 1.154/sql/sql_db.cc	2007-06-14 19:23:52 +04:00
+++ 1.155/sql/sql_db.cc	2007-06-22 20:08:39 +04:00
@@ -689,7 +689,7 @@ bool mysql_create_db(THD *thd, char *db,
   
   if (!silent)
   {
-    char *query;
+    const char *query;
     uint query_length;
 
     if (!thd->query)				// Only in replication

--- 1.274/sql/sql_insert.cc	2007-06-10 14:43:54 +04:00
+++ 1.275/sql/sql_insert.cc	2007-06-22 20:08:39 +04:00
@@ -559,7 +559,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
   Name_resolution_context *context;
   Name_resolution_context_state ctx_state;
 #ifndef EMBEDDED_LIBRARY
-  char *query= thd->query;
+  const char *query= thd->query;
   /*
     log_on is about delayed inserts only.
     By default, both logs are enabled (this won't cause problems if the server
@@ -786,7 +786,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
 #ifndef EMBEDDED_LIBRARY
     if (lock_type == TL_WRITE_DELAYED)
     {
-      LEX_STRING const st_query = { query, thd->query_length };
+      LEX_STRING const st_query = { (char*) query, thd->query_length };
       error=write_delayed(thd, table, duplic, st_query, ignore, log_on);
       query=0;
     }
@@ -1826,7 +1826,7 @@ bool delayed_get_table(THD *thd, TABLE_L
         goto end_create;
       }
       tmp->table_list= *table_list;			// Needed to open table
-      tmp->table_list.alias= tmp->table_list.table_name= tmp->thd.query;
+      tmp->table_list.alias= tmp->table_list.table_name= (char*) tmp->thd.query;
       tmp->lock();
       pthread_mutex_lock(&tmp->mutex);
       if ((error=pthread_create(&tmp->thd.real_id,&connection_attrib,

--- 1.248/sql/sql_lex.cc	2007-06-16 17:52:46 +04:00
+++ 1.249/sql/sql_lex.cc	2007-06-22 20:08:39 +04:00
@@ -111,7 +111,7 @@ st_parsing_options::reset()
 }
 
 Lex_input_stream::Lex_input_stream(THD *thd,
-                                   const char* buffer,
+                                   const char *buffer,
                                    unsigned int length)
 : m_thd(thd),
   yylineno(1),
@@ -120,10 +120,10 @@ Lex_input_stream::Lex_input_stream(THD *
   m_ptr(buffer),
   m_tok_start(NULL),
   m_tok_end(NULL),
-  m_end_of_query(buffer + length),
+  m_end(buffer + length),
   m_tok_start_prev(NULL),
   m_buf(buffer),
-  m_echo(true),
+  m_echo(TRUE),
   m_cpp_tok_start(NULL),
   m_cpp_tok_start_prev(NULL),
   m_cpp_tok_end(NULL),
@@ -133,7 +133,16 @@ Lex_input_stream::Lex_input_stream(THD *
   stmt_prepare_mode(FALSE),
   in_comment(NO_COMMENT)
 {
-  m_cpp_buf= (char*) thd->alloc(length + 1);
+
+  while (m_ptr < m_end && my_isspace(thd->charset(), *m_ptr))
+    m_ptr++;
+
+  while (m_ptr < m_end && (m_end[-1] == ';' ||
+                           my_isspace(thd->charset(), m_end[-1])))
+    m_end--;
+  *(char*)m_end= '\0';
+
+  m_cpp_buf= (char*) thd->alloc(m_end - m_ptr + 1);
   m_cpp_ptr= m_cpp_buf;
 }
 
@@ -365,7 +374,7 @@ static char *get_text(Lex_input_stream *
       if (use_mb(cs) &&
           (l = my_ismbchar(cs,
                            lip->get_ptr() -1,
-                           lip->get_end_of_query()))) {
+                           lip->get_end()))) {
         lip->skip_binary(l-1);
         continue;
       }
@@ -692,7 +701,7 @@ int MYSQLlex(void *arg, void *yythd)
         {
           int l = my_ismbchar(cs,
                               lip->get_ptr() -1,
-                              lip->get_end_of_query());
+                              lip->get_end());
           if (l == 0) {
             state = MY_LEX_CHAR;
             continue;
@@ -706,7 +715,7 @@ int MYSQLlex(void *arg, void *yythd)
             int l;
             if ((l = my_ismbchar(cs,
                                  lip->get_ptr() -1,
-                                 lip->get_end_of_query())) == 0)
+                                 lip->get_end())) == 0)
               break;
             lip->skip_binary(l-1);
           }
@@ -835,7 +844,7 @@ int MYSQLlex(void *arg, void *yythd)
             int l;
             if ((l = my_ismbchar(cs,
                                  lip->get_ptr() -1,
-                                 lip->get_end_of_query())) == 0)
+                                 lip->get_end())) == 0)
               break;
             lip->skip_binary(l-1);
           }
@@ -1017,7 +1026,7 @@ int MYSQLlex(void *arg, void *yythd)
       {
         lip->in_comment= DISCARD_COMMENT;
         /* Accept '/' '*' '!', but do not keep this marker. */
-        lip->set_echo(false);
+        lip->set_echo(FALSE);
         lip->yySkip();
         lip->yySkip();
         lip->yySkip();
@@ -1050,7 +1059,7 @@ int MYSQLlex(void *arg, void *yythd)
           if (version <= MYSQL_VERSION_ID)
           {
             /* Expand the content of the special comment as real code */
-            lip->set_echo(true);
+            lip->set_echo(TRUE);
             state=MY_LEX_START;
             break;
           }
@@ -1058,7 +1067,7 @@ int MYSQLlex(void *arg, void *yythd)
         else
         {
           state=MY_LEX_START;
-          lip->set_echo(true);
+          lip->set_echo(TRUE);
           break;
         }
       }
@@ -1078,7 +1087,7 @@ int MYSQLlex(void *arg, void *yythd)
       if (! lip->eof())
         lip->yySkip();                  // remove last '/'
       state = MY_LEX_START;             // Try again
-      lip->set_echo(true);
+      lip->set_echo(TRUE);
       break;
     case MY_LEX_END_LONG_COMMENT:
       if ((lip->in_comment != NO_COMMENT) && lip->yyPeek() == '/')
@@ -1089,7 +1098,7 @@ int MYSQLlex(void *arg, void *yythd)
         lip->set_echo(lip->in_comment == PRESERVE_COMMENT);
         lip->yySkipn(2);
         /* And start recording the tokens again */
-        lip->set_echo(true);
+        lip->set_echo(TRUE);
         lip->in_comment=NO_COMMENT;
         state=MY_LEX_START;
       }
@@ -1114,7 +1123,7 @@ int MYSQLlex(void *arg, void *yythd)
           lip->found_semicolon= lip->get_ptr();
           thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
           lip->next_state= MY_LEX_END;
-          lip->set_echo(true);
+          lip->set_echo(TRUE);
           return (END_OF_INPUT);
         }
         state= MY_LEX_CHAR;		// Return ';'
@@ -1126,9 +1135,9 @@ int MYSQLlex(void *arg, void *yythd)
       if (lip->eof())
       {
         lip->yyUnget();                 // Reject the last '\0'
-        lip->set_echo(false);
+        lip->set_echo(FALSE);
         lip->yySkip();
-        lip->set_echo(true);
+        lip->set_echo(TRUE);
         lip->next_state=MY_LEX_END;     // Mark for next loop
         return(END_OF_INPUT);
       }

--- 1.286/sql/sql_lex.h	2007-06-16 17:52:46 +04:00
+++ 1.287/sql/sql_lex.h	2007-06-22 20:08:39 +04:00
@@ -1196,7 +1196,7 @@ public:
   */
   bool eof()
   {
-    return (m_ptr >= m_end_of_query);
+    return (m_ptr >= m_end);
   }
 
   /**
@@ -1206,25 +1206,41 @@ public:
   */
   bool eof(int n)
   {
-    return ((m_ptr + n) >= m_end_of_query);
+    return ((m_ptr + n) >= m_end);
   }
 
   /** Get the raw query buffer. */
-  const char* get_buf()
+  const char *get_buf()
   {
     return m_buf;
   }
 
   /** Get the pre-processed query buffer. */
-  const char* get_cpp_buf()
+  const char *get_cpp_buf()
   {
     return m_cpp_buf;
   }
+  /**
+    Call this once after parsing is complete to get SQL text of the
+    statement without version comments (output of SQL preprocessor.
+    Returns a NUL-terminated string to be compatible with the rest of
+    the server code. 'cpp' is "comments pre-procesor".
+  */
+  const char *get_cpp_sql()
+  {
+    if (m_cpp_ptr)                              /* is 0 if out of memory */
+      *m_cpp_ptr= '\0';
+    return m_cpp_buf;
+  }
+  size_t get_cpp_sql_length() const
+  {
+    return m_cpp_ptr - m_cpp_buf;
+  }
 
   /** Get the end of the raw query buffer. */
-  const char* get_end_of_query()
+  const char *get_end()
   {
-    return m_end_of_query;
+    return m_end;
   }
 
   /** Mark the stream position as the start of a new token. */
@@ -1250,43 +1266,43 @@ public:
   }
 
   /** Get the token start position, in the raw buffer. */
-  const char* get_tok_start()
+  const char *get_tok_start()
   {
     return m_tok_start;
   }
 
   /** Get the token start position, in the pre-processed buffer. */
-  const char* get_cpp_tok_start()
+  const char *get_cpp_tok_start()
   {
     return m_cpp_tok_start;
   }
 
   /** Get the token end position, in the raw buffer. */
-  const char* get_tok_end()
+  const char *get_tok_end()
   {
     return m_tok_end;
   }
 
   /** Get the token end position, in the pre-processed buffer. */
-  const char* get_cpp_tok_end()
+  const char *get_cpp_tok_end()
   {
     return m_cpp_tok_end;
   }
 
   /** Get the previous token start position, in the raw buffer. */
-  const char* get_tok_start_prev()
+  const char *get_tok_start_prev()
   {
     return m_tok_start_prev;
   }
 
   /** Get the current stream pointer, in the raw buffer. */
-  const char* get_ptr()
+  const char *get_ptr()
   {
     return m_ptr;
   }
 
   /** Get the current stream pointer, in the pre-processed buffer. */
-  const char* get_cpp_ptr()
+  const char *get_cpp_ptr()
   {
     return m_cpp_ptr;
   }
@@ -1316,49 +1332,49 @@ public:
 
 private:
   /** Pointer to the current position in the raw input stream. */
-  const char* m_ptr;
+  const char *m_ptr;
 
   /** Starting position of the last token parsed, in the raw buffer. */
-  const char* m_tok_start;
+  const char *m_tok_start;
 
   /** Ending position of the previous token parsed, in the raw buffer. */
-  const char* m_tok_end;
+  const char *m_tok_end;
 
   /** End of the query text in the input stream, in the raw buffer. */
-  const char* m_end_of_query;
+  const char *m_end;
 
   /** Starting position of the previous token parsed, in the raw buffer. */
-  const char* m_tok_start_prev;
+  const char *m_tok_start_prev;
 
-  /** Begining of the query text in the input stream, in the raw buffer. */
-  const char* m_buf;
+  /** Beginning of the query text in the input stream, in the raw buffer. */
+  const char *m_buf;
 
   /** Echo the parsed stream to the pre-processed buffer. */
   bool m_echo;
 
   /** Pre-processed buffer. */
-  char* m_cpp_buf;
+  char *m_cpp_buf;
 
   /** Pointer to the current position in the pre-processed input stream. */
-  char* m_cpp_ptr;
+  char *m_cpp_ptr;
 
   /**
     Starting position of the last token parsed,
     in the pre-processed buffer.
   */
-  const char* m_cpp_tok_start;
+  const char *m_cpp_tok_start;
 
   /**
     Starting position of the previous token parsed,
     in the pre-procedded buffer.
   */
-  const char* m_cpp_tok_start_prev;
+  const char *m_cpp_tok_start_prev;
 
   /**
     Ending position of the previous token parsed,
     in the pre-processed buffer.
   */
-  const char* m_cpp_tok_end;
+  const char *m_cpp_tok_end;
 
 public:
 
@@ -1369,7 +1385,7 @@ public:
     Position of ';' in the stream, to delimit multiple queries.
     This delimiter is in the raw buffer.
   */
-  const char* found_semicolon;
+  const char *found_semicolon;
 
   /** SQL_MODE = IGNORE_SPACE. */
   bool ignore_space;

--- 1.682/sql/sql_parse.cc	2007-06-16 17:52:46 +04:00
+++ 1.683/sql/sql_parse.cc	2007-06-22 20:08:39 +04:00
@@ -362,28 +362,18 @@ pthread_handler_t handle_bootstrap(void 
     if (thd->is_fatal_error)
       break;                                    /* purecov: inspected */
 
-    while (length && (my_isspace(thd->charset(), buff[length-1]) ||
-                      buff[length-1] == ';'))
-      length--;
     buff[length]=0;
 
     /* Skip lines starting with delimiter */
     if (strncmp(buff, STRING_WITH_LEN("delimiter")) == 0)
       continue;
-
-    thd->query_length=length;
-    thd->query= (char*) thd->memdup_w_gap(buff, length+1, 
-                                          thd->db_length+1+
-                                          QUERY_CACHE_FLAGS_SIZE);
-    thd->query[length] = '\0';
-    DBUG_PRINT("query",("%-.4096s",thd->query));
     /*
       We don't need to obtain LOCK_thread_count here because in bootstrap
       mode we have only one thread.
     */
     thd->query_id=next_query_id();
     thd->set_time();
-    mysql_parse(thd, thd->query, length, & found_semicolon);
+    mysql_parse(thd, buff, length, &found_semicolon);
     close_thread_tables(thd);			// Free tables
 
     if (thd->is_fatal_error)
@@ -905,9 +895,7 @@ bool dispatch_command(enum enum_server_c
   }
   case COM_QUERY:
   {
-    if (alloc_query(thd, packet, packet_length))
-      break;					// fatal error is set
-    char *packet_end= thd->query + thd->query_length;
+    char *packet_end= packet + packet_length;
     /* 'b' stands for 'buffer' parameter', special for 'my_snprintf' */
     const char *format= "%.*b";
     const char* found_semicolon= NULL;
@@ -918,7 +906,7 @@ bool dispatch_command(enum enum_server_c
     if (!(specialflag & SPECIAL_NO_PRIOR))
       my_pthread_setprio(pthread_self(),QUERY_PRIOR);
 
-    mysql_parse(thd, thd->query, thd->query_length, & found_semicolon);
+    mysql_parse(thd, packet, packet_length, & found_semicolon);
 
     while (!thd->killed && found_semicolon && !thd->net.report_error)
     {
@@ -934,15 +922,7 @@ bool dispatch_command(enum enum_server_c
 
       log_slow_statement(thd);
 
-      /* Remove garbage at start of query */
-      while (my_isspace(thd->charset(), *next_packet) && length > 0)
-      {
-        next_packet++;
-        length--;
-      }
       VOID(pthread_mutex_lock(&LOCK_thread_count));
-      thd->query_length= length;
-      thd->query= next_packet;
       thd->query_id= next_query_id();
       thd->set_time(); /* Reset the query start time. */
       /* TODO: set thd->lex->sql_command to SQLCOM_END here */
@@ -1301,7 +1281,9 @@ bool dispatch_command(enum enum_server_c
   thd->query_length=0;
   thread_running--;
   VOID(pthread_mutex_unlock(&LOCK_thread_count));
-  thd->packet.shrink(thd->variables.net_buffer_length);	// Reclaim some memory
+  /* Reclaim some memory */
+  thd->packet.shrink(thd->variables.net_buffer_length);
+  thd->convert_buffer.shrink(thd->variables.net_buffer_length);
   free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
   DBUG_RETURN(error);
 }
@@ -1470,52 +1452,6 @@ int prepare_schema_table(THD *thd, LEX *
 }
 
 
-/*
-  Read query from packet and store in thd->query
-  Used in COM_QUERY and COM_STMT_PREPARE
-
-  DESCRIPTION
-    Sets the following THD variables:
-      query
-      query_length
-
-  RETURN VALUES
-    FALSE ok
-    TRUE  error;  In this case thd->fatal_error is set
-*/
-
-bool alloc_query(THD *thd, const char *packet, uint packet_length)
-{
-  /* Remove garbage at start and end of query */
-  while (packet_length > 0 && my_isspace(thd->charset(), packet[0]))
-  {
-    packet++;
-    packet_length--;
-  }
-  const char *pos= packet + packet_length;     // Point at end null
-  while (packet_length > 0 &&
-	 (pos[-1] == ';' || my_isspace(thd->charset() ,pos[-1])))
-  {
-    pos--;
-    packet_length--;
-  }
-  /* We must allocate some extra memory for query cache */
-  thd->query_length= 0;                        // Extra safety: Avoid races
-  if (!(thd->query= (char*) thd->memdup_w_gap((uchar*) (packet),
-					      packet_length,
-					      thd->db_length+ 1 +
-					      QUERY_CACHE_FLAGS_SIZE)))
-    return TRUE;
-  thd->query[packet_length]=0;
-  thd->query_length= packet_length;
-
-  /* Reclaim some memory */
-  thd->packet.shrink(thd->variables.net_buffer_length);
-  thd->convert_buffer.shrink(thd->variables.net_buffer_length);
-
-  return FALSE;
-}
-
 static void reset_one_shot_variables(THD *thd) 
 {
   thd->variables.character_set_client=
@@ -5373,19 +5309,6 @@ void mysql_parse(THD *thd, const char *i
       {
 	if (! thd->net.report_error)
 	{
-          /*
-            Binlog logs a string starting from thd->query and having length
-            thd->query_length; so we set thd->query_length correctly (to not
-            log several statements in one event, when we executed only first).
-            We set it to not see the ';' (otherwise it would get into binlog
-            and Query_log_event::print() would give ';;' output).
-            This also helps display only the current query in SHOW
-            PROCESSLIST.
-            Note that we don't need LOCK_thread_count to modify query_length.
-          */
-          if (*found_semicolon &&
-              (thd->query_length= (ulong)(*found_semicolon - thd->query)))
-            thd->query_length--;
           /* Actually execute the query */
 	  mysql_execute_command(thd);
 	  query_cache_end_of_result(thd);
@@ -7159,6 +7082,9 @@ bool parse_sql(THD *thd, Lex_input_strea
   thd->m_lip= lip;
 
   err_status= MYSQLparse(thd) != 0 || thd->is_fatal_error;
+
+  if (err_status == FALSE)
+    thd->set_query(lip->get_cpp_sql(), lip->get_cpp_sql_length());
 
   thd->m_lip= NULL;
 

--- 1.583/sql/sql_yacc.yy	2007-06-16 17:52:46 +04:00
+++ 1.584/sql/sql_yacc.yy	2007-06-22 20:08:39 +04:00
@@ -9336,7 +9336,8 @@ param_marker:
             my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
             MYSQL_YYABORT;
           }
-          item= new Item_param((uint) (lip->get_tok_start() - thd->query));
+          item= new Item_param(lip->get_cpp_tok_start() -
+                               lip->get_cpp_buf());
           if (!($$= item) || lex->param_list.push_back(item))
           {
             my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));

--- 1.57/storage/innobase/include/trx0trx.h	2007-04-15 20:45:11 +04:00
+++ 1.58/storage/innobase/include/trx0trx.h	2007-06-22 20:08:39 +04:00
@@ -458,7 +458,7 @@ struct trx_struct{
 					was taken */
 	void*		mysql_thd;	/* MySQL thread handle corresponding
 					to this trx, or NULL */
-	char**		mysql_query_str;/* pointer to the field in mysqld_thd
+	const char**	mysql_query_str;/* pointer to the field in mysqld_thd
 					which contains the pointer to the
 					current SQL query string */
 	const char*	mysql_log_file_name;

--- 1.39/sql/sql_cache.h	2007-06-16 13:29:21 +04:00
+++ 1.40/sql/sql_cache.h	2007-06-22 20:08:39 +04:00
@@ -399,7 +399,7 @@ protected:
     Check if the query is in the cache and if this is true send the
     data to client.
   */
-  int send_result_to_client(THD *thd, char *query, uint query_length);
+  int send_result_to_client(THD *thd, const char *query, uint query_length);
 
   /* Remove all queries that uses any of the listed following tables */
   void invalidate(THD* thd, TABLE_LIST *tables_used,

--- 1.280/sql/sp_head.cc	2007-06-16 11:33:42 +04:00
+++ 1.281/sql/sp_head.cc	2007-06-22 20:08:38 +04:00
@@ -806,32 +806,34 @@ int cmp_splocal_locations(Item_splocal *
 */
 
 
-/*
-  Replace thd->query{_length} with a string that one can write to the binlog.
- 
-  SYNOPSIS
-    subst_spvars()
-      thd        Current thread. 
-      instr      Instruction (we look for Item_splocal instances in
-                 instr->free_list)
-      query_str  Original query string
-     
-  DESCRIPTION
+/**
+  Save in subst_query with a string that one can write to the binlog.
 
+  @param[in,out]  thd        Current thread, used
+                             for memory allocation
+  @param[in]      instr      Instruction (we look for Item_splocal instances
+                             in instr->free_list)
+  @param[in]      query_str  Original query string
+  @param[out]     subst_query Resulting query
+     
   The binlog-suitable string is produced by replacing references to SP local 
   variables with NAME_CONST('sp_var_name', value) calls.
- 
-  RETURN
-    FALSE  on success
-           thd->query{_length} either has been appropriately replaced or there
-           is no need for replacements.
-    TRUE   out of memory error.
+
+  @retval FALSE  Success, subst_query either has been appropriately replaced
+                 or there is no need for replacements, and then subst_query
+                 is assigned from the original query.
+  @retval  TRUE   out of memory error.
 */
 
 static bool
-subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str)
+subst_spvars(THD *thd, sp_instr *instr,
+             const LEX_STRING *query_str,
+             LEX_STRING *subst_query)
 {
   DBUG_ENTER("subst_spvars");
+
+  *subst_query= *query_str;
+
   if (thd->prelocked_mode == NON_PRELOCKED && mysql_bin_log.is_open())
   {
     Dynamic_array<Item_splocal*> sp_vars_uses;
@@ -903,8 +905,8 @@ subst_spvars(THD *thd, sp_instr *instr, 
     if (!(pbuf= thd->strmake(qbuf.ptr(), qbuf.length())))
       DBUG_RETURN(TRUE);
 
-    thd->query= pbuf;
-    thd->query_length= qbuf.length();
+    subst_query->str= pbuf;
+    subst_query->length= qbuf.length();
   }
   DBUG_RETURN(FALSE);
 }
@@ -2531,7 +2533,6 @@ sp_lex_keeper::reset_lex_and_exec_core(T
   /* Update the state of the active arena. */
   thd->stmt_arena->state= Query_arena::EXECUTED;
 
-
   /*
     Unlike for PS we should not call Item's destructors for newly created
     items after execution of each instruction in stored routine. This is
@@ -2585,37 +2586,39 @@ int sp_instr::exec_core(THD *thd, uint *
 int
 sp_instr_stmt::execute(THD *thd, uint *nextp)
 {
-  char *query;
-  uint32 query_length;
+  LEX_STRING subst_query;
   int res;
   DBUG_ENTER("sp_instr_stmt::execute");
   DBUG_PRINT("info", ("command: %d", m_lex_keeper.sql_command()));
 
-  query= thd->query;
-  query_length= thd->query_length;
-  if (!(res= alloc_query(thd, m_query.str, m_query.length)) &&
-      !(res=subst_spvars(thd, this, &m_query)))
+  if ((res= subst_spvars(thd, this, &m_query, &subst_query)))
+    DBUG_RETURN(res);
+
+  if (unlikely((thd->options & OPTION_LOG_OFF)==0))
+    general_log_print(thd, COM_QUERY, "%s", thd->query);
+
+  if (query_cache_send_result_to_client(thd,
+                                        subst_query.str,
+                                        subst_query.length) <= 0)
   {
-    /*
-      (the order of query cache and subst_spvars calls is irrelevant because
-      queries with SP vars can't be cached)
-    */
-    if (unlikely((thd->options & OPTION_LOG_OFF)==0))
-      general_log_print(thd, COM_QUERY, "%s", thd->query);
+    LEX_STRING save_query;
 
-    if (query_cache_send_result_to_client(thd,
-					  thd->query, thd->query_length) <= 0)
-    {
-      res= m_lex_keeper.reset_lex_and_exec_core(thd, nextp, FALSE, this);
-      if (!res && unlikely(thd->enable_slow_log))
-        log_slow_statement(thd);
-      query_cache_end_of_result(thd);
-    }
-    else
-      *nextp= m_ip+1;
-    thd->query= query;
-    thd->query_length= query_length;
+    lex_string_set(&save_query, thd->query, thd->query_length);
+    thd->set_query(subst_query.str, subst_query.length);
+
+    res= m_lex_keeper.reset_lex_and_exec_core(thd, nextp, FALSE, this);
+
+    query_cache_end_of_result(thd);
+
+    if (!res && unlikely(thd->enable_slow_log))
+      log_slow_statement(thd);
+
+    /* Restore the old thd->query */
+    thd->set_query(save_query.str, save_query.length);
   }
+  else
+    *nextp= m_ip+1;
+
   DBUG_RETURN(res);
 }
 

--- 1.120/sql/ha_ndbcluster_binlog.cc	2007-05-31 18:45:16 +04:00
+++ 1.121/sql/ha_ndbcluster_binlog.cc	2007-06-22 20:08:38 +04:00
@@ -225,7 +225,7 @@ static void run_query(THD *thd, char *bu
                       my_bool print_error, my_bool disable_binlog)
 {
   ulong save_query_length= thd->query_length;
-  char *save_query= thd->query;
+  const char *save_query= thd->query;
   ulong save_thread_id= thd->variables.pseudo_thread_id;
   ulonglong save_thd_options= thd->options;
   DBUG_ASSERT(sizeof(save_thd_options) == sizeof(thd->options));
@@ -233,14 +233,12 @@ static void run_query(THD *thd, char *bu
   const char* found_semicolon= NULL;
 
   bzero((char*) &thd->net, sizeof(NET));
-  thd->query_length= end - buf;
-  thd->query= buf;
   thd->variables.pseudo_thread_id= thread_id;
   if (disable_binlog)
     thd->options&= ~OPTION_BIN_LOG;
     
   DBUG_PRINT("query", ("%s", thd->query));
-  mysql_parse(thd, thd->query, thd->query_length, &found_semicolon);
+  mysql_parse(thd, buf, end - buf, &found_semicolon);
 
   if (print_error && thd->query_error)
   {

--- 1.224/sql/sql_prepare.cc	2007-06-16 17:52:46 +04:00
+++ 1.225/sql/sql_prepare.cc	2007-06-22 20:08:39 +04:00
@@ -2826,7 +2826,7 @@ bool Prepared_statement::set_name(LEX_ST
     thd->mem_root contains unused memory allocated during validation.
 */
 
-bool Prepared_statement::prepare(const char *packet, uint packet_len)
+bool Prepared_statement::prepare(const char *packet, uint packet_length)
 {
   bool error;
   Statement stmt_backup;
@@ -2839,29 +2839,17 @@ bool Prepared_statement::prepare(const c
   */
   status_var_increment(thd->status_var.com_stmt_prepare);
 
-  /*
-    alloc_query() uses thd->memroot && thd->query, so we should call
-    both of backup_statement() and backup_query_arena() here.
-  */
   thd->set_n_backup_statement(this, &stmt_backup);
   thd->set_n_backup_active_arena(this, &stmt_backup);
 
-  if (alloc_query(thd, packet, packet_len))
-  {
-    thd->restore_backup_statement(this, &stmt_backup);
-    thd->restore_active_arena(this, &stmt_backup);
-    DBUG_RETURN(TRUE);
-  }
-
   old_stmt_arena= thd->stmt_arena;
   thd->stmt_arena= this;
 
-  Lex_input_stream lip(thd, thd->query, thd->query_length);
+  Lex_input_stream lip(thd, packet, packet_length);
   lip.stmt_prepare_mode= TRUE;
   lex_start(thd);
 
   error= parse_sql(thd, &lip) || init_param_array(this);
-
   /*
     While doing context analysis of the query (in check_prepared_statement)
     we allocate a lot of additional memory: for open tables, JOINs, derived
@@ -3005,20 +2993,20 @@ bool Prepared_statement::execute(String 
   */
 
   thd->set_n_backup_statement(this, &stmt_backup);
-  if (expanded_query->length() &&
-      alloc_query(thd, (char*) expanded_query->ptr(),
-                  expanded_query->length()))
+  if (expanded_query->length())
   {
-    my_error(ER_OUTOFMEMORY, 0, expanded_query->length());
-    goto error;
+    char *copy= (char*) thd->memdup(expanded_query->c_ptr_safe(),
+                                    expanded_query->length() + 1);
+    if (copy == NULL) /* Out of memory, error reported */
+      goto error;
+    thd->set_query(copy, expanded_query->length());
+    /*
+      Expanded query is needed for slow logging, so we want thd->query
+      to point at it even after we restore from backup. This is ok, as
+      expanded query was allocated in thd->mem_root.
+    */
+    stmt_backup.set_query(copy, expanded_query->length());
   }
-  /*
-    Expanded query is needed for slow logging, so we want thd->query
-    to point at it even after we restore from backup. This is ok, as
-    expanded query was allocated in thd->mem_root.
-  */
-  stmt_backup.query= thd->query;
-  stmt_backup.query_length= thd->query_length;
 
   /*
     At first execution of prepared statement we may perform logical
Thread
bk commit into 5.1 tree (kostja:1.2559)konstantin22 Jun