List:Commits« Previous MessageNext Message »
From:Chad MILLER Date:April 25 2007 12:14pm
Subject:bk commit into 5.0 tree (cmiller:1.2438)
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of cmiller. When cmiller 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-04-25 08:14:46-04:00, cmiller@stripped +40 -0
  Merge zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community-formerge51
  into  zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-enterprise-formergecomm
  MERGE: 1.2392.104.27

  configure.in@stripped, 2007-04-25 08:14:43-04:00, cmiller@stripped +1 -3
    Manual merge, convert to default community-features off.
    MERGE: 1.416.1.21

  include/config-win.h@stripped, 2007-04-24 18:28:59-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.84.1.1

  myisam/mi_open.c@stripped, 2007-04-24 18:28:59-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.105.1.1

  mysql-test/r/func_in.result@stripped, 2007-04-24 18:28:59-04:00, cmiller@stripped +0 -5
    Auto merged
    MERGE: 1.33.1.1

  mysql-test/r/information_schema.result@stripped, 2007-04-24 18:28:59-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.117.1.4

  mysql-test/r/information_schema_db.result@stripped, 2007-04-24 18:28:59-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.9.1.2

  mysql-test/t/func_in.test@stripped, 2007-04-24 18:28:59-04:00, cmiller@stripped +0 -11
    Auto merged
    MERGE: 1.27.1.1

  ndb/src/ndbapi/DictCache.cpp@stripped, 2007-04-24 18:28:59-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.20.1.1

  sql/ha_archive.cc@stripped, 2007-04-24 18:28:59-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.83.2.1

  sql/ha_myisam.cc@stripped, 2007-04-24 18:28:59-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.175.2.1

  sql/ha_ndbcluster.cc@stripped, 2007-04-24 18:28:59-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.299.6.1

  sql/item_cmpfunc.cc@stripped, 2007-04-24 18:29:00-04:00, cmiller@stripped +0 -2
    Auto merged
    MERGE: 1.240.1.2

  sql/item_func.cc@stripped, 2007-04-24 18:29:00-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.327.2.1

  sql/lex.h@stripped, 2007-04-24 18:29:00-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.145.1.1

  sql/lock.cc@stripped, 2007-04-24 18:29:00-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.93.1.2

  sql/log_event.cc@stripped, 2007-04-24 18:29:00-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.228.1.1

  sql/mysql_priv.h@stripped, 2007-04-24 18:29:00-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.437.1.2

  sql/mysqld.cc@stripped, 2007-04-24 18:29:00-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.598.2.2

  sql/set_var.cc@stripped, 2007-04-25 08:14:43-04:00, cmiller@stripped +1 -3
    Manual merge.
    MERGE: 1.181.1.2

  sql/slave.cc@stripped, 2007-04-24 18:29:01-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.295.1.1

  sql/sp_head.cc@stripped, 2007-04-24 18:29:01-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.236.2.1

  sql/sql_base.cc@stripped, 2007-04-24 18:29:01-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.360.1.16

  sql/sql_cache.cc@stripped, 2007-04-24 18:29:01-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.97.1.2

  sql/sql_class.cc@stripped, 2007-04-24 18:29:01-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.256.1.13

  sql/sql_class.h@stripped, 2007-04-24 18:29:01-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.314.1.14

  sql/sql_delete.cc@stripped, 2007-04-24 18:29:01-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.188.1.9

  sql/sql_insert.cc@stripped, 2007-04-24 18:29:01-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.211.1.19

  sql/sql_lex.cc@stripped, 2007-04-24 18:29:01-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.217.1.1

  sql/sql_lex.h@stripped, 2007-04-24 18:29:02-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.241.1.1

  sql/sql_parse.cc@stripped, 2007-04-25 08:14:43-04:00, cmiller@stripped +7 -12
    Manual merge.
    MERGE: 1.593.1.24

  sql/sql_prepare.cc@stripped, 2007-04-24 18:29:02-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.196.1.2

  sql/sql_repl.cc@stripped, 2007-04-24 18:29:02-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.155.1.5

  sql/sql_select.cc@stripped, 2007-04-24 18:29:02-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.498.3.1

  sql/sql_show.cc@stripped, 2007-04-24 18:29:02-04:00, cmiller@stripped +0 -9
    Auto merged
    MERGE: 1.341.2.3

  sql/sql_table.cc@stripped, 2007-04-24 18:29:03-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.333.3.1

  sql/sql_update.cc@stripped, 2007-04-24 18:29:03-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.212.1.1

  sql/sql_view.cc@stripped, 2007-04-24 18:29:03-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.105.3.1

  sql/sql_yacc.yy@stripped, 2007-04-24 18:29:03-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.509.2.1

  sql/table.h@stripped, 2007-04-24 18:29:03-04:00, cmiller@stripped +0 -0
    Auto merged
    MERGE: 1.138.1.3

  support-files/mysql.spec.sh@stripped, 2007-04-25 08:14:44-04:00, cmiller@stripped +5 -5
    Manual merge.
    
    Disable the community-server advertisement for Enterprise.  Re-enable
    this later.
    MERGE: 1.169.1.1

# 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:	cmiller
# Host:	zippy.cornsilk.net
# Root:	/home/cmiller/work/mysql/mysql-5.0-enterprise-formergecomm/RESYNC

--- 1.426/configure.in	2007-04-24 18:11:51 -04:00
+++ 1.427/configure.in	2007-04-25 08:14:43 -04:00
@@ -7,9 +7,9 @@ AC_INIT(sql/mysqld.cc)
 AC_CANONICAL_SYSTEM
 # The Docs Makefile.am parses this line!
 # remember to also change ndb version below and update version.c in ndb
-AM_INIT_AUTOMAKE(mysql, 5.0.39)
+AM_INIT_AUTOMAKE(mysql, 5.0.42)
 AM_CONFIG_HEADER(config.h)
-is_this_community_tree=yes
+is_this_community_tree=no
 
 PROTOCOL_VERSION=10
 DOT_FRM_VERSION=6
@@ -24,14 +24,14 @@ NDB_SHARED_LIB_VERSION=$NDB_SHARED_LIB_M
 # ndb version
 NDB_VERSION_MAJOR=5
 NDB_VERSION_MINOR=0
-NDB_VERSION_BUILD=39
+NDB_VERSION_BUILD=42
 NDB_VERSION_STATUS=""
 
 # Set all version vars based on $VERSION. How do we do this more elegant ?
 # Remember that regexps needs to quote [ and ] since this is run through m4
 MYSQL_NO_DASH_VERSION=`echo $VERSION | sed -e "s|[[a-z]]*-.*$||"`
 MYSQL_BASE_VERSION=`echo $MYSQL_NO_DASH_VERSION | sed -e "s|\.[[^.]]*$||"`
-MYSQL_VERSION_ID=`echo $MYSQL_NO_DASH_VERSION. | sed -e 's/[[^0-9.]]//g; s/\./  /g; s/ \([[0-9]]\) / 0\\1 /g; s/ //g'`
+MYSQL_VERSION_ID=`echo $MYSQL_NO_DASH_VERSION | sed -e 's|[[^0-9.]].*$||;s|$|.|' | sed -e 's/[[^0-9.]]//g; s/\./  /g; s/ \([[0-9]]\) / 0\\1 /g; s/ //g'`
 
 # The port should be constant for a LONG time
 MYSQL_TCP_PORT_DEFAULT=3306
@@ -1640,9 +1640,9 @@ fi
 # dlopen, dlerror
 case "$with_mysqld_ldflags " in
 
-  *"-static "*)
+  *"-all-static "*)
     # No need to check for dlopen when mysqld is linked with
-    # -all-static or -static as it won't be able to load any functions.
+    # -all-static as it won't be able to load any functions.
     # NOTE! It would be better if it was possible to test if dlopen
     # can be used, but a good way to test it couldn't be found
 
@@ -2415,12 +2415,18 @@ AC_ARG_WITH(man,
     [with_man=yes]
 )
 
-if test "$with_man" = "yes"
+if test X"$with_man" = Xyes
 then
   man_dirs="man"
-  man1_files=`ls -1 $srcdir/man/*.1 | sed -e 's;^.*man/;;'`
+  if test X"$have_ndbcluster" = Xyes
+  then
+    man1_files=`ls $srcdir/man/*.1 | sed -e 's;^.*man/;;'`
+    man8_files=`ls $srcdir/man/*.8 | sed -e 's;^.*man/;;'`
+  else
+    man1_files=`ls $srcdir/man/*.1 | grep -v '/ndb' | sed -e 's;^.*man/;;'`
+    man8_files=`ls $srcdir/man/*.8 | grep -v '/ndb' | sed -e 's;^.*man/;;'`
+  fi
   man1_files=`echo $man1_files`
-  man8_files=`ls -1 $srcdir/man/*.8 | sed -e 's;^.*man/;;'`
   man8_files=`echo $man8_files`
 else
   man_dirs=""

--- 1.85/include/config-win.h	2007-03-28 17:00:25 -04:00
+++ 1.86/include/config-win.h	2007-04-24 18:28:59 -04:00
@@ -205,6 +205,9 @@ typedef uint rf_SetTimer;
 /* If LOAD DATA LOCAL INFILE should be enabled by default */
 #define ENABLED_LOCAL_INFILE 1
 
+/* If query profiling should be enabled by default */
+#define ENABLED_PROFILING 1
+
 /* Convert some simple functions to Posix */
 
 #define my_sigset(A,B) signal((A),(B))

--- 1.107/myisam/mi_open.c	2007-04-02 04:41:31 -04:00
+++ 1.108/myisam/mi_open.c	2007-04-24 18:28:59 -04:00
@@ -196,7 +196,7 @@ MI_INFO *mi_open(const char *name, int m
     if (len != MI_BASE_INFO_SIZE)
     {
       DBUG_PRINT("warning",("saved_base_info_length: %d  base_info_length: %d",
-			    len,MI_BASE_INFO_SIZE))
+			    len,MI_BASE_INFO_SIZE));
     }
     disk_pos= (char*) 
       my_n_base_info_read((uchar*) disk_cache + base_pos, &share->base);

--- 1.178/sql/ha_myisam.cc	2007-03-28 04:22:20 -04:00
+++ 1.179/sql/ha_myisam.cc	2007-04-24 18:28:59 -04:00
@@ -673,7 +673,7 @@ int ha_myisam::check(THD* thd, HA_CHECK_
   MYISAM_SHARE* share = file->s;
   const char *old_proc_info=thd->proc_info;
 
-  thd->proc_info="Checking table";
+  thd_proc_info(thd, "Checking table");
   myisamchk_init(&param);
   param.thd = thd;
   param.op_name =   "check";
@@ -747,7 +747,7 @@ int ha_myisam::check(THD* thd, HA_CHECK_
     file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
   }
 
-  thd->proc_info=old_proc_info;
+  thd_proc_info(thd, old_proc_info);
   return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK;
 }
 
@@ -1029,22 +1029,22 @@ int ha_myisam::repair(THD *thd, MI_CHECK
         char buf[40];
         /* TODO: respect myisam_repair_threads variable */
         my_snprintf(buf, 40, "Repair with %d threads", my_count_bits(key_map));
-        thd->proc_info=buf;
+        thd_proc_info(thd, buf);
         error = mi_repair_parallel(&param, file, fixed_name,
             param.testflag & T_QUICK);
-        thd->proc_info="Repair done"; // to reset proc_info, as
+        thd_proc_info(thd, "Repair done"); // to reset proc_info, as
                                       // it was pointing to local buffer
       }
       else
       {
-        thd->proc_info="Repair by sorting";
+        thd_proc_info(thd, "Repair by sorting");
         error = mi_repair_by_sort(&param, file, fixed_name,
             param.testflag & T_QUICK);
       }
     }
     else
     {
-      thd->proc_info="Repair with keycache";
+      thd_proc_info(thd, "Repair with keycache");
       param.testflag &= ~T_REP_BY_SORT;
       error=  mi_repair(&param, file, fixed_name,
 			param.testflag & T_QUICK);
@@ -1058,7 +1058,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK
 	(share->state.changed & STATE_NOT_SORTED_PAGES))
     {
       optimize_done=1;
-      thd->proc_info="Sorting index";
+      thd_proc_info(thd, "Sorting index");
       error=mi_sort_index(&param,file,fixed_name);
     }
     if (!statistics_done && (local_testflag & T_STATISTICS))
@@ -1066,14 +1066,14 @@ int ha_myisam::repair(THD *thd, MI_CHECK
       if (share->state.changed & STATE_NOT_ANALYZED)
       {
 	optimize_done=1;
-	thd->proc_info="Analyzing";
+	thd_proc_info(thd, "Analyzing");
 	error = chk_key(&param, file);
       }
       else
 	local_testflag&= ~T_STATISTICS;		// Don't update statistics
     }
   }
-  thd->proc_info="Saving state";
+  thd_proc_info(thd, "Saving state");
   if (!error)
   {
     if ((share->state.changed & STATE_CHANGED) || mi_is_crashed(file))
@@ -1111,7 +1111,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK
     file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
     update_state_info(&param, file, 0);
   }
-  thd->proc_info=old_proc_info;
+  thd_proc_info(thd, old_proc_info);
   if (!thd->locked_tables)
     mi_lock_database(file,F_UNLCK);
   DBUG_RETURN(error ? HA_ADMIN_FAILED :
@@ -1336,7 +1336,7 @@ int ha_myisam::enable_indexes(uint mode)
     THD *thd=current_thd;
     MI_CHECK param;
     const char *save_proc_info=thd->proc_info;
-    thd->proc_info="Creating index";
+    thd_proc_info(thd, "Creating index");
     myisamchk_init(&param);
     param.op_name= "recreating_index";
     param.testflag= (T_SILENT | T_REP_BY_SORT | T_QUICK |
@@ -1361,7 +1361,7 @@ int ha_myisam::enable_indexes(uint mode)
         thd->clear_error();
     }
     info(HA_STATUS_CONST);
-    thd->proc_info=save_proc_info;
+    thd_proc_info(thd, save_proc_info);
   }
   else
   {

--- 1.246/sql/item_cmpfunc.cc	2007-04-20 18:36:15 -04:00
+++ 1.247/sql/item_cmpfunc.cc	2007-04-24 18:29:00 -04:00
@@ -3375,7 +3375,7 @@ longlong Item_is_not_null_test::val_int(
   }
   if (args[0]->is_null())
   {
-    DBUG_PRINT("info", ("null"))
+    DBUG_PRINT("info", ("null"));
     owner->was_null|= 1;
     DBUG_RETURN(0);
   }

--- 1.333/sql/item_func.cc	2007-04-08 14:46:37 -04:00
+++ 1.334/sql/item_func.cc	2007-04-24 18:29:00 -04:00
@@ -3215,7 +3215,7 @@ void debug_sync_point(const char* lock_n
     Structure is now initialized.  Try to get the lock.
     Set up control struct to allow others to abort locks
   */
-  thd->proc_info="User lock";
+  thd_proc_info(thd, "User lock");
   thd->mysys_var->current_mutex= &LOCK_user_locks;
   thd->mysys_var->current_cond=  &ull->cond;
 
@@ -3240,7 +3240,7 @@ void debug_sync_point(const char* lock_n
   }
   pthread_mutex_unlock(&LOCK_user_locks);
   pthread_mutex_lock(&thd->mysys_var->mutex);
-  thd->proc_info=0;
+  thd_proc_info(thd, 0);
   thd->mysys_var->current_mutex= 0;
   thd->mysys_var->current_cond=  0;
   pthread_mutex_unlock(&thd->mysys_var->mutex);
@@ -3321,7 +3321,7 @@ longlong Item_func_get_lock::val_int()
     Structure is now initialized.  Try to get the lock.
     Set up control struct to allow others to abort locks.
   */
-  thd->proc_info="User lock";
+  thd_proc_info(thd, "User lock");
   thd->mysys_var->current_mutex= &LOCK_user_locks;
   thd->mysys_var->current_cond=  &ull->cond;
 
@@ -3359,7 +3359,7 @@ longlong Item_func_get_lock::val_int()
   pthread_mutex_unlock(&LOCK_user_locks);
 
   pthread_mutex_lock(&thd->mysys_var->mutex);
-  thd->proc_info=0;
+  thd_proc_info(thd, 0);
   thd->mysys_var->current_mutex= 0;
   thd->mysys_var->current_cond=  0;
   pthread_mutex_unlock(&thd->mysys_var->mutex);

--- 1.146/sql/lex.h	2007-01-03 18:24:20 -05:00
+++ 1.147/sql/lex.h	2007-04-24 18:29:00 -04:00
@@ -32,10 +32,10 @@ SYM_GROUP sym_group_rtree= {"RTree keys"
 #define SYM(A) SYM_OR_NULL(A),0,0,&sym_group_common
 #define F_SYM(A) SYM_OR_NULL(A)
 
-#define CREATE_FUNC(A) (void *)(SYM_OR_NULL(A)), &sym_group_common
+#define CREATE_FUNC(A) (void (*)())(SYM_OR_NULL(A)), &sym_group_common
 
 #ifdef HAVE_SPATIAL
-#define CREATE_FUNC_GEOM(A) (void *)(SYM_OR_NULL(A)), &sym_group_geom
+#define CREATE_FUNC_GEOM(A) (void (*)())(SYM_OR_NULL(A)), &sym_group_geom
 #else
 #define CREATE_FUNC_GEOM(A) 0, &sym_group_geom
 #endif

--- 1.95/sql/lock.cc	2007-04-03 09:05:19 -04:00
+++ 1.96/sql/lock.cc	2007-04-24 18:29:00 -04:00
@@ -544,7 +544,7 @@ TABLE_LIST *mysql_lock_have_duplicate(TH
     goto end;
 
   /* A temporary table does not have locks. */
-  if (table->s->tmp_table == TMP_TABLE)
+  if (table->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE)
     goto end;
 
   /* Get command lock or LOCK TABLES lock. Maybe empty for INSERT DELAYED. */
@@ -569,7 +569,7 @@ TABLE_LIST *mysql_lock_have_duplicate(TH
     if (haystack->placeholder())
       continue;
     table2= haystack->table;
-    if (table2->s->tmp_table == TMP_TABLE)
+    if (table2->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE)
       continue;
 
     /* All tables in list must be in lock. */
@@ -655,7 +655,7 @@ static MYSQL_LOCK *get_lock_data(THD *th
   *write_lock_used=0;
   for (i=tables=lock_count=0 ; i < count ; i++)
   {
-    if (table_ptr[i]->s->tmp_table != TMP_TABLE)
+    if (table_ptr[i]->s->tmp_table != NON_TRANSACTIONAL_TMP_TABLE)
     {
       tables+=table_ptr[i]->file->lock_count();
       lock_count++;
@@ -697,7 +697,7 @@ static MYSQL_LOCK *get_lock_data(THD *th
     TABLE *table;
     enum thr_lock_type lock_type;
 
-    if ((table=table_ptr[i])->s->tmp_table == TMP_TABLE)
+    if ((table=table_ptr[i])->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE)
       continue;
     lock_type= table->reginfo.lock_type;
     if (lock_type >= TL_WRITE_ALLOW_WRITE)

--- 1.231/sql/log_event.cc	2007-04-12 05:46:06 -04:00
+++ 1.232/sql/log_event.cc	2007-04-24 18:29:00 -04:00
@@ -4412,7 +4412,7 @@ int Create_file_log_event::exec_event(st
   bzero((char*)&file, sizeof(file));
   fname_buf= strmov(proc_info, "Making temp file ");
   ext= slave_load_file_stem(fname_buf, file_id, server_id, ".info");
-  thd->proc_info= proc_info;
+  thd_proc_info(thd, proc_info);
   my_delete(fname_buf, MYF(0)); // old copy may exist already
   if ((fd= my_create(fname_buf, CREATE_MODE,
 		     O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
@@ -4466,7 +4466,7 @@ err:
     end_io_cache(&file);
   if (fd >= 0)
     my_close(fd, MYF(0));
-  thd->proc_info= 0;
+  thd_proc_info(thd, 0);
   return error ? 1 : Log_event::exec_event(rli);
 }
 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
@@ -4586,7 +4586,7 @@ int Append_block_log_event::exec_event(s
 
   fname= strmov(proc_info, "Making temp file ");
   slave_load_file_stem(fname, file_id, server_id, ".data");
-  thd->proc_info= proc_info;
+  thd_proc_info(thd, proc_info);
   if (get_create_or_append())
   {
     my_delete(fname, MYF(0)); // old copy may exist already
@@ -4620,7 +4620,7 @@ int Append_block_log_event::exec_event(s
 err:
   if (fd >= 0)
     my_close(fd, MYF(0));
-  thd->proc_info= 0;
+  thd_proc_info(thd, 0);
   DBUG_RETURN(error ? error : Log_event::exec_event(rli));
 }
 #endif

--- 1.445/sql/mysql_priv.h	2007-04-20 04:35:21 -04:00
+++ 1.446/sql/mysql_priv.h	2007-04-24 18:29:00 -04:00
@@ -196,6 +196,8 @@ MY_LOCALE *my_locale_by_number(uint numb
 #define BDB_LOG_ALLOC_BLOCK_SIZE	1024
 #define WARN_ALLOC_BLOCK_SIZE		2048
 #define WARN_ALLOC_PREALLOC_SIZE	1024
+#define PROFILE_ALLOC_BLOCK_SIZE  2048
+#define PROFILE_ALLOC_PREALLOC_SIZE 1024
 
 /*
   The following parameters is to decide when to use an extra cache to
@@ -365,6 +367,8 @@ MY_LOCALE *my_locale_by_number(uint numb
   fulltext functions when reading from it.
 */
 #define TMP_TABLE_FORCE_MYISAM          (ULL(1) << 32)
+#define OPTION_PROFILING                (ULL(1) << 33)
+
 
 
 /*
@@ -567,6 +571,8 @@ typedef my_bool (*qc_engine_callback)(TH
 #include "field.h"				/* Field definitions */
 #include "protocol.h"
 #include "sql_udf.h"
+#include "sql_profile.h"
+
 class user_var_entry;
 class Security_context;
 enum enum_var_type
@@ -1241,7 +1247,7 @@ void my_dbopt_free(void);
   External variables
 */
 
-extern time_t server_start_time;
+extern time_t server_start_time, flush_status_time;
 extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH],
 	    mysql_real_data_home[], *opt_mysql_tmpdir, mysql_charsets_dir[],
             def_ft_boolean_syntax[sizeof(ft_boolean_syntax)];

--- 1.605/sql/mysqld.cc	2007-04-20 04:35:21 -04:00
+++ 1.606/sql/mysqld.cc	2007-04-24 18:29:00 -04:00
@@ -436,7 +436,7 @@ ulong rpl_recovery_rank=0;
 
 double log_10[32];			/* 10 potences */
 double log_01[32];
-time_t server_start_time;
+time_t server_start_time, flush_status_time;
 
 char mysql_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30];
 char *default_tz_name;
@@ -1670,7 +1670,7 @@ void end_thread(THD *thd, bool put_in_ca
       ! abort_loop && !kill_cached_threads)
   {
     /* Don't kill the thread, just put it in cache for reuse */
-    DBUG_PRINT("info", ("Adding thread to cache"))
+    DBUG_PRINT("info", ("Adding thread to cache"));
     cached_thread_count++;
     while (!abort_loop && ! wake_thread && ! kill_cached_threads)
       (void) pthread_cond_wait(&COND_thread_cache, &LOCK_thread_count);
@@ -2636,7 +2636,7 @@ static int init_common_variables(const c
   tzset();			// Set tzname
 
   max_system_variables.pseudo_thread_id= (ulong)~0;
-  server_start_time= time((time_t*) 0);
+  server_start_time= flush_status_time= time((time_t*) 0);
   if (init_thread_environment())
     return 1;
   mysql_init_variables();
@@ -4783,6 +4783,7 @@ enum options_mysqld
   OPT_TABLE_LOCK_WAIT_TIMEOUT,
   OPT_PORT_OPEN_TIMEOUT,
   OPT_MERGE,
+  OPT_PROFILING,
   OPT_INNODB_ROLLBACK_ON_TIMEOUT,
   OPT_SECURE_FILE_PRIV
 };
@@ -5361,6 +5362,12 @@ Disable with --skip-ndbcluster (will sav
    "Maximum time in seconds to wait for the port to become free. "
    "(Default: no wait)", (gptr*) &mysqld_port_timeout,
    (gptr*) &mysqld_port_timeout, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+  {"profiling_history_size", OPT_PROFILING, "Limit of query profiling memory",
+   (gptr*) &global_system_variables.profiling_history_size,
+   (gptr*) &max_system_variables.profiling_history_size,
+   0, GET_ULONG, REQUIRED_ARG, 15, 0, 100, 0, 0, 0},
+#endif
   {"relay-log", OPT_RELAY_LOG,
    "The location and name to use for relay logs.",
    (gptr*) &opt_relay_logname, (gptr*) &opt_relay_logname, 0,
@@ -6387,6 +6394,7 @@ struct show_var_st status_vars[]= {
   {"Threads_created",	       (char*) &thread_created,		SHOW_LONG_CONST},
   {"Threads_running",          (char*) &thread_running,         SHOW_INT_CONST},
   {"Uptime",                   (char*) 0,                       SHOW_STARTTIME},
+  {"Uptime_since_flush_status",(char*) 0,                       SHOW_FLUSHTIME},
   {NullS, NullS, SHOW_LONG}
 };
 
@@ -7693,6 +7701,9 @@ void refresh_status(THD *thd)
 
   /* Reset the counters of all key caches (default and named). */
   process_key_caches(reset_key_cache_counters);
+#ifdef COMMUNITY_SERVER
+  flush_status_time= time((time_t*) 0);
+#endif
   pthread_mutex_unlock(&LOCK_status);
 
   /*

--- 1.298/sql/slave.cc	2007-04-20 04:35:22 -04:00
+++ 1.299/sql/slave.cc	2007-04-24 18:29:01 -04:00
@@ -1560,8 +1560,8 @@ static int create_table_from_dump(THD* t
 
   /* Create the table. We do not want to log the "create table" statement */
   save_options = thd->options;
-  thd->options &= ~(ulong) (OPTION_BIN_LOG);
-  thd->proc_info = "Creating table from master dump";
+  thd->options &= ~ (OPTION_BIN_LOG);
+  thd_proc_info(thd, "Creating table from master dump");
   // save old db in case we are creating in a different database
   save_db = thd->db;
   save_db_length= thd->db_length;
@@ -1575,7 +1575,7 @@ static int create_table_from_dump(THD* t
   if (thd->query_error)
     goto err;			// mysql_parse took care of the error send
 
-  thd->proc_info = "Opening master dump table";
+  thd_proc_info(thd, "Opening master dump table");
   tables.lock_type = TL_WRITE;
   if (!open_ltable(thd, &tables, TL_WRITE))
   {
@@ -1584,7 +1584,7 @@ static int create_table_from_dump(THD* t
   }
   
   file = tables.table->file;
-  thd->proc_info = "Reading master dump table data";
+  thd_proc_info(thd, "Reading master dump table data");
   /* Copy the data file */
   if (file->net_read_dump(net))
   {
@@ -1596,7 +1596,7 @@ static int create_table_from_dump(THD* t
 
   check_opt.init();
   check_opt.flags|= T_VERY_SILENT | T_CALC_CHECKSUM | T_QUICK;
-  thd->proc_info = "Rebuilding the index on master dump table";
+  thd_proc_info(thd, "Rebuilding the index on master dump table");
   /*
     We do not want repair() to spam us with messages
     just send them to the error log, and report the failure in case of
@@ -2926,9 +2926,9 @@ static int init_slave_thread(THD* thd, S
 #endif
 
   if (thd_type == SLAVE_THD_SQL)
-    thd->proc_info= "Waiting for the next event in relay log";
+    thd_proc_info(thd, "Waiting for the next event in relay log");
   else
-    thd->proc_info= "Waiting for master update";
+    thd_proc_info(thd, "Waiting for master update");
   thd->version=refresh_version;
   thd->set_time();
   DBUG_RETURN(0);
@@ -3489,7 +3489,7 @@ slave_begin:
     goto err;
   }
 
-  thd->proc_info = "Connecting to master";
+  thd_proc_info(thd, "Connecting to master");
   // we can get killed during safe_connect
   if (!safe_connect(thd, mysql, mi))
   {
@@ -3516,7 +3516,7 @@ connected:
   // TODO: the assignment below should be under mutex (5.0)
   mi->slave_running= MYSQL_SLAVE_RUN_CONNECT;
   thd->slave_net = &mysql->net;
-  thd->proc_info = "Checking master version";
+  thd_proc_info(thd, "Checking master version");
   if (get_master_version_and_clock(mysql, mi))
     goto err;
 
@@ -3527,7 +3527,7 @@ connected:
       If fails, this is not fatal - we just print the error message and go
       on with life.
     */
-    thd->proc_info = "Registering slave on master";
+    thd_proc_info(thd, "Registering slave on master");
     if (register_slave_on_master(mysql) ||  update_slave_list(mysql, mi))
       goto err;
   }
@@ -3536,7 +3536,7 @@ connected:
   while (!io_slave_killed(thd,mi))
   {
     bool suppress_warnings= 0;
-    thd->proc_info = "Requesting binlog dump";
+    thd_proc_info(thd, "Requesting binlog dump");
     if (request_dump(mysql, mi, &suppress_warnings))
     {
       sql_print_error("Failed on request_dump()");
@@ -3548,7 +3548,7 @@ dump");
       }
 
       mi->slave_running= MYSQL_SLAVE_RUN_NOT_CONNECT;
-      thd->proc_info= "Waiting to reconnect after a failed binlog dump request";
+      thd_proc_info(thd, "Waiting to reconnect after a failed binlog dump request");
 #ifdef SIGNAL_WITH_VIO_CLOSE
       thd->clear_active_vio();
 #endif
@@ -3572,7 +3572,7 @@ dump");
 	goto err;
       }
 
-      thd->proc_info = "Reconnecting after a failed binlog dump request";
+      thd_proc_info(thd, "Reconnecting after a failed binlog dump request");
       if (!suppress_warnings)
 	sql_print_error("Slave I/O thread: failed dump request, \
 reconnecting to try again, log '%s' at postion %s", IO_RPL_LOG_NAME,
@@ -3599,7 +3599,7 @@ after reconnect");
          important thing is to not confuse users by saying "reading" whereas
          we're in fact receiving nothing.
       */
-      thd->proc_info= "Waiting for master to send event";
+      thd_proc_info(thd, "Waiting for master to send event");
       event_len= read_event(mysql, mi, &suppress_warnings);
       if (io_slave_killed(thd,mi))
       {
@@ -3627,7 +3627,7 @@ max_allowed_packet",
 	  goto err;
 	}
         mi->slave_running= MYSQL_SLAVE_RUN_NOT_CONNECT;
-	thd->proc_info = "Waiting to reconnect after a failed master event read";
+	thd_proc_info(thd, "Waiting to reconnect after a failed master event read");
 #ifdef SIGNAL_WITH_VIO_CLOSE
         thd->clear_active_vio();
 #endif
@@ -3646,7 +3646,7 @@ max_allowed_packet",
 reconnect after a failed read");
 	  goto err;
 	}
-	thd->proc_info = "Reconnecting after a failed master event read";
+	thd_proc_info(thd, "Reconnecting after a failed master event read");
 	if (!suppress_warnings)
 	  sql_print_information("Slave I/O thread: Failed reading log event, \
 reconnecting to retry, log '%s' position %s", IO_RPL_LOG_NAME,
@@ -3663,7 +3663,7 @@ reconnect done to recover from failed re
       } // if (event_len == packet_error)
 
       retry_count=0;			// ok event, reset retry counter
-      thd->proc_info = "Queueing master event to the relay log";
+      thd_proc_info(thd, "Queueing master event to the relay log");
       if (queue_event(mi,(const char*)mysql->net.read_pos + 1,
 		      event_len))
       {
@@ -3745,7 +3745,7 @@ err:
     mi->mysql=0;
   }
   write_ignored_events_info_to_relay_log(thd, mi);
-  thd->proc_info = "Waiting for slave mutex on exit";
+  thd_proc_info(thd, "Waiting for slave mutex on exit");
   pthread_mutex_lock(&mi->run_lock);
 
   /* Forget the relay log's format */
@@ -3922,7 +3922,7 @@ Slave SQL thread aborted. Can't execute 
 
   while (!sql_slave_killed(thd,rli))
   {
-    thd->proc_info = "Reading event from the relay log";
+    thd_proc_info(thd, "Reading event from the relay log");
     DBUG_ASSERT(rli->sql_thd == thd);
     THD_CHECK_SENTRY(thd);
     if (exec_relay_log_event(thd,rli))
@@ -3954,7 +3954,7 @@ the slave SQL thread with \"SLAVE START\
   thd->query= 0; 
   thd->query_length= 0;
   VOID(pthread_mutex_unlock(&LOCK_thread_count));
-  thd->proc_info = "Waiting for slave mutex on exit";
+  thd_proc_info(thd, "Waiting for slave mutex on exit");
   pthread_mutex_lock(&rli->run_lock);
   /* We need data_lock, at least to wake up any waiting master_pos_wait() */
   pthread_mutex_lock(&rli->data_lock);

--- 1.365/sql/sql_base.cc	2007-04-03 09:05:20 -04:00
+++ 1.366/sql/sql_base.cc	2007-04-24 18:29:01 -04:00
@@ -1640,6 +1640,9 @@ TABLE *open_table(THD *thd, TABLE_LIST *
   table->used_keys= table->s->keys_for_keyread;
   table->fulltext_searched= 0;
   table->file->ft_handler= 0;
+  /* Catch wrong handling of the auto_increment_field_not_null. */
+  DBUG_ASSERT(!table->auto_increment_field_not_null);
+  table->auto_increment_field_not_null= FALSE;
   if (table->timestamp_field)
     table->timestamp_field_type= table->timestamp_field->get_auto_set_type();
   table->pos_in_table_list= table_list;
@@ -2950,7 +2953,7 @@ TABLE *open_temporary_table(THD *thd, co
   share= tmp_table->s;
   tmp_table->reginfo.lock_type=TL_WRITE;	 // Simulate locked
   share->tmp_table= (tmp_table->file->has_transactions() ? 
-                     TRANSACTIONAL_TMP_TABLE : TMP_TABLE);
+                     TRANSACTIONAL_TMP_TABLE : NON_TRANSACTIONAL_TMP_TABLE);
   share->table_cache_key= (char*) (tmp_table+1);
   share->db= share->table_cache_key;
   share->key_length= (uint) (strmov(((char*) (share->table_name=
@@ -3573,14 +3576,35 @@ find_field_in_tables(THD *thd, Item_iden
   {
     Field *cur_field= find_field_in_table_ref(thd, cur_table, name, length,
                                               item->name, db, table_name, ref,
-                                              check_privileges, allow_rowid,
+                                              check_privileges,
+                                              allow_rowid,
                                               &(item->cached_field_index),
                                               register_tree_change,
                                               &actual_table);
     if (cur_field)
     {
       if (cur_field == WRONG_GRANT)
-	return (Field*) 0;
+      {
+        if (thd->lex->sql_command != SQLCOM_SHOW_FIELDS)
+          return (Field*) 0;
+
+        thd->clear_error();
+        cur_field= find_field_in_table_ref(thd, cur_table, name, length,
+                                           item->name, db, table_name, ref,
+                                           false,
+                                           allow_rowid,
+                                           &(item->cached_field_index),
+                                           register_tree_change,
+                                           &actual_table);
+        if (cur_field)
+        {
+          Field *nf=new Field_null(NULL,0,Field::NONE,
+                                   cur_field->field_name,
+                                   cur_field->table,
+                                   &my_charset_bin);
+          cur_field= nf;
+        }
+      }
 
       /*
         Store the original table of the field, which may be different from
@@ -3603,7 +3627,7 @@ find_field_in_tables(THD *thd, Item_iden
             report_error == IGNORE_EXCEPT_NON_UNIQUE)
           my_error(ER_NON_UNIQ_ERROR, MYF(0),
                    table_name ? item->full_name() : name, thd->where);
-	return (Field*) 0;
+        return (Field*) 0;
       }
       found= cur_field;
     }
@@ -4582,7 +4606,8 @@ int setup_wild(THD *thd, TABLE_LIST *tab
 
           Item_int do not need fix_fields() because it is basic constant.
         */
-        it.replace(new Item_int("Not_used", (longlong) 1, 21));
+        it.replace(new Item_int("Not_used", (longlong) 1,
+                                MY_INT64_NUM_DECIMAL_DIGITS));
       }
       else if (insert_fields(thd, ((Item_field*) item)->context,
                              ((Item_field*) item)->db_name,
@@ -5271,6 +5296,11 @@ err_no_arena:
     values        values to fill with
     ignore_errors TRUE if we should ignore errors
 
+  NOTE
+    fill_record() may set table->auto_increment_field_not_null and a
+    caller should make sure that it is reset after their last call to this
+    function.
+
   RETURN
     FALSE   OK
     TRUE    error occured
@@ -5283,27 +5313,52 @@ fill_record(THD * thd, List<Item> &field
   List_iterator_fast<Item> f(fields),v(values);
   Item *value, *fld;
   Item_field *field;
+  TABLE *table= 0;
   DBUG_ENTER("fill_record");
 
+  /*
+    Reset the table->auto_increment_field_not_null as it is valid for
+    only one row.
+  */
+  if (fields.elements)
+  {
+    /*
+      On INSERT or UPDATE fields are checked to be from the same table,
+      thus we safely can take table from the first field.
+    */
+    fld= (Item_field*)f++;
+    if (!(field= fld->filed_for_view_update()))
+    {
+      my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), fld->name);
+      goto err;
+    }
+    table= field->field->table;
+    table->auto_increment_field_not_null= FALSE;
+    f.rewind();
+  }
   while ((fld= f++))
   {
     if (!(field= fld->filed_for_view_update()))
     {
       my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), fld->name);
-      DBUG_RETURN(TRUE);
+      goto err;
     }
     value=v++;
     Field *rfield= field->field;
-    TABLE *table= rfield->table;
+    table= rfield->table;
     if (rfield == table->next_number_field)
       table->auto_increment_field_not_null= TRUE;
     if ((value->save_in_field(rfield, 0) < 0) && !ignore_errors)
     {
       my_message(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), MYF(0));
-      DBUG_RETURN(TRUE);
+      goto err;
     }
   }
   DBUG_RETURN(thd->net.report_error);
+err:
+  if (table)
+    table->auto_increment_field_not_null= FALSE;
+  DBUG_RETURN(TRUE);
 }
 
 
@@ -5352,6 +5407,11 @@ fill_record_n_invoke_before_triggers(THD
     values        list of fields
     ignore_errors TRUE if we should ignore errors
 
+  NOTE
+    fill_record() may set table->auto_increment_field_not_null and a
+    caller should make sure that it is reset after their last call to this
+    function.
+
   RETURN
     FALSE   OK
     TRUE    error occured
@@ -5362,19 +5422,38 @@ fill_record(THD *thd, Field **ptr, List<
 {
   List_iterator_fast<Item> v(values);
   Item *value;
+  TABLE *table= 0;
   DBUG_ENTER("fill_record");
 
   Field *field;
+  /*
+    Reset the table->auto_increment_field_not_null as it is valid for
+    only one row.
+  */
+  if (*ptr)
+  {
+    /*
+      On INSERT or UPDATE fields are checked to be from the same table,
+      thus we safely can take table from the first field.
+    */
+    table= (*ptr)->table;
+    table->auto_increment_field_not_null= FALSE;
+  }
   while ((field = *ptr++))
   {
     value=v++;
-    TABLE *table= field->table;
+    table= field->table;
     if (field == table->next_number_field)
       table->auto_increment_field_not_null= TRUE;
     if (value->save_in_field(field, 0) == -1)
-      DBUG_RETURN(TRUE);
+      goto err;
   }
   DBUG_RETURN(thd->net.report_error);
+
+err:
+  if (table)
+    table->auto_increment_field_not_null= FALSE;
+  DBUG_RETURN(TRUE);
 }
 
 

--- 1.100/sql/sql_cache.cc	2007-04-03 09:05:20 -04:00
+++ 1.101/sql/sql_cache.cc	2007-04-24 18:29:01 -04:00
@@ -381,7 +381,7 @@ inline Query_cache_block * Query_cache_b
 void Query_cache_block::init(ulong block_length)
 {
   DBUG_ENTER("Query_cache_block::init");
-  DBUG_PRINT("qcache", ("init block 0x%lx  length: %lu", (ulong) this,
+  DBUG_PRINT("qcache", ("init block: 0x%lx  length: %lu", (ulong) this,
 			block_length));
   length = block_length;
   used = 0;
@@ -3687,7 +3687,7 @@ void Query_cache::queries_dump()
       Query_cache_query_flags flags;
       memcpy(&flags, str+len, QUERY_CACHE_FLAGS_SIZE);
       str[len]= 0; // make zero ending DB name
-      DBUG_PRINT("qcache", ("F:%u C:%u L:%lu T:'%s' (%u) '%s' '%s'",
+      DBUG_PRINT("qcache", ("F: %u  C: %u L: %lu  T: '%s' (%u)  '%s'  '%s'",
 			    flags.client_long_flag,
 			    flags.character_set_client_num, 
                             (ulong)flags.limit,
@@ -4010,7 +4010,7 @@ my_bool Query_cache::check_integrity(boo
       } while (block != bins[i].free_blocks);
       if (count != bins[i].number)
       {
-	DBUG_PRINT("error", ("bins[%d].number = %d, but bin have %d blocks",
+	DBUG_PRINT("error", ("bins[%d].number= %d, but bin have %d blocks",
 			     i, bins[i].number,  count));
 	result = 1;
       }

--- 1.261/sql/sql_class.cc	2007-04-24 18:11:52 -04:00
+++ 1.262/sql/sql_class.cc	2007-04-24 18:29:01 -04:00
@@ -336,6 +336,7 @@ void THD::init(void)
   if (variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES)
     server_status|= SERVER_STATUS_NO_BACKSLASH_ESCAPES;
   options= thd_startup_options;
+  no_trans_update.stmt= no_trans_update.all= FALSE;
   open_options=ha_open_options;
   update_lock_default= (variables.low_priority_updates ?
 			TL_WRITE_LOW_PRIORITY :
@@ -346,7 +347,6 @@ void THD::init(void)
   total_warn_count= 0;
   update_charset();
   bzero((char *) &status_var, sizeof(status_var));
-  variables.lc_time_names = &my_locale_en_US;
 }
 
 
@@ -616,6 +616,18 @@ void THD::cleanup_after_query()
     clear_next_insert_id= 0;
     next_insert_id= 0;
   }
+  /*
+    Reset rand_used so that detection of calls to rand() will save random 
+    seeds if needed by the slave.
+
+    Do not reset rand_used if inside a stored function or trigger because 
+    only the call to these operations is logged. Thus only the calling 
+    statement needs to detect rand() calls made by its substatements. These
+    substatements must not set rand_used to 0 because it would remove the
+    detection of rand() by the calling statement. 
+  */
+  if (!in_sub_stmt)
+    rand_used= 0;
   /* Free Items that were created during this execution */
   free_items();
   /* Reset where. */
@@ -751,7 +763,8 @@ void THD::add_changed_table(const char *
     {
       list_include(prev_changed, curr, changed_table_dup(key, key_length));
       DBUG_PRINT("info", 
-		 ("key_length %ld %u", key_length, (*prev_changed)->key_length));
+		 ("key_length: %ld  %u", key_length,
+                  (*prev_changed)->key_length));
       DBUG_VOID_RETURN;
     }
     else if (cmp == 0)
@@ -761,7 +774,7 @@ void THD::add_changed_table(const char *
       {
 	list_include(prev_changed, curr, changed_table_dup(key, key_length));
 	DBUG_PRINT("info", 
-		   ("key_length %ld %u", key_length,
+		   ("key_length:  %ld  %u", key_length,
 		    (*prev_changed)->key_length));
 	DBUG_VOID_RETURN;
       }
@@ -773,7 +786,7 @@ void THD::add_changed_table(const char *
     }
   }
   *prev_changed = changed_table_dup(key, key_length);
-  DBUG_PRINT("info", ("key_length %ld %u", key_length,
+  DBUG_PRINT("info", ("key_length: %ld  %u", key_length,
 		      (*prev_changed)->key_length));
   DBUG_VOID_RETURN;
 }

--- 1.319/sql/sql_class.h	2007-04-24 18:11:52 -04:00
+++ 1.320/sql/sql_class.h	2007-04-24 18:29:01 -04:00
@@ -356,13 +356,25 @@ public:
   inline uint32 get_open_count() { return open_count; }
 };
 
-
+/*
+  The COPY_INFO structure is used by INSERT/REPLACE code.
+  The schema of the row counting by the INSERT/INSERT ... ON DUPLICATE KEY
+  UPDATE code:
+    If a row is inserted then the copied variable is incremented.
+    If a row is updated by the INSERT ... ON DUPLICATE KEY UPDATE and the
+      new data differs from the old one then the copied and the updated
+      variables are incremented.
+    The touched variable is incremented if a row was touched by the update part
+      of the INSERT ... ON DUPLICATE KEY UPDATE no matter whether the row
+      was actually changed or not.
+*/
 typedef struct st_copy_info {
-  ha_rows records;
-  ha_rows deleted;
-  ha_rows updated;
-  ha_rows copied;
+  ha_rows records; /* Number of processed records */
+  ha_rows deleted; /* Number of deleted records */
+  ha_rows updated; /* Number of updated records */
+  ha_rows copied;  /* Number of copied records */
   ha_rows error_count;
+  ha_rows touched; /* Number of touched records */
   enum enum_duplicates handle_duplicates;
   int escape_char, last_errno;
   bool ignore;
@@ -1436,7 +1448,11 @@ public:
   bool	     charset_is_system_charset, charset_is_collation_connection;
   bool       charset_is_character_set_filesystem;
   bool       enable_slow_log;   /* enable slow log for current statement */
-  bool	     no_trans_update, abort_on_warning;
+  struct {
+    bool all:1;
+    bool stmt:1;
+  } no_trans_update;
+  bool	     abort_on_warning;
   bool 	     got_warning;       /* Set on call to push_warning() */
   bool	     no_warnings_for_error; /* no warnings on call to my_error() */
   /* set during loop of derived table processing */
@@ -1660,7 +1676,7 @@ public:
   inline bool really_abort_on_warning()
   {
     return (abort_on_warning &&
-            (!no_trans_update ||
+            (!no_trans_update.stmt ||
              (variables.sql_mode & MODE_STRICT_ALL_TABLES)));
   }
   void set_status_var_init();

--- 1.192/sql/sql_delete.cc	2007-04-03 09:05:20 -04:00
+++ 1.193/sql/sql_delete.cc	2007-04-24 18:29:01 -04:00
@@ -60,6 +60,27 @@ bool mysql_delete(THD *thd, TABLE_LIST *
   if (mysql_prepare_delete(thd, table_list, &conds))
     DBUG_RETURN(TRUE);
 
+  /* check ORDER BY even if it can be ignored */
+  if (order && order->elements)
+  {
+    TABLE_LIST   tables;
+    List<Item>   fields;
+    List<Item>   all_fields;
+
+    bzero((char*) &tables,sizeof(tables));
+    tables.table = table;
+    tables.alias = table_list->alias;
+
+      if (select_lex->setup_ref_array(thd, order->elements) ||
+	  setup_order(thd, select_lex->ref_pointer_array, &tables,
+                    fields, all_fields, (ORDER*) order->first))
+    {
+      delete select;
+      free_underlaid_joins(thd, &thd->lex->select_lex);
+      DBUG_RETURN(TRUE);
+    }
+  }
+
   const_cond= (!conds || conds->const_item());
   safe_update=test(thd->options & OPTION_SAFE_UPDATES);
   if (safe_update && const_cond)
@@ -148,23 +169,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *
   {
     uint         length= 0;
     SORT_FIELD  *sortorder;
-    TABLE_LIST   tables;
-    List<Item>   fields;
-    List<Item>   all_fields;
     ha_rows examined_rows;
-
-    bzero((char*) &tables,sizeof(tables));
-    tables.table = table;
-    tables.alias = table_list->alias;
-
-      if (select_lex->setup_ref_array(thd, order->elements) ||
-	  setup_order(thd, select_lex->ref_pointer_array, &tables,
-                    fields, all_fields, (ORDER*) order->first))
-    {
-      delete select;
-      free_underlaid_joins(thd, &thd->lex->select_lex);
-      DBUG_RETURN(TRUE);
-    }
     
     if ((!select || table->quick_keys.is_clear_all()) && limit != HA_POS_ERROR)
       usable_index= get_index_for_order(table, (ORDER*)(order->first), limit);
@@ -212,7 +217,19 @@ bool mysql_delete(THD *thd, TABLE_LIST *
   thd_proc_info(thd, "updating");
 
   if (table->triggers)
+  {
     table->triggers->mark_fields_used(thd, TRG_EVENT_DELETE);
+    if (table->triggers->has_triggers(TRG_EVENT_DELETE,
+                                      TRG_ACTION_AFTER))
+    {
+      /*
+	The table has AFTER DELETE triggers that might access to subject table
+	and therefore might need delete to be done immediately. So we turn-off
+	the batching.
+      */
+      (void) table->file->extra(HA_EXTRA_DELETE_CANNOT_BATCH);
+    }
+  }
 
   while (!(error=info.read_record(&info)) && !thd->killed &&
 	 !thd->net.report_error)
@@ -311,7 +328,7 @@ cleanup:
 	error=1;
     }
     if (!transactional_table)
-      thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
+      thd->no_trans_update.all= TRUE;
   }
   free_underlaid_joins(thd, select_lex);
   if (transactional_table)
@@ -352,6 +369,8 @@ bool mysql_prepare_delete(THD *thd, TABL
 {
   Item *fake_conds= 0;
   SELECT_LEX *select_lex= &thd->lex->select_lex;
+  const char *operation = thd->lex->sql_command == SQLCOM_TRUNCATE ?
+                          "TRUNCATE" : "DELETE";
   DBUG_ENTER("mysql_prepare_delete");
   List<Item> all_fields;
 
@@ -366,14 +385,14 @@ bool mysql_prepare_delete(THD *thd, TABL
     DBUG_RETURN(TRUE);
   if (!table_list->updatable || check_key_in_view(thd, table_list))
   {
-    my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "DELETE");
+    my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, operation);
     DBUG_RETURN(TRUE);
   }
   {
     TABLE_LIST *duplicate;
     if ((duplicate= unique_table(thd, table_list, table_list->next_global, 0)))
     {
-      update_non_unique_table_error(table_list, "DELETE", duplicate);
+      update_non_unique_table_error(table_list, operation, duplicate);
       DBUG_RETURN(TRUE);
     }
   }
@@ -535,7 +554,19 @@ multi_delete::initialize_tables(JOIN *jo
       else
 	normal_tables= 1;
       if (tbl->triggers)
+      {
         tbl->triggers->mark_fields_used(thd, TRG_EVENT_DELETE);
+	if (tbl->triggers->has_triggers(TRG_EVENT_DELETE,
+                                      TRG_ACTION_AFTER))
+	{
+	  /*
+	    The table has AFTER DELETE triggers that might access to subject 
+	    table and therefore might need delete to be done immediately. 
+	    So we turn-off the batching.
+	  */
+	  (void) tbl->file->extra(HA_EXTRA_DELETE_CANNOT_BATCH);
+	}
+      }
     }
     else if ((tab->type != JT_SYSTEM && tab->type != JT_CONST) &&
              walk == delete_tables)
@@ -791,7 +822,7 @@ bool multi_delete::send_eof()
 	local_error=1;  // Log write failed: roll back the SQL statement
     }
     if (!transactional_tables)
-      thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
+      thd->no_trans_update.all= TRUE;
   }
   /* Commit or rollback the current SQL statement */
   if (transactional_tables)
@@ -866,7 +897,8 @@ bool mysql_truncate(THD *thd, TABLE_LIST
   if (!dont_send_ok)
   {
     db_type table_type;
-    mysql_frm_type(thd, path, &table_type);
+    if (mysql_frm_type(thd, path, &table_type) == FRMTYPE_VIEW)
+      goto trunc_by_del;
     if (table_type == DB_TYPE_UNKNOWN)
     {
       my_error(ER_NO_SUCH_TABLE, MYF(0),

--- 1.215/sql/sql_insert.cc	2007-04-03 09:05:20 -04:00
+++ 1.216/sql/sql_insert.cc	2007-04-24 18:29:01 -04:00
@@ -330,6 +330,51 @@ static int check_update_fields(THD *thd,
 
 
 /*
+  Prepare triggers  for INSERT-like statement.
+
+  SYNOPSIS
+    prepare_triggers_for_insert_stmt()
+      thd     The current thread
+      table   Table to which insert will happen
+      duplic  Type of duplicate handling for insert which will happen
+
+  NOTE
+    Prepare triggers for INSERT-like statement by marking fields
+    used by triggers and inform handlers that batching of UPDATE/DELETE 
+    cannot be done if there are BEFORE UPDATE/DELETE triggers.
+*/
+
+void prepare_triggers_for_insert_stmt(THD *thd, TABLE *table,
+                                      enum_duplicates duplic)
+{
+  if (table->triggers)
+  {
+    if (table->triggers->has_triggers(TRG_EVENT_DELETE,
+                                      TRG_ACTION_AFTER))
+    {
+      /*
+        The table has AFTER DELETE triggers that might access to 
+        subject table and therefore might need delete to be done 
+        immediately. So we turn-off the batching.
+      */ 
+      (void) table->file->extra(HA_EXTRA_DELETE_CANNOT_BATCH);
+    }
+    if (table->triggers->has_triggers(TRG_EVENT_UPDATE,
+                                      TRG_ACTION_AFTER))
+    {
+      /*
+        The table has AFTER UPDATE triggers that might access to subject 
+        table and therefore might need update to be done immediately. 
+        So we turn-off the batching.
+      */ 
+      (void) table->file->extra(HA_EXTRA_UPDATE_CANNOT_BATCH);
+    }
+    mark_fields_used_by_triggers_for_insert_stmt(thd, table, duplic);
+  }
+}
+
+
+/*
   Mark fields used by triggers for INSERT-like statement.
 
   SYNOPSIS
@@ -473,10 +518,15 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
   thd_proc_info(thd, "init");
   thd->used_tables=0;
   values= its++;
+  value_count= values->elements;
 
   if (mysql_prepare_insert(thd, table_list, table, fields, values,
 			   update_fields, update_values, duplic, &unused_conds,
-                           FALSE))
+                           FALSE,
+                           (fields.elements || !value_count),
+                           !ignore && (thd->variables.sql_mode &
+                                       (MODE_STRICT_TRANS_TABLES |
+                                        MODE_STRICT_ALL_TABLES))))
     goto abort;
 
   /* mysql_prepare_insert set table_list->table if it was not set */
@@ -502,7 +552,6 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
   table_list->next_local= 0;
   context->resolve_in_table_list_only(table_list);
 
-  value_count= values->elements;
   while ((values= its++))
   {
     counter++;
@@ -522,7 +571,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
   /*
     Fill in the given fields and dump it to the table file
   */
-  info.records= info.deleted= info.copied= info.updated= 0;
+  info.records= info.deleted= info.copied= info.updated= info.touched= 0;
   info.ignore= ignore;
   info.handle_duplicates=duplic;
   info.update_fields= &update_fields;
@@ -580,20 +629,12 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
   if (lock_type != TL_WRITE_DELAYED && !thd->prelocked_mode)
     table->file->start_bulk_insert(values_list.elements);
 
-  thd->no_trans_update= 0;
-  thd->abort_on_warning= (!ignore &&
-                          (thd->variables.sql_mode &
-                           (MODE_STRICT_TRANS_TABLES |
-                            MODE_STRICT_ALL_TABLES)));
-
-  if ((fields.elements || !value_count) &&
-      check_that_all_fields_are_given_values(thd, table, table_list))
-  {
-    /* thd->net.report_error is now set, which will abort the next loop */
-    error= 1;
-  }
+  thd->no_trans_update.stmt= FALSE;
+  thd->abort_on_warning= (!ignore && (thd->variables.sql_mode &
+                                       (MODE_STRICT_TRANS_TABLES |
+                                        MODE_STRICT_ALL_TABLES)));
 
-  mark_fields_used_by_triggers_for_insert_stmt(thd, table, duplic);
+  prepare_triggers_for_insert_stmt(thd, table, duplic);
 
   if (table_list->prepare_where(thd, 0, TRUE) ||
       table_list->prepare_check_option(thd))
@@ -735,7 +776,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
             error=1;
         }
         if (!transactional_table)
-          thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
+          thd->no_trans_update.all= TRUE;
       }
     }
     if (transactional_table)
@@ -761,14 +802,15 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
   table->next_number_field=0;
   thd->count_cuted_fields= CHECK_FIELD_IGNORE;
   thd->next_insert_id=0;			// Reset this if wrongly used
+  table->auto_increment_field_not_null= FALSE;
   if (duplic != DUP_ERROR || ignore)
     table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
   if (duplic == DUP_REPLACE &&
       (!table->triggers || !table->triggers->has_delete_triggers()))
     table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
 
-  /* Reset value of LAST_INSERT_ID if no rows where inserted */
-  if (!info.copied && thd->insert_id_used)
+  /* Reset value of LAST_INSERT_ID if no rows were inserted or touched */
+  if (!info.copied && !info.touched && thd->insert_id_used)
   {
     thd->insert_id(0);
     id=0;
@@ -963,6 +1005,10 @@ static bool mysql_prepare_insert_check_t
 			be taken from table_list->table)    
     where		Where clause (for insert ... select)
     select_insert	TRUE if INSERT ... SELECT statement
+    check_fields        TRUE if need to check that all INSERT fields are 
+                        given values.
+    abort_on_warning    whether to report if some INSERT field is not 
+                        assigned as an error (TRUE) or as a warning (FALSE).
 
   TODO (in far future)
     In cases of:
@@ -983,7 +1029,8 @@ bool mysql_prepare_insert(THD *thd, TABL
                           TABLE *table, List<Item> &fields, List_item *values,
                           List<Item> &update_fields, List<Item> &update_values,
                           enum_duplicates duplic,
-                          COND **where, bool select_insert)
+                          COND **where, bool select_insert,
+                          bool check_fields, bool abort_on_warning)
 {
   SELECT_LEX *select_lex= &thd->lex->select_lex;
   Name_resolution_context *context= &select_lex->context;
@@ -1046,10 +1093,22 @@ bool mysql_prepare_insert(THD *thd, TABL
     table_list->next_local= 0;
     context->resolve_in_table_list_only(table_list);
 
-    if (!(res= check_insert_fields(thd, context->table_list, fields, *values,
-                                 !insert_into_view, &map) ||
-          setup_fields(thd, 0, *values, 0, 0, 0)) 
-        && duplic == DUP_UPDATE)
+    res= check_insert_fields(thd, context->table_list, fields, *values,
+                             !insert_into_view, &map) ||
+      setup_fields(thd, 0, *values, 0, 0, 0);
+
+    if (!res && check_fields)
+    {
+      bool saved_abort_on_warning= thd->abort_on_warning;
+      thd->abort_on_warning= abort_on_warning;
+      res= check_that_all_fields_are_given_values(thd, 
+                                                  table ? table : 
+                                                  context->table_list->table,
+                                                  context->table_list);
+      thd->abort_on_warning= saved_abort_on_warning;
+    }
+
+    if (!res && duplic == DUP_UPDATE)
     {
       select_lex->no_wrap_view_item= TRUE;
       res= check_update_fields(thd, context->table_list, update_fields, &map);
@@ -1116,7 +1175,7 @@ static int last_uniq_key(TABLE *table,ui
     then both on update triggers will work instead. Similarly both on
     delete triggers will be invoked if we will delete conflicting records.
 
-    Sets thd->no_trans_update if table which is updated didn't have
+    Sets thd->no_trans_update.stmt to TRUE if table which is updated didn't have
     transactions.
 
   RETURN VALUE
@@ -1221,21 +1280,23 @@ int write_record(THD *thd, TABLE *table,
           }
           goto err;
         }
+
+        if (table->next_number_field)
+          table->file->adjust_next_insert_id_after_explicit_value(
+            table->next_number_field->val_int());
+        info->touched++;
+
         if ((table->file->table_flags() & HA_PARTIAL_COLUMN_READ) ||
             compare_record(table, thd->query_id))
         {
           info->updated++;
-
-          if (table->next_number_field)
-            table->file->adjust_next_insert_id_after_explicit_value(
-              table->next_number_field->val_int());
-
           trg_error= (table->triggers &&
                       table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
                                                         TRG_ACTION_AFTER,
                                                         TRUE));
           info->copied++;
         }
+
         goto ok_or_after_trg_err;
       }
       else /* DUP_REPLACE */
@@ -1280,7 +1341,7 @@ int write_record(THD *thd, TABLE *table,
             goto err;
           info->deleted++;
           if (!table->file->has_transactions())
-            thd->no_trans_update= 1;
+            thd->no_trans_update.stmt= TRUE;
           if (table->triggers &&
               table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
                                                 TRG_ACTION_AFTER, TRUE))
@@ -1312,7 +1373,7 @@ ok_or_after_trg_err:
   if (key)
     my_safe_afree(key,table->s->max_unique_length,MAX_KEY_LENGTH);
   if (!table->file->has_transactions())
-    thd->no_trans_update= 1;
+    thd->no_trans_update.stmt= TRUE;
   DBUG_RETURN(trg_error);
 
 err:
@@ -2324,7 +2385,7 @@ bool mysql_insert_select_prepare(THD *th
                            lex->query_tables->table, lex->field_list, 0,
                            lex->update_list, lex->value_list,
                            lex->duplicates,
-                           &select_lex->where, TRUE))
+                           &select_lex->where, TRUE, FALSE, FALSE))
     DBUG_RETURN(TRUE);
 
   /*
@@ -2386,7 +2447,18 @@ select_insert::prepare(List<Item> &value
                            !insert_into_view, &map) ||
        setup_fields(thd, 0, values, 0, 0, 0);
 
-  if (info.handle_duplicates == DUP_UPDATE)
+  if (!res && fields->elements)
+  {
+    bool saved_abort_on_warning= thd->abort_on_warning;
+    thd->abort_on_warning= !info.ignore && (thd->variables.sql_mode &
+                                            (MODE_STRICT_TRANS_TABLES |
+                                             MODE_STRICT_ALL_TABLES));
+    res= check_that_all_fields_are_given_values(thd, table_list->table, 
+                                                table_list);
+    thd->abort_on_warning= saved_abort_on_warning;
+  }
+
+  if (info.handle_duplicates == DUP_UPDATE && !res)
   {
     Name_resolution_context *context= &lex->select_lex.context;
     Name_resolution_context_state ctx_state;
@@ -2492,19 +2564,17 @@ select_insert::prepare(List<Item> &value
       table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
     table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
   }
-  thd->no_trans_update= 0;
+  thd->no_trans_update.stmt= FALSE;
   thd->abort_on_warning= (!info.ignore &&
                           (thd->variables.sql_mode &
                            (MODE_STRICT_TRANS_TABLES |
                             MODE_STRICT_ALL_TABLES)));
-  res= ((fields->elements &&
-         check_that_all_fields_are_given_values(thd, table, table_list)) ||
-        table_list->prepare_where(thd, 0, TRUE) ||
+  res= (table_list->prepare_where(thd, 0, TRUE) ||
         table_list->prepare_check_option(thd));
 
   if (!res)
-    mark_fields_used_by_triggers_for_insert_stmt(thd, table,
-                                                 info.handle_duplicates);
+    prepare_triggers_for_insert_stmt(thd, table,
+                                     info.handle_duplicates);
   DBUG_RETURN(res);
 }
 
@@ -2547,6 +2617,7 @@ select_insert::~select_insert()
   if (table)
   {
     table->next_number_field=0;
+    table->auto_increment_field_not_null= FALSE;
     table->file->reset();
   }
   thd->count_cuted_fields= CHECK_FIELD_IGNORE;
@@ -2652,7 +2723,7 @@ void select_insert::send_error(uint errc
       mysql_bin_log.write(&qinfo);
     }
     if (!table->s->tmp_table)
-      thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
+      thd->no_trans_update.all= TRUE;
   }
   if (info.copied || info.deleted || info.updated)
   {
@@ -2681,7 +2752,7 @@ bool select_insert::send_eof()
   {
     query_cache_invalidate3(thd, table, 1);
     if (!(table->file->has_transactions() || table->s->tmp_table))
-      thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
+      thd->no_trans_update.all= TRUE;
   }
 
   if (last_insert_id)
@@ -2907,7 +2978,7 @@ select_create::prepare(List<Item> &value
   }
   if (!thd->prelocked_mode)
     table->file->start_bulk_insert((ha_rows) 0);
-  thd->no_trans_update= 0;
+  thd->no_trans_update.stmt= FALSE;
   thd->abort_on_warning= (!info.ignore &&
                           (thd->variables.sql_mode &
                            (MODE_STRICT_TRANS_TABLES |

--- 1.218/sql/sql_lex.cc	2007-04-03 09:05:20 -04:00
+++ 1.219/sql/sql_lex.cc	2007-04-24 18:29:01 -04:00
@@ -1834,6 +1834,7 @@ bool st_lex::can_use_merged()
   case SQLCOM_UPDATE_MULTI:
   case SQLCOM_DELETE:
   case SQLCOM_DELETE_MULTI:
+  case SQLCOM_TRUNCATE:
   case SQLCOM_INSERT:
   case SQLCOM_INSERT_SELECT:
   case SQLCOM_REPLACE:

--- 1.242/sql/sql_lex.h	2007-04-03 09:05:20 -04:00
+++ 1.243/sql/sql_lex.h	2007-04-24 18:29:02 -04:00
@@ -473,6 +473,7 @@ public:
   bool change_result(select_subselect *result, select_subselect *old_result);
   void set_limit(st_select_lex *values);
   void set_thd(THD *thd_arg) { thd= thd_arg; }
+  inline bool is_union (); 
 
   friend void lex_start(THD *thd, uchar *buf, uint length);
   friend int subselect_union_engine::exec();
@@ -704,6 +705,13 @@ public:
   void cleanup_all_joins(bool full);
 };
 typedef class st_select_lex SELECT_LEX;
+
+
+inline bool st_select_lex_unit::is_union ()
+{ 
+  return first_select()->next_select() && 
+    first_select()->next_select()->linkage == UNION_TYPE;
+}
 
 #define ALTER_ADD_COLUMN	1
 #define ALTER_DROP_COLUMN	2

--- 1.599/sql/sql_parse.cc	2007-04-24 18:11:52 -04:00
+++ 1.600/sql/sql_parse.cc	2007-04-25 08:14:43 -04:00
@@ -147,7 +147,8 @@ static bool end_active_trans(THD *thd)
     thd->server_status&= ~SERVER_STATUS_IN_TRANS;
     if (ha_commit(thd))
       error=1;
-    thd->options&= ~(OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
+    thd->options&= ~OPTION_BEGIN;
+    thd->no_trans_update.all= FALSE;
   }
   DBUG_RETURN(error);
 }
@@ -171,8 +172,8 @@ static bool begin_trans(THD *thd)
   else
   {
     LEX *lex= thd->lex;
-    thd->options= ((thd->options &  ~(OPTION_STATUS_NO_TRANS_UPDATE)) |
-		   OPTION_BEGIN);
+    thd->no_trans_update.all= FALSE;
+    thd->options|= OPTION_BEGIN;
     thd->server_status|= SERVER_STATUS_IN_TRANS;
     if (lex->start_transaction_opt & MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT)
       error= ha_start_consistent_snapshot(thd);
@@ -289,7 +290,8 @@ int check_user(THD *thd, enum enum_serve
 	       bool check_count)
 {
   DBUG_ENTER("check_user");
-  
+  LEX_STRING db_str= { (char *) db, db ? strlen(db) : 0 };
+
 #ifdef NO_EMBEDDED_ACCESS_CHECKS
   thd->main_security_ctx.master_access= GLOBAL_ACLS;       // Full rights
   /* Change database if necessary */
@@ -300,7 +302,7 @@ int check_user(THD *thd, enum enum_serve
       function returns 0
     */
     thd->reset_db(NULL, 0);
-    if (mysql_change_db(thd, db, FALSE))
+    if (mysql_change_db(thd, &db_str, FALSE))
     {
       /* Send the error to the client */
       net_send_error(thd);
@@ -442,7 +444,7 @@ int check_user(THD *thd, enum enum_serve
       /* Change database if necessary */
       if (db && db[0])
       {
-        if (mysql_change_db(thd, db, FALSE))
+        if (mysql_change_db(thd, &db_str, FALSE))
         {
           /* Send error to the client */
           net_send_error(thd);
@@ -1463,7 +1465,8 @@ int end_trans(THD *thd, enum enum_mysql_
     */
     thd->server_status&= ~SERVER_STATUS_IN_TRANS;
     res= ha_commit(thd);
-    thd->options&= ~(OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
+    thd->options&= ~OPTION_BEGIN;
+    thd->no_trans_update.all= FALSE;
     break;
   case COMMIT_RELEASE:
     do_release= 1; /* fall through */
@@ -1480,7 +1483,8 @@ int end_trans(THD *thd, enum enum_mysql_
     thd->server_status&= ~SERVER_STATUS_IN_TRANS;
     if (ha_rollback(thd))
       res= -1;
-    thd->options&= ~(OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
+    thd->options&= ~OPTION_BEGIN;
+    thd->no_trans_update.all= FALSE;
     if (!res && (completion == ROLLBACK_AND_CHAIN))
       res= begin_trans(thd);
     break;
@@ -1635,7 +1639,7 @@ bool dispatch_command(enum enum_server_c
 			&LOCK_status);
     thd->convert_string(&tmp, system_charset_info,
 			packet, strlen(packet), thd->charset());
-    if (!mysql_change_db(thd, tmp.str, FALSE))
+    if (!mysql_change_db(thd, &tmp, FALSE))
     {
       mysql_log.write(thd,command,"%s",thd->db);
       send_ok(thd);
@@ -1859,7 +1863,7 @@ bool dispatch_command(enum enum_server_c
     packet= pend+1;
 
     if (!my_strcasecmp(system_charset_info, table_list.db,
-                       information_schema_name.str))
+                       INFORMATION_SCHEMA_NAME.str))
     {
       ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, table_list.alias);
       if (schema_table)
@@ -2234,7 +2238,8 @@ int prepare_schema_table(THD *thd, LEX *
                          enum enum_schema_tables schema_table_idx)
 {
   DBUG_ENTER("prepare_schema_table");
-  SELECT_LEX *sel= 0;
+  SELECT_LEX *schema_select_lex= NULL;
+
   switch (schema_table_idx) {
   case SCH_SCHEMATA:
 #if defined(DONT_ALLOW_SHOW_COMMANDS)
@@ -2242,11 +2247,9 @@ int prepare_schema_table(THD *thd, LEX *
                ER(ER_NOT_ALLOWED_COMMAND), MYF(0));   /* purecov: inspected */
     DBUG_RETURN(1);
 #else
-    if ((specialflag & SPECIAL_SKIP_SHOW_DB) &&
-	check_global_access(thd, SHOW_DB_ACL))
-      DBUG_RETURN(1);
     break;
 #endif
+
   case SCH_TABLE_NAMES:
   case SCH_TABLES:
   case SCH_VIEWS:
@@ -2256,32 +2259,25 @@ int prepare_schema_table(THD *thd, LEX *
                ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */
     DBUG_RETURN(1);
 #else
+    if (lex->select_lex.db == NULL &&
+        thd->copy_db_to(&lex->select_lex.db, NULL))
     {
-      char *db;
-      if (lex->select_lex.db == NULL &&
-          thd->copy_db_to(&lex->select_lex.db, 0))
-      {
-        DBUG_RETURN(1);
-      }
-      db= lex->select_lex.db;
-      remove_escape(db);				// Fix escaped '_'
-      if (check_db_name(db))
-      {
-        my_error(ER_WRONG_DB_NAME, MYF(0), db);
-        DBUG_RETURN(1);
-      }
-      if (check_access(thd, SELECT_ACL, db, &thd->col_access, 0, 0,
-                       is_schema_db(db)))
-        DBUG_RETURN(1);			        /* purecov: inspected */
-      if (!thd->col_access && check_grant_db(thd,db))
-      {
-	my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
-                 thd->security_ctx->priv_user, thd->security_ctx->priv_host,
-                 db);
-	DBUG_RETURN(1);
-      }
-      break;
+      DBUG_RETURN(1);
     }
+
+    schema_select_lex= new SELECT_LEX();
+    schema_select_lex->db= lex->select_lex.db;
+    schema_select_lex->table_list.first= NULL;
+    remove_escape(schema_select_lex->db); // Fix escaped '_'
+
+    if (check_db_name(schema_select_lex->db))
+    {
+      my_error(ER_WRONG_DB_NAME, MYF(0), schema_select_lex->db);
+      DBUG_RETURN(1);
+    }
+
+
+    break;
 #endif
   case SCH_COLUMNS:
   case SCH_STATISTICS:
@@ -2290,28 +2286,23 @@ int prepare_schema_table(THD *thd, LEX *
                ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */
     DBUG_RETURN(1);
 #else
-    if (table_ident)
     {
+      DBUG_ASSERT(table_ident);
+
       TABLE_LIST **query_tables_last= lex->query_tables_last;
-      sel= new SELECT_LEX();
+      schema_select_lex= new SELECT_LEX();
       /* 'parent_lex' is used in init_query() so it must be before it. */
-      sel->parent_lex= lex;
-      sel->init_query();
-      if (!sel->add_table_to_list(thd, table_ident, 0, 0, TL_READ, 
-                                 (List<String> *) 0, (List<String> *) 0))
+      schema_select_lex->parent_lex= lex;
+      schema_select_lex->init_query();
+      if (!schema_select_lex->add_table_to_list(thd, table_ident, 0, 0, TL_READ,
+                                  (List<String> *) 0, (List<String> *) 0))
         DBUG_RETURN(1);
       lex->query_tables_last= query_tables_last;
-      TABLE_LIST *table_list= (TABLE_LIST*) sel->table_list.first;
-      char *db= table_list->db;
-      remove_escape(db);			// Fix escaped '_'
-      remove_escape(table_list->table_name);
-      if (check_access(thd,SELECT_ACL | EXTRA_ACL,db,
-                       &table_list->grant.privilege, 0, 0,
-                       test(table_list->schema_table)))
-        DBUG_RETURN(1);				/* purecov: inspected */
-      if (grant_option && check_grant(thd, SELECT_ACL, table_list, 2,
-                                      UINT_MAX, 0))
-        DBUG_RETURN(1);
+
+      TABLE_LIST *dst_table= (TABLE_LIST*) schema_select_lex->table_list.first;
+      remove_escape(dst_table->db);			// Fix escaped '_'
+      remove_escape(dst_table->table_name);
+
       break;
     }
 #endif
@@ -2338,7 +2329,7 @@ int prepare_schema_table(THD *thd, LEX *
     DBUG_RETURN(1);
   }
   TABLE_LIST *table_list= (TABLE_LIST*) select_lex->table_list.first;
-  table_list->schema_select_lex= sel;
+  table_list->schema_select_lex= schema_select_lex;
   table_list->schema_table_reformed= 1;
   statistic_increment(thd->status_var.com_stat[lex->orig_sql_command],
                       &LOCK_status);
@@ -2965,7 +2956,7 @@ mysql_execute_command(THD *thd)
     else 
     {
       /* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
-      thd->options|= OPTION_STATUS_NO_TRANS_UPDATE;
+      thd->no_trans_update.all= TRUE;
     }
     DBUG_ASSERT(first_table == all_tables && first_table != 0);
     bool link_to_local;
@@ -3739,10 +3730,10 @@ end_with_restore_list:
 	we silently add IF EXISTS if TEMPORARY was used.
       */
       if (thd->slave_thread)
-	lex->drop_if_exists= 1;
+        lex->drop_if_exists= 1;
 
       /* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
-      thd->options|= OPTION_STATUS_NO_TRANS_UPDATE;
+      thd->no_trans_update.all= TRUE;
     }
     /* DDL and binlog write order protected by LOCK_open */
     res= mysql_rm_table(thd, first_table, lex->drop_if_exists,
@@ -3782,9 +3773,14 @@ end_with_restore_list:
     }
 #endif
   case SQLCOM_CHANGE_DB:
-    if (!mysql_change_db(thd,select_lex->db,FALSE))
+  {
+    LEX_STRING db_str= { (char *) select_lex->db, strlen(select_lex->db) };
+
+    if (!mysql_change_db(thd, &db_str, FALSE))
       send_ok(thd);
+
     break;
+  }
 
   case SQLCOM_LOAD:
   {
@@ -4328,7 +4324,7 @@ end_with_restore_list:
         res= TRUE; // cannot happen
       else
       {
-        if ((thd->options & OPTION_STATUS_NO_TRANS_UPDATE) &&
+        if (thd->no_trans_update.all &&
             !thd->slave_thread)
           push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
                        ER_WARNING_NOT_COMPLETE_ROLLBACK,
@@ -4971,8 +4967,8 @@ create_sp_error:
     thd->transaction.xid_state.xa_state=XA_ACTIVE;
     thd->transaction.xid_state.xid.set(thd->lex->xid);
     xid_cache_insert(&thd->transaction.xid_state);
-    thd->options= ((thd->options & ~(OPTION_STATUS_NO_TRANS_UPDATE)) |
-                   OPTION_BEGIN);
+    thd->no_trans_update.all= FALSE;
+    thd->options|= OPTION_BEGIN;
     thd->server_status|= SERVER_STATUS_IN_TRANS;
     send_ok(thd);
     break;
@@ -5065,7 +5061,8 @@ create_sp_error:
                xa_state_names[thd->transaction.xid_state.xa_state]);
       break;
     }
-    thd->options&= ~(OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
+    thd->options&= ~OPTION_BEGIN;
+    thd->no_trans_update.all= FALSE;
     thd->server_status&= ~SERVER_STATUS_IN_TRANS;
     xid_cache_delete(&thd->transaction.xid_state);
     thd->transaction.xid_state.xa_state=XA_NOTR;
@@ -5095,7 +5092,8 @@ create_sp_error:
       my_error(ER_XAER_RMERR, MYF(0));
     else
       send_ok(thd);
-    thd->options&= ~(OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
+    thd->options&= ~OPTION_BEGIN;
+    thd->no_trans_update.all= FALSE;
     thd->server_status&= ~SERVER_STATUS_IN_TRANS;
     xid_cache_delete(&thd->transaction.xid_state);
     thd->transaction.xid_state.xa_state=XA_NOTR;
@@ -5191,7 +5189,10 @@ bool check_single_table_access(THD *thd,
     goto deny;
 
   /* Show only 1 table for check_grant */
-  if (grant_option && check_grant(thd, privilege, all_tables, 0, 1, 0))
+  if (grant_option &&
+      !(all_tables->belong_to_view &&
+        (thd->lex->sql_command == SQLCOM_SHOW_FIELDS)) &&
+      check_grant(thd, privilege, all_tables, 0, 1, 0))
     goto deny;
 
   thd->security_ctx= backup_ctx;
@@ -5409,6 +5410,83 @@ bool check_global_access(THD *thd, ulong
 }
 
 
+static bool check_show_access(THD *thd, TABLE_LIST *table)
+{
+  switch (get_schema_table_idx(table->schema_table))
+  {
+  case SCH_SCHEMATA:
+    return (specialflag & SPECIAL_SKIP_SHOW_DB) &&
+           check_global_access(thd, SHOW_DB_ACL);
+
+  case SCH_TABLE_NAMES:
+  case SCH_TABLES:
+  case SCH_VIEWS:
+  case SCH_TRIGGERS:
+    {
+      const char *dst_db_name= table->schema_select_lex->db;
+
+      DBUG_ASSERT(dst_db_name);
+
+      if (check_access(thd, SELECT_ACL, dst_db_name,
+                       &thd->col_access, FALSE, FALSE,
+                       is_schema_db(dst_db_name)))
+      {
+        return TRUE;
+      }
+
+      if (!thd->col_access && check_grant_db(thd, dst_db_name))
+      {
+        my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
+                 thd->security_ctx->priv_user,
+                 thd->security_ctx->priv_host,
+                 dst_db_name);
+        return TRUE;
+      }
+
+      return FALSE;
+    }
+
+  case SCH_COLUMNS:
+  case SCH_STATISTICS:
+    {
+      TABLE_LIST *dst_table=
+        (TABLE_LIST *) table->schema_select_lex->table_list.first;
+
+      DBUG_ASSERT(dst_table);
+
+      if (check_access(thd, SELECT_ACL | EXTRA_ACL,
+                       dst_table->db,
+                       &dst_table->grant.privilege,
+                       FALSE, FALSE,
+                       test(dst_table->schema_table)))
+      {
+        return FALSE;
+      }
+
+      return grant_option &&
+             check_grant(thd, SELECT_ACL, dst_table, 2, UINT_MAX, FALSE);
+    }
+
+  case SCH_OPEN_TABLES:
+  case SCH_VARIABLES:
+  case SCH_STATUS:
+  case SCH_PROCEDURES:
+  case SCH_CHARSETS:
+  case SCH_COLLATIONS:
+  case SCH_COLLATION_CHARACTER_SET_APPLICABILITY:
+  case SCH_USER_PRIVILEGES:
+  case SCH_SCHEMA_PRIVILEGES:
+  case SCH_TABLE_PRIVILEGES:
+  case SCH_COLUMN_PRIVILEGES:
+  case SCH_TABLE_CONSTRAINTS:
+  case SCH_KEY_COLUMN_USAGE:
+    break;
+  }
+
+  return FALSE;
+}
+
+
 /*
   Check the privilege for all used tables.
 
@@ -5438,7 +5516,7 @@ check_table_access(THD *thd, ulong want_
 {
   uint found=0;
   ulong found_access=0;
-#ifndef EMBEDDED_LIBRARY
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
   TABLE_LIST *org_tables= tables;
 #endif
   TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table();
@@ -5461,7 +5539,7 @@ check_table_access(THD *thd, ulong want_
       if (!no_errors)
         my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
                  sctx->priv_user, sctx->priv_host,
-                 information_schema_name.str);
+                 INFORMATION_SCHEMA_NAME.str);
       return TRUE;
     }
     /*
@@ -5469,7 +5547,16 @@ check_table_access(THD *thd, ulong want_
        Remove SHOW_VIEW_ACL, because it will be checked during making view
      */
     tables->grant.orig_want_privilege= (want_access & ~SHOW_VIEW_ACL);
-    if (tables->derived || tables->schema_table ||
+
+    if (tables->schema_table_reformed)
+    {
+      if (check_show_access(thd, tables))
+        goto deny;
+
+      continue;
+    }
+
+    if (tables->derived ||
         (tables->table && (int)tables->table->s->tmp_table) ||
         my_tz_check_n_skip_implicit_tables(&tables,
                                            thd->lex->time_zone_tables_used))
@@ -6287,7 +6374,7 @@ TABLE_LIST *st_select_lex::add_table_to_
   ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES);
   ptr->derived=	    table->sel;
   if (!ptr->derived && !my_strcasecmp(system_charset_info, ptr->db,
-                                      information_schema_name.str))
+                                      INFORMATION_SCHEMA_NAME.str))
   {
     ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, ptr->table_name);
     if (!schema_table ||
@@ -6295,7 +6382,7 @@ TABLE_LIST *st_select_lex::add_table_to_
          lex->orig_sql_command == SQLCOM_END))  // not a 'show' command
     {
       my_error(ER_UNKNOWN_TABLE, MYF(0),
-               ptr->table_name, information_schema_name.str);
+               ptr->table_name, INFORMATION_SCHEMA_NAME.str);
       DBUG_RETURN(0);
     }
     ptr->schema_table_name= ptr->table_name;

--- 1.510/sql/sql_select.cc	2007-04-20 18:36:15 -04:00
+++ 1.511/sql/sql_select.cc	2007-04-24 18:29:02 -04:00
@@ -742,6 +742,7 @@ JOIN::optimize()
   if (thd->lex->orig_sql_command != SQLCOM_SHOW_STATUS)
     thd->status_var.last_query_cost= 0.0;
 
+  thd_proc_info(thd, "optimizing");
   row_limit= ((select_distinct || order || group_list) ? HA_POS_ERROR :
 	      unit->select_limit_cnt);
   /* select_limit is used to decide if we are likely to scan the whole table */
@@ -857,7 +858,14 @@ JOIN::optimize()
         thd->fatal_error();
         error= res;
         DBUG_PRINT("error",("Error from opt_sum_query"));
-	DBUG_RETURN(1);
+        DBUG_RETURN(1);
+      }
+      if (res < 0)
+      {
+        DBUG_PRINT("info",("No matching min/max row"));
+        zero_result_cause= "No matching min/max row";
+        error=0;
+        DBUG_RETURN(0);
       }
       DBUG_PRINT("info",("Select tables optimized away"));
       zero_result_cause= "Select tables optimized away";
@@ -893,7 +901,7 @@ JOIN::optimize()
   sort_by_table= get_sort_by_table(order, group_list, select_lex->leaf_tables);
 
   /* Calculate how to do the join */
-  thd->proc_info= "statistics";
+  thd_proc_info(thd, "statistics");
   if (make_join_statistics(this, select_lex->leaf_tables, conds, &keyuse) ||
       thd->is_fatal_error)
   {
@@ -903,7 +911,7 @@ JOIN::optimize()
 
   /* Remove distinct if only const tables */
   select_distinct= select_distinct && (const_tables != tables);
-  thd->proc_info= "preparing";
+  thd_proc_info(thd, "preparing");
   if (result->initialize_tables(this))
   {
     DBUG_PRINT("error",("Error: initialize_tables() failed"));
@@ -1267,8 +1275,9 @@ JOIN::optimize()
         join_tab[const_tables].type != JT_REF_OR_NULL &&
         (order && simple_order || group_list && simple_group))
     {
-      if (add_ref_to_table_cond(thd,&join_tab[const_tables]))
+      if (add_ref_to_table_cond(thd,&join_tab[const_tables])) {
         DBUG_RETURN(1);
+      }
     }
     
     if (!(select_options & SELECT_BIG_RESULT) &&
@@ -1326,7 +1335,7 @@ JOIN::optimize()
   if (need_tmp)
   {
     DBUG_PRINT("info",("Creating tmp table"));
-    thd->proc_info="Creating tmp table";
+    thd_proc_info(thd, "Creating tmp table");
 
     init_items_ref_array();
 
@@ -1355,7 +1364,9 @@ JOIN::optimize()
 			   select_options,
                            tmp_rows_limit,
 			   (char *) "")))
+		{
       DBUG_RETURN(1);
+    }
 
     /*
       We don't have to store rows in temp table that doesn't match HAVING if:
@@ -1375,28 +1386,34 @@ JOIN::optimize()
     if (group_list && simple_group)
     {
       DBUG_PRINT("info",("Sorting for group"));
-      thd->proc_info="Sorting for group";
+      thd_proc_info(thd, "Sorting for group");
       if (create_sort_index(thd, this, group_list,
 			    HA_POS_ERROR, HA_POS_ERROR) ||
 	  alloc_group_fields(this, group_list) ||
           make_sum_func_list(all_fields, fields_list, 1) ||
           setup_sum_funcs(thd, sum_funcs))
-	DBUG_RETURN(1);
+      {
+        DBUG_RETURN(1);
+      }
       group_list=0;
     }
     else
     {
       if (make_sum_func_list(all_fields, fields_list, 0) ||
           setup_sum_funcs(thd, sum_funcs))
-	DBUG_RETURN(1);
+      {
+        DBUG_RETURN(1);
+      }
+
       if (!group_list && ! exec_tmp_table1->distinct && order && simple_order)
       {
-	DBUG_PRINT("info",("Sorting for order"));
-	thd->proc_info="Sorting for order";
-	if (create_sort_index(thd, this, order,
+        thd_proc_info(thd, "Sorting for order");
+        if (create_sort_index(thd, this, order,
                               HA_POS_ERROR, HA_POS_ERROR))
-	  DBUG_RETURN(1);
-	order=0;
+        {
+          DBUG_RETURN(1);
+        }
+        order=0;
       }
     }
     
@@ -1519,6 +1536,7 @@ JOIN::exec()
   int      tmp_error;
   DBUG_ENTER("JOIN::exec");
 
+  thd_proc_info(thd, "executing");
   error= 0;
   if (procedure)
   {
@@ -1658,7 +1676,7 @@ JOIN::exec()
     curr_tmp_table= exec_tmp_table1;
 
     /* Copy data to the temporary table */
-    thd->proc_info= "Copying to tmp table";
+    thd_proc_info(thd, "Copying to tmp table");
     DBUG_PRINT("info", ("%s", thd->proc_info));
     if ((tmp_error= do_select(curr_join, (List<Item> *) 0, curr_tmp_table, 0)))
     {
@@ -1781,7 +1799,7 @@ JOIN::exec()
       }
       if (curr_join->group_list)
       {
-	thd->proc_info= "Creating sort index";
+	thd_proc_info(thd, "Creating sort index");
 	if (curr_join->join_tab == join_tab && save_join_tab())
 	{
 	  DBUG_VOID_RETURN;
@@ -1795,7 +1813,7 @@ JOIN::exec()
         sortorder= curr_join->sortorder;
       }
       
-      thd->proc_info="Copying to group table";
+      thd_proc_info(thd, "Copying to group table");
       DBUG_PRINT("info", ("%s", thd->proc_info));
       tmp_error= -1;
       if (curr_join != this)
@@ -1851,7 +1869,7 @@ JOIN::exec()
     curr_join->join_free();			/* Free quick selects */
     if (curr_join->select_distinct && ! curr_join->group_list)
     {
-      thd->proc_info="Removing duplicates";
+      thd_proc_info(thd, "Removing duplicates");
       if (curr_join->tmp_having)
 	curr_join->tmp_having->update_used_tables();
       if (remove_duplicates(curr_join, curr_tmp_table,
@@ -1912,7 +1930,7 @@ JOIN::exec()
   if (curr_join->group_list || curr_join->order)
   {
     DBUG_PRINT("info",("Sorting for send_fields"));
-    thd->proc_info="Sorting result";
+    thd_proc_info(thd, "Sorting result");
     /* If we have already done the group, add HAVING to sorted table */
     if (curr_join->tmp_having && ! curr_join->group_list && 
 	! curr_join->sort_and_group)
@@ -2036,7 +2054,7 @@ JOIN::exec()
   }
   else
   {
-    thd->proc_info="Sending data";
+    thd_proc_info(thd, "Sending data");
     DBUG_PRINT("info", ("%s", thd->proc_info));
     result->send_fields((procedure ? curr_join->procedure_fields_list :
                          *curr_fields_list),
@@ -2184,7 +2202,7 @@ mysql_select(THD *thd, Item ***rref_poin
   {
     if (!(join= new JOIN(thd, fields, select_options, result)))
 	DBUG_RETURN(TRUE);
-    thd->proc_info="init";
+    thd_proc_info(thd, "init");
     thd->used_tables=0;                         // Updated by setup_fields
     if (err= join->prepare(rref_pointer_array, tables, wild_num,
                            conds, og_num, order, group, having, proc_param,
@@ -2229,8 +2247,9 @@ mysql_select(THD *thd, Item ***rref_poin
 err:
   if (free_join)
   {
-    thd->proc_info="end";
+    thd_proc_info(thd, "end");
     err|= select_lex->cleanup();
+    thd_proc_info(thd, "end");
     DBUG_RETURN(err || thd->net.report_error);
   }
   DBUG_RETURN(join->error);
@@ -9998,7 +10017,7 @@ free_tmp_table(THD *thd, TABLE *entry)
   DBUG_PRINT("enter",("table: %s",entry->alias));
 
   save_proc_info=thd->proc_info;
-  thd->proc_info="removing tmp table";
+  thd_proc_info(thd, "removing tmp table");
 
   if (entry->file)
   {
@@ -10026,7 +10045,7 @@ free_tmp_table(THD *thd, TABLE *entry)
     bitmap_clear_bit(&temp_pool, entry->temp_pool_slot);
 
   free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
-  thd->proc_info=save_proc_info;
+  thd_proc_info(thd, save_proc_info);
 
   DBUG_VOID_RETURN;
 }
@@ -10056,7 +10075,7 @@ bool create_myisam_from_heap(THD *thd, T
     DBUG_RETURN(1);				// End of memory
 
   save_proc_info=thd->proc_info;
-  thd->proc_info="converting HEAP to MyISAM";
+  thd_proc_info(thd, "converting HEAP to MyISAM");
 
   if (create_myisam_tmp_table(&new_table,param,
 			      thd->lex->select_lex.options | thd->options))
@@ -10109,8 +10128,8 @@ bool create_myisam_from_heap(THD *thd, T
   table->s= &table->share_not_to_be_used;
   table->file->change_table_ptr(table);
   if (save_proc_info)
-    thd->proc_info= (!strcmp(save_proc_info,"Copying to tmp table") ?
-                     "Copying to tmp table on disk" : save_proc_info);
+    thd_proc_info(thd, (!strcmp(save_proc_info,"Copying to tmp table") ?
+                  "Copying to tmp table on disk" : save_proc_info));
   DBUG_RETURN(0);
 
  err:
@@ -10122,7 +10141,7 @@ bool create_myisam_from_heap(THD *thd, T
   new_table.file->delete_table(new_table.s->table_name);
   delete new_table.file;
  err2:
-  thd->proc_info=save_proc_info;
+  thd_proc_info(thd, save_proc_info);
   DBUG_RETURN(1);
 }
 

--- 1.347/sql/sql_show.cc	2007-04-20 18:36:15 -04:00
+++ 1.348/sql/sql_show.cc	2007-04-24 18:29:02 -04:00
@@ -44,7 +44,7 @@ static void
 append_algorithm(TABLE_LIST *table, String *buff);
 static int
 view_store_create_info(THD *thd, TABLE_LIST *table, String *buff);
-static bool schema_table_store_record(THD *thd, TABLE *table);
+bool schema_table_store_record(THD *thd, TABLE *table);
 
 
 /***************************************************************************
@@ -1354,7 +1354,7 @@ void mysqld_list_processes(THD *thd,cons
 
 #if !defined(DONT_USE_THR_ALARM) && ! defined(SCO)
         if (pthread_kill(tmp->real_id,0))
-          tmp->proc_info="*** DEAD ***";        // This shouldn't happen
+          thd_proc_info(tmp, "*** DEAD ***");        // This shouldn't happen
 #endif
 #ifdef EXTRA_DEBUG
         thd_info->start_time= tmp->time_after_lock;
@@ -1497,6 +1497,12 @@ static bool show_status_array(THD *thd, 
           nr= (long) (thd->query_start() - server_start_time);
           end= int10_to_str(nr, buff, 10);
           break;
+#ifdef COMMUNITY_SERVER
+        case SHOW_FLUSHTIME:
+          nr= (long) (thd->query_start() - flush_status_time);
+          end= int10_to_str(nr, buff, 10);
+          break;
+#endif
         case SHOW_QUESTION:
           end= int10_to_str((long) thd->query_id, buff, 10);
           break;
@@ -1849,7 +1855,7 @@ typedef struct st_index_field_values
     1	                  error
 */
 
-static bool schema_table_store_record(THD *thd, TABLE *table)
+bool schema_table_store_record(THD *thd, TABLE *table)
 {
   int error;
   if ((error= table->file->write_row(table->record[0])))
@@ -4354,6 +4360,8 @@ ST_SCHEMA_TABLE schema_tables[]=
     get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0},
   {"OPEN_TABLES", open_tables_fields_info, create_schema_table,
    fill_open_tables, make_old_format, 0, -1, -1, 1},
+  {"PROFILING", query_profile_statistics_info, create_schema_table,
+    fill_query_profile_statistics_info, NULL, NULL, -1, -1, false},
   {"ROUTINES", proc_fields_info, create_schema_table, 
     fill_schema_proc, make_proc_old_format, 0, -1, -1, 0},
   {"SCHEMATA", schema_fields_info, create_schema_table,

--- 1.340/sql/sql_table.cc	2007-04-17 09:51:57 -04:00
+++ 1.341/sql/sql_table.cc	2007-04-24 18:29:03 -04:00
@@ -1770,7 +1770,7 @@ bool mysql_create_table(THD *thd,const c
     }
   }
 
-  thd->proc_info="creating table";
+  thd_proc_info(thd, "creating table");
   create_info->table_existed= 0;		// Mark that table is created
 
   if (thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE)
@@ -1801,7 +1801,7 @@ bool mysql_create_table(THD *thd,const c
 
 end:
   VOID(pthread_mutex_unlock(&LOCK_open));
-  thd->proc_info="After create";
+  thd_proc_info(thd, "After create");
   DBUG_RETURN(error);
 
 warn:
@@ -2931,7 +2931,7 @@ mysql_discard_or_import_tablespace(THD *
     ALTER TABLE
   */
 
-  thd->proc_info="discard_or_import_tablespace";
+  thd_proc_info(thd, "discard_or_import_tablespace");
 
   discard= test(tablespace_op == DISCARD_TABLESPACE);
 
@@ -2948,7 +2948,7 @@ mysql_discard_or_import_tablespace(THD *
 
   error=table->file->discard_or_import_tablespace(discard);
 
-  thd->proc_info="end";
+  thd_proc_info(thd, "end");
 
   if (error)
     goto err;
@@ -3065,7 +3065,7 @@ bool mysql_alter_table(THD *thd,char *ne
   frm_type_enum frm_type;
   DBUG_ENTER("mysql_alter_table");
 
-  thd->proc_info="init";
+  thd_proc_info(thd, "init");
   table_name=table_list->table_name;
   alias= (lower_case_table_names == 2) ? table_list->alias : table_name;
 
@@ -3202,7 +3202,7 @@ view_err:
     DBUG_RETURN(TRUE);
   }
   
-  thd->proc_info="setup";
+  thd_proc_info(thd, "setup");
   if (!(alter_info->flags & ~(ALTER_RENAME | ALTER_KEYS_ONOFF)) &&
       !table->s->tmp_table) // no need to touch frm
   {
@@ -3253,7 +3253,7 @@ view_err:
 
     if (!error && (new_name != table_name || new_db != db))
     {
-      thd->proc_info="rename";
+      thd_proc_info(thd, "rename");
       /* Then do a 'simple' rename of the table */
       if (!access(new_name_buff,F_OK))
       {
@@ -3718,7 +3718,7 @@ view_err:
   /* We don't want update TIMESTAMP fields during ALTER TABLE. */
   thd->count_cuted_fields= CHECK_FIELD_WARN;	// calc cuted fields
   thd->cuted_fields=0L;
-  thd->proc_info="copy to tmp table";
+  thd_proc_info(thd, "copy to tmp table");
   next_insert_id=thd->next_insert_id;		// Remember for logging
   copied=deleted=0;
   if (new_table && !new_table->s->is_view)
@@ -3802,7 +3802,7 @@ view_err:
     from the cache, free all locks, close the old table and remove it.
   */
 
-  thd->proc_info="rename result table";
+  thd_proc_info(thd, "rename result table");
   my_snprintf(old_name, sizeof(old_name), "%s2-%lx-%lx", tmp_file_prefix,
 	      current_pid, thd->thread_id);
   if (lower_case_table_names)
@@ -3913,7 +3913,7 @@ view_err:
     broadcast_refresh();
     goto err;
   }
-  thd->proc_info="end";
+  thd_proc_info(thd, "end");
   if (mysql_bin_log.is_open())
   {
     thd->clear_error();

--- 1.215/sql/sql_update.cc	2007-04-12 05:46:07 -04:00
+++ 1.216/sql/sql_update.cc	2007-04-24 18:29:03 -04:00
@@ -164,7 +164,7 @@ int mysql_update(THD *thd,
        mysql_handle_derived(thd->lex, &mysql_derived_filling)))
     DBUG_RETURN(1);
 
-  thd->proc_info="init";
+  thd_proc_info(thd, "init");
   table= table_list->table;
   table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
 
@@ -360,7 +360,7 @@ int mysql_update(THD *thd,
       else
         init_read_record_idx(&info, thd, table, 1, used_index);
 
-      thd->proc_info="Searching rows for update";
+      thd_proc_info(thd, "Searching rows for update");
       uint tmp_limit= limit;
 
       while (!(error=info.read_record(&info)) && !thd->killed)
@@ -425,7 +425,7 @@ int mysql_update(THD *thd,
   updated= found= 0;
   thd->count_cuted_fields= CHECK_FIELD_WARN;		/* calc cuted fields */
   thd->cuted_fields=0L;
-  thd->proc_info="Updating";
+  thd_proc_info(thd, "Updating");
   query_id=thd->query_id;
 
   transactional_table= table->file->has_transactions();
@@ -525,7 +525,7 @@ int mysql_update(THD *thd,
   end_read_record(&info);
   free_io_cache(table);				// If ORDER BY
   delete select;
-  thd->proc_info="end";
+  thd_proc_info(thd, "end");
   VOID(table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY));
 
   /*
@@ -973,7 +973,7 @@ int multi_update::prepare(List<Item> &no
 
   thd->count_cuted_fields= CHECK_FIELD_WARN;
   thd->cuted_fields=0L;
-  thd->proc_info="updating main table";
+  thd_proc_info(thd, "updating main table");
 
   tables_to_update= get_table_map(fields);
 
@@ -1538,11 +1538,11 @@ err2:
 bool multi_update::send_eof()
 {
   char buff[STRING_BUFFER_USUAL_SIZE];
-  thd->proc_info="updating reference tables";
+  thd_proc_info(thd, "updating reference tables");
 
   /* Does updates for the last n - 1 tables, returns 0 if ok */
   int local_error = (table_count) ? do_updates(0) : 0;
-  thd->proc_info= "end";
+  thd_proc_info(thd, "end");
 
   /* We must invalidate the query cache before binlog writing and
   ha_autocommit_... */

--- 1.514/sql/sql_yacc.yy	2007-04-02 04:50:17 -04:00
+++ 1.515/sql/sql_yacc.yy	2007-04-24 18:29:03 -04:00
@@ -500,6 +500,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
 %token  BIT_SYM
 %token  BIT_XOR
 %token  BLOB_SYM
+%token  BLOCK_SYM
 %token  BOOLEAN_SYM
 %token  BOOL_SYM
 %token  BOTH
@@ -540,10 +541,12 @@ bool my_yyoverflow(short **a, YYSTYPE **
 %token  CONSISTENT_SYM
 %token  CONSTRAINT
 %token  CONTAINS_SYM
+%token  CONTEXT_SYM
 %token  CONTINUE_SYM
 %token  CONVERT_SYM
 %token  CONVERT_TZ_SYM
 %token  COUNT_SYM
+%token  CPU_SYM
 %token  CREATE
 %token  CROSS
 %token  CUBE_SYM
@@ -617,6 +620,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
 %token  EXTRACT_SYM
 %token  FALSE_SYM
 %token  FAST_SYM
+%token  FAULTS_SYM
 %token  FETCH_SYM
 %token  FIELD_FUNC
 %token  FILE_SYM
@@ -686,6 +690,8 @@ bool my_yyoverflow(short **a, YYSTYPE **
 %token  INT_SYM
 %token  INVOKER_SYM
 %token  IN_SYM
+%token  IO_SYM
+%token  IPC_SYM
 %token  IS
 %token  ISOLATION
 %token  ISSUER_SYM
@@ -754,6 +760,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
 %token  MEDIUMINT
 %token  MEDIUMTEXT
 %token  MEDIUM_SYM
+%token  MEMORY_SYM
 %token  MERGE_SYM
 %token  MICROSECOND_SYM
 %token  MIGRATE_SYM
@@ -812,6 +819,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
 %token  OUTFILE
 %token  OUT_SYM
 %token  PACK_KEYS_SYM
+%token  PAGE_SYM
 %token  PARTIAL
 %token  PASSWORD
 %token  PARAM_MARKER
@@ -829,6 +837,8 @@ bool my_yyoverflow(short **a, YYSTYPE **
 %token  PROCEDURE
 %token  PROCESS
 %token  PROCESSLIST_SYM
+%token  PROFILE_SYM
+%token  PROFILES_SYM
 %token  PURGE
 %token  QUARTER_SYM
 %token  QUERY_SYM
@@ -899,6 +909,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
 %token  SMALLINT
 %token  SNAPSHOT_SYM
 %token  SOUNDS_SYM
+%token  SOURCE_SYM
 %token  SPATIAL_SYM
 %token  SPECIFIC_SYM
 %token  SQLEXCEPTION_SYM
@@ -929,6 +940,8 @@ bool my_yyoverflow(short **a, YYSTYPE **
 %token  SUM_SYM
 %token  SUPER_SYM
 %token  SUSPEND_SYM
+%token  SWAPS_SYM
+%token  SWITCHES_SYM
 %token  SYSDATE
 %token  TABLES
 %token  TABLESPACE
@@ -6835,6 +6848,64 @@ opt_table_sym:
 	/* empty */
 	| TABLE_SYM;
 
+opt_profile_defs:
+  /* empty */
+  | profile_defs
+
+profile_defs:
+  profile_def
+  | profile_defs ',' profile_def
+
+profile_def:
+  CPU_SYM
+    {
+      Lex->profile_options|= PROFILE_CPU;
+    }
+  | MEMORY_SYM
+    {
+      Lex->profile_options|= PROFILE_MEMORY;
+    }
+  | BLOCK_SYM IO_SYM
+    {
+      Lex->profile_options|= PROFILE_BLOCK_IO;
+    }
+  | CONTEXT_SYM SWITCHES_SYM
+    {
+      Lex->profile_options|= PROFILE_CONTEXT;
+    }
+  | PAGE_SYM FAULTS_SYM
+    {
+      Lex->profile_options|= PROFILE_PAGE_FAULTS;
+    }
+  | IPC_SYM
+    {
+      Lex->profile_options|= PROFILE_IPC;
+    }
+  | SWAPS_SYM
+    {
+      Lex->profile_options|= PROFILE_SWAPS;
+    }
+  | SOURCE_SYM
+    {
+      Lex->profile_options|= PROFILE_SOURCE;
+    }
+  | ALL
+    {
+      Lex->profile_options|= PROFILE_ALL;
+    }
+  ;
+
+opt_profile_args:
+  /* empty */
+    {
+      Lex->profile_query_id= 0;
+    }
+  | FOR_SYM QUERY_SYM NUM
+    {
+      Lex->profile_query_id= atoi($3.str);
+    }
+  ;
+
 /* Show things */
 
 show:	SHOW
@@ -6970,6 +7041,10 @@ show_param:
           { Lex->sql_command = SQLCOM_SHOW_WARNS;}
         | ERRORS opt_limit_clause_init
           { Lex->sql_command = SQLCOM_SHOW_ERRORS;}
+        | PROFILES_SYM
+          { Lex->sql_command = SQLCOM_SHOW_PROFILES; }
+        | PROFILE_SYM opt_profile_defs opt_profile_args opt_limit_clause_init
+          { Lex->sql_command = SQLCOM_SHOW_PROFILE; }
         | opt_var_type STATUS_SYM wild_and_where
           {
             LEX *lex= Lex;
@@ -8063,6 +8138,7 @@ keyword_sp:
 	| BERKELEY_DB_SYM	{}
 	| BINLOG_SYM		{}
 	| BIT_SYM		{}
+	| BLOCK_SYM             {}
 	| BOOL_SYM		{}
 	| BOOLEAN_SYM		{}
 	| BTREE_SYM		{}
@@ -8080,6 +8156,8 @@ keyword_sp:
 	| CONCURRENT		{}
 	| CONNECTION_SYM	{}
 	| CONSISTENT_SYM	{}
+	| CONTEXT_SYM           {}
+	| CPU_SYM               {}
 	| CUBE_SYM		{}
 	| DATA_SYM		{}
 	| DATETIME		{}
@@ -8102,6 +8180,7 @@ keyword_sp:
         | EXPANSION_SYM         {}
 	| EXTENDED_SYM		{}
 	| FAST_SYM		{}
+	| FAULTS_SYM            {}
 	| FOUND_SYM		{}
 	| DISABLE_SYM		{}
 	| ENABLE_SYM		{}
@@ -8126,6 +8205,8 @@ keyword_sp:
 	| ISSUER_SYM		{}
 	| INNOBASE_SYM		{}
 	| INSERT_METHOD		{}
+	| IO_SYM                {}
+	| IPC_SYM               {}
 	| RELAY_THREAD		{}
 	| LAST_SYM		{}
 	| LEAVES                {}
@@ -8155,6 +8236,7 @@ keyword_sp:
 	| MAX_UPDATES_PER_HOUR	{}
 	| MAX_USER_CONNECTIONS_SYM {}
 	| MEDIUM_SYM		{}
+	| MEMORY_SYM            {}
 	| MERGE_SYM		{}
 	| MICROSECOND_SYM	{}
         | MIGRATE_SYM           {}
@@ -8181,6 +8263,7 @@ keyword_sp:
 	| ONE_SHOT_SYM		{}
         | ONE_SYM               {}
 	| PACK_KEYS_SYM		{}
+	| PAGE_SYM              {}
 	| PARTIAL		{}
 	| PASSWORD		{}
         | PHASE_SYM             {}
@@ -8190,6 +8273,8 @@ keyword_sp:
         | PRIVILEGES            {}
 	| PROCESS		{}
 	| PROCESSLIST_SYM	{}
+	| PROFILE_SYM           {}
+	| PROFILES_SYM          {}
 	| QUARTER_SYM		{}
 	| QUERY_SYM		{}
 	| QUICK			{}
@@ -8223,6 +8308,7 @@ keyword_sp:
 	| SHUTDOWN		{}
 	| SNAPSHOT_SYM		{}
 	| SOUNDS_SYM		{}
+	| SOURCE_SYM            {}
 	| SQL_CACHE_SYM		{}
 	| SQL_BUFFER_RESULT	{}
 	| SQL_NO_CACHE_SYM	{}
@@ -8234,6 +8320,8 @@ keyword_sp:
 	| SUBJECT_SYM		{}
 	| SUPER_SYM		{}
         | SUSPEND_SYM           {}
+        | SWAPS_SYM             {}
+	| SWITCHES_SYM          {}
         | TABLES                {}
 	| TABLESPACE		{}
 	| TEMPORARY		{}

--- 1.140/sql/table.h	2007-04-03 09:05:22 -04:00
+++ 1.141/sql/table.h	2007-04-24 18:29:03 -04:00
@@ -55,7 +55,8 @@ typedef struct st_grant_info
   ulong orig_want_privilege;
 } GRANT_INFO;
 
-enum tmp_table_type {NO_TMP_TABLE=0, TMP_TABLE=1, TRANSACTIONAL_TMP_TABLE=2,
+enum tmp_table_type {NO_TMP_TABLE=0,
+                     NON_TRANSACTIONAL_TMP_TABLE=1, TRANSACTIONAL_TMP_TABLE=2,
                      SYSTEM_TMP_TABLE=3};
 
 enum frm_type_enum
@@ -273,6 +274,11 @@ struct st_table {
   my_bool no_cache;
   /* To signal that we should reset query_id for tables and cols */
   my_bool clear_query_id;
+  /*
+    To indicate that a non-null value of the auto_increment field
+    was provided by the user or retrieved from the current record.
+    Used only in the MODE_NO_AUTO_VALUE_ON_ZERO mode.
+  */
   my_bool auto_increment_field_not_null;
   my_bool insert_or_update;             /* Can be used by the handler */
   my_bool alias_name_used;		/* true if table_name is alias */

--- 1.172/support-files/mysql.spec.sh	2007-04-06 22:14:27 -04:00
+++ 1.173/support-files/mysql.spec.sh	2007-04-25 08:14:44 -04:00
@@ -481,6 +481,11 @@ chmod -R og-rw $mysql_datadir/mysql
 # Allow safe_mysqld to start mysqld and print a message before we exit
 sleep 2
 
+#echo "Thank you for installing the MySQL Community Server! For Production
+#systems, we recommend MySQL Enterprise, which contains enterprise-ready
+#software, intelligent advisory services, and full production support with
+#scheduled service packs and more.  Visit www.mysql.com/enterprise for more
+#information." 
 %post ndb-storage
 mysql_clusterdir=/var/lib/mysql-cluster
 

--- 1.109/sql/sql_view.cc	2007-04-20 18:36:15 -04:00
+++ 1.110/sql/sql_view.cc	2007-04-24 18:29:03 -04:00
@@ -603,7 +603,7 @@ bool mysql_create_view(THD *thd, TABLE_L
   DBUG_RETURN(0);
 
 err:
-  thd->proc_info= "end";
+  thd_proc_info(thd, "end");
   lex->link_first_table_back(view, link_to_local);
   unit->cleanup();
   DBUG_RETURN(res || thd->net.report_error);

--- 1.85/sql/ha_archive.cc	2007-04-12 05:46:05 -04:00
+++ 1.86/sql/ha_archive.cc	2007-04-24 18:28:59 -04:00
@@ -1209,7 +1209,7 @@ int ha_archive::check(THD* thd, HA_CHECK
   ha_rows count= share->rows_recorded;
   DBUG_ENTER("ha_archive::check");
 
-  thd->proc_info= "Checking table";
+  thd_proc_info(thd, "Checking table");
   /* Flush any waiting data */
   gzflush(share->archive_write, Z_SYNC_FLUSH);
 
@@ -1233,7 +1233,7 @@ int ha_archive::check(THD* thd, HA_CHECK
 
   my_free((char*)buf, MYF(0));
 
-  thd->proc_info= old_proc_info;
+  thd_proc_info(thd, old_proc_info);
 
   if ((rc && rc != HA_ERR_END_OF_FILE) || count)  
   {

--- 1.123/mysql-test/r/information_schema.result	2007-04-03 13:26:17 -04:00
+++ 1.124/mysql-test/r/information_schema.result	2007-04-24 18:28:59 -04:00
@@ -688,7 +688,7 @@ Warnings:
 Warning	1356	View 'test.v2' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
 show create table v3;
 View	Create View
-v3	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select `test`.`sub1`(1) AS `c`
+v3	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select `sub1`(1) AS `c`
 Warnings:
 Warning	1356	View 'test.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
 drop view v2;

--- 1.11/mysql-test/r/information_schema_db.result	2007-04-03 09:05:18 -04:00
+++ 1.12/mysql-test/r/information_schema_db.result	2007-04-24 18:28:59 -04:00
@@ -107,16 +107,82 @@ use testdb_1;
 create table t1 (f1 char(4));
 create view v1 as select f1 from t1;
 grant insert on v1 to testdb_2@localhost;
+create view v5 as select f1 from t1;
+grant show view on v5 to testdb_2@localhost;
+create definer=`no_such_user`@`no_such_host` view v6 as select f1 from t1;
+ERROR 42000: Access denied; you need the SUPER privilege for this operation
+use testdb_1;
+create view v6 as select f1 from t1;
+grant show view on v6 to testdb_2@localhost;
+create table t2 (f1 char(4));
+create definer=`no_such_user`@`no_such_host` view v7 as select * from t2;
+Warnings:
+Note	1449	There is no 'no_such_user'@'no_such_host' registered
+show fields from testdb_1.v6;
+Field	Type	Null	Key	Default	Extra
+f1	char(4)	YES		NULL	
+show create view testdb_1.v6;
+View	Create View
+v6	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v6` AS select `t1`.`f1` AS `f1` from `t1`
+show create view testdb_1.v7;
+View	Create View
+v7	CREATE ALGORITHM=UNDEFINED DEFINER=`no_such_user`@`no_such_host` SQL SECURITY DEFINER VIEW `v7` AS select `testdb_1`.`t2`.`f1` AS `f1` from `t2`
+Warnings:
+Warning	1356	View 'testdb_1.v7' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+show fields from testdb_1.v7;
+Field	Type	Null	Key	Default	Extra
+f1	null	YES		NULL	
+Warnings:
+Note	1449	There is no 'no_such_user'@'no_such_host' registered
 create table t3 (f1 char(4), f2 char(4));
 create view v3 as select f1,f2 from t3;
 grant insert(f1), insert(f2) on v3 to testdb_2@localhost;
 create view v2 as select f1 from testdb_1.v1;
 create view v4 as select f1,f2 from testdb_1.v3;
+show fields from testdb_1.v5;
+Field	Type	Null	Key	Default	Extra
+f1	char(4)	YES		NULL	
+show create view testdb_1.v5;
+View	Create View
+v5	CREATE ALGORITHM=UNDEFINED DEFINER=`testdb_1`@`localhost` SQL SECURITY DEFINER VIEW `testdb_1`.`v5` AS select `testdb_1`.`t1`.`f1` AS `f1` from `testdb_1`.`t1`
+show fields from testdb_1.v6;
+Field	Type	Null	Key	Default	Extra
+f1	char(4)	YES		NULL	
+show create view testdb_1.v6;
+View	Create View
+v6	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `testdb_1`.`v6` AS select `testdb_1`.`t1`.`f1` AS `f1` from `testdb_1`.`t1`
+show fields from testdb_1.v7;
+Field	Type	Null	Key	Default	Extra
+f1	null	YES		NULL	
+Warnings:
+Note	1449	There is no 'no_such_user'@'no_such_host' registered
+show create view testdb_1.v7;
+View	Create View
+v7	CREATE ALGORITHM=UNDEFINED DEFINER=`no_such_user`@`no_such_host` SQL SECURITY DEFINER VIEW `v7` AS select `testdb_1`.`t2`.`f1` AS `f1` from `t2`
+Warnings:
+Warning	1356	View 'testdb_1.v7' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
 revoke insert(f1) on v3 from testdb_2@localhost;
+revoke show view on v5 from testdb_2@localhost;
+use testdb_1;
+revoke show view on v6 from testdb_2@localhost;
+show fields from testdb_1.v5;
+ERROR 42000: SELECT command denied to user 'testdb_2'@'localhost' for table 'v5'
+show create view testdb_1.v5;
+ERROR 42000: SELECT command denied to user 'testdb_2'@'localhost' for table 'v5'
+show fields from testdb_1.v6;
+ERROR 42000: SELECT command denied to user 'testdb_2'@'localhost' for table 'v6'
+show create view testdb_1.v6;
+ERROR 42000: SELECT command denied to user 'testdb_2'@'localhost' for table 'v6'
+show fields from testdb_1.v7;
+ERROR 42000: SELECT command denied to user 'testdb_2'@'localhost' for table 'v7'
+show create view testdb_1.v7;
+ERROR 42000: SELECT command denied to user 'testdb_2'@'localhost' for table 'v7'
 show create view v4;
 ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
 show fields from v4;
-ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+Field	Type	Null	Key	Default	Extra
+f1	null	YES		NULL	
+f2	char(4)	YES		NULL	
 show fields from v2;
 Field	Type	Null	Key	Default	Extra
 f1	char(4)	YES		NULL	
@@ -141,7 +207,8 @@ where a.table_name = 'testdb_1.v1';
 view_definition
 select * from v2;
 ERROR HY000: View 'test.v2' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
-drop view testdb_1.v1,v2, testdb_1.v3, v4;
+use test;
+drop view testdb_1.v1, v2, testdb_1.v3, v4;
 drop database testdb_1;
 drop user testdb_1@localhost;
 drop user testdb_2@localhost;

--- 1.21/ndb/src/ndbapi/DictCache.cpp	2007-02-22 10:03:02 -05:00
+++ 1.22/ndb/src/ndbapi/DictCache.cpp	2007-04-24 18:28:59 -04:00
@@ -141,7 +141,7 @@ void GlobalDictCache::printCache()
 }
 
 NdbTableImpl *
-GlobalDictCache::get(const char * name)
+GlobalDictCache::get(const char * name, int *error)
 {
   DBUG_ENTER("GlobalDictCache::get");
   DBUG_PRINT("enter", ("name: %s", name));
@@ -151,6 +151,11 @@ GlobalDictCache::get(const char * name)
   versions = m_tableHash.getData(name, len);
   if(versions == 0){
     versions = new Vector<TableVersion>(2);
+    if (versions == NULL)
+    {
+      *error = -1;
+      DBUG_RETURN(0);
+    }
     m_tableHash.insertKey(name, len, 0, versions);
   }
 
@@ -180,7 +185,11 @@ GlobalDictCache::get(const char * name)
   tmp.m_impl = 0;
   tmp.m_status = RETREIVING;
   tmp.m_refCount = 1; // The one retreiving it
-  versions->push_back(tmp);
+  if (versions->push_back(tmp))
+  {
+    *error = -1;
+    DBUG_RETURN(0);
+  }
   DBUG_RETURN(0);
 }
 

--- 1.308/sql/ha_ndbcluster.cc	2007-04-17 09:51:56 -04:00
+++ 1.309/sql/ha_ndbcluster.cc	2007-04-24 18:28:59 -04:00
@@ -5970,14 +5970,14 @@ ha_ndbcluster::register_query_cache_tabl
 
   if (!is_autocommit)
   {
-    DBUG_PRINT("exit", ("Can't register table during transaction"))
+    DBUG_PRINT("exit", ("Can't register table during transaction"));
     DBUG_RETURN(FALSE);
   }
 
   if (ndb_get_commitcount(thd, m_dbname, m_tabname, &commit_count))
   {
     *engine_data= 0;
-    DBUG_PRINT("exit", ("Error, could not get commitcount"))
+    DBUG_PRINT("exit", ("Error, could not get commitcount"));
     DBUG_RETURN(FALSE);
   }
   *engine_data= commit_count;

--- 1.183/sql/set_var.cc	2007-04-20 04:35:22 -04:00
+++ 1.184/sql/set_var.cc	2007-04-25 08:14:43 -04:00
@@ -544,6 +544,12 @@ static sys_var_thd_bit	sys_unique_checks
 					  set_option_bit,
 					  OPTION_RELAXED_UNIQUE_CHECKS,
 					  1);
+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+static sys_var_thd_bit  sys_profiling("profiling", NULL, set_option_bit,
+                                      ulonglong(OPTION_PROFILING));
+static sys_var_thd_ulong	sys_profiling_history_size("profiling_history_size",
+					      &SV::profiling_history_size);
+#endif
 
 /* Local state variables */
 
@@ -700,6 +706,10 @@ sys_var *sys_variables[]=
   &sys_optimizer_prune_level,
   &sys_optimizer_search_depth,
   &sys_preload_buff_size,
+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+  &sys_profiling,
+  &sys_profiling_history_size,
+#endif
   &sys_pseudo_thread_id,
   &sys_query_alloc_block_size,
   &sys_query_cache_size,
@@ -1011,6 +1021,10 @@ struct show_var_st init_vars[]= {
   {"pid_file",                (char*) pidfile_name,                 SHOW_CHAR},
   {"port",                    (char*) &mysqld_port,                  SHOW_INT},
   {sys_preload_buff_size.name, (char*) &sys_preload_buff_size,      SHOW_SYS},
+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+  {sys_profiling.name,        (char*) &sys_profiling,               SHOW_SYS},
+  {sys_profiling_history_size.name, (char*) &sys_profiling_history_size, SHOW_SYS},
+#endif
   {"protocol_version",        (char*) &protocol_version,            SHOW_INT},
   {sys_query_alloc_block_size.name, (char*) &sys_query_alloc_block_size,
    SHOW_SYS},
@@ -2881,7 +2895,7 @@ static bool set_option_autocommit(THD *t
     if ((org_options & OPTION_NOT_AUTOCOMMIT))
     {
       /* We changed to auto_commit mode */
-      thd->options&= ~(ulong) OPTION_BEGIN;
+      thd->options&= ~OPTION_BEGIN;
       thd->no_trans_update.all= FALSE;
       thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
       if (ha_commit(thd))

--- 1.242/sql/sp_head.cc	2007-04-12 05:46:07 -04:00
+++ 1.243/sql/sp_head.cc	2007-04-24 18:29:01 -04:00
@@ -2408,9 +2408,9 @@ sp_lex_keeper::reset_lex_and_exec_core(T
 
   m_lex->unit.cleanup();
 
-  thd->proc_info="closing tables";
+  thd_proc_info(thd, "closing tables");
   close_thread_tables(thd);
-  thd->proc_info= 0;
+  thd_proc_info(thd, 0);
 
   if (m_lex->query_tables_own_last)
   {

--- 1.198/sql/sql_prepare.cc	2007-03-28 13:46:37 -04:00
+++ 1.199/sql/sql_prepare.cc	2007-04-24 18:29:02 -04:00
@@ -2231,6 +2231,9 @@ void mysql_stmt_execute(THD *thd, char *
   if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_execute")))
     DBUG_VOID_RETURN;
 
+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+  thd->profiling.set_query_source(stmt->query, stmt->query_length);
+#endif
   DBUG_PRINT("exec_query", ("%s", stmt->query));
   DBUG_PRINT("info",("stmt: %p", stmt));
 
Thread
bk commit into 5.0 tree (cmiller:1.2438)Chad MILLER25 Apr