List:Internals« Previous MessageNext Message »
From:monty Date:October 7 2005 8:42pm
Subject:bk commit into 5.0 tree (monty:1.2030)
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of monty. When monty 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
  1.2030 05/10/07 23:41:57 monty@stripped +1 -0
  Merge bk-internal.mysql.com:/home/bk/mysql-5.0
  into  mysql.com:/my/mysql-5.0

  sql/sql_parse.cc
    1.476 05/10/07 23:41:51 monty@stripped +0 -0
    Auto merged

# 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:	monty
# Host:	hasky.mysql.fi
# Root:	/my/mysql-5.0/RESYNC

--- 1.475/sql/sql_parse.cc	2005-09-13 12:52:42 +03:00
+++ 1.476/sql/sql_parse.cc	2005-10-07 23:41:51 +03:00
@@ -25,6 +25,10 @@
 #include "ha_innodb.h"
 #endif
 
+#ifdef HAVE_NDBCLUSTER_DB
+#include "ha_ndbcluster.h"
+#endif
+
 #include "sp_head.h"
 #include "sp.h"
 #include "sp_cache.h"
@@ -130,6 +134,12 @@
     my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
     DBUG_RETURN(1);
   }
+  if (thd->transaction.xid_state.xa_state != XA_NOTR)
+  {
+    my_error(ER_XAER_RMFAIL, MYF(0),
+             xa_state_names[thd->transaction.xid_state.xa_state]);
+    DBUG_RETURN(1);
+  }
   if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN |
 		      OPTION_TABLE_LOCK))
   {
@@ -179,10 +189,7 @@
 */
 inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables)
 {
-  return (table_rules_on && tables && !tables_ok(thd,tables) &&
-          ((thd->lex->sql_command != SQLCOM_DELETE_MULTI) ||
-           !tables_ok(thd,
-		      (TABLE_LIST *)thd->lex->auxilliary_table_list.first)));
+  return table_rules_on && tables && !tables_ok(thd,tables);
 }
 #endif
 
@@ -245,7 +252,7 @@
 
   SYNOPSIS
     check_user()
-    thd          thread handle, thd->{host,user,ip} are used
+    thd          thread handle, thd->security_ctx->{host,user,ip} are used
     command      originator of the check: now check_user is called
                  during connect and change user procedures; used for 
                  logging.
@@ -260,8 +267,8 @@
     are 'IN'.
 
   RETURN VALUE
-    0  OK; thd->user, thd->master_access, thd->priv_user, thd->db and
-       thd->db_access are updated; OK is sent to client;
+    0  OK; thd->security_ctx->user/master_access/priv_user/db_access and
+       thd->db are updated; OK is sent to client;
    -1  access denied or handshake error; error is sent to client;
    >0  error, not sent to client
 */
@@ -273,7 +280,7 @@
   DBUG_ENTER("check_user");
   
 #ifdef NO_EMBEDDED_ACCESS_CHECKS
-  thd->master_access= GLOBAL_ACLS;			// Full rights
+  thd->main_security_ctx.master_access= GLOBAL_ACLS;       // Full rights
   /* Change database if necessary */
   if (db && db[0])
   {
@@ -340,15 +347,17 @@
     if (opt_secure_auth_local)
     {
       net_printf_error(thd, ER_SERVER_IS_IN_SECURE_AUTH_MODE,
-                       thd->user, thd->host_or_ip);
+                       thd->main_security_ctx.user,
+                       thd->main_security_ctx.host_or_ip);
       mysql_log.write(thd, COM_CONNECT, ER(ER_SERVER_IS_IN_SECURE_AUTH_MODE),
-                      thd->user, thd->host_or_ip);
+                      thd->main_security_ctx.user,
+                      thd->main_security_ctx.host_or_ip);
       DBUG_RETURN(-1);
     }
     /* We have to read very specific packet size */
     if (send_old_password_request(thd) ||
         my_net_read(net) != SCRAMBLE_LENGTH_323 + 1)
-    {                                               
+    {
       inc_host_errors(&thd->remote.sin_addr);
       DBUG_RETURN(ER_HANDSHAKE_ERROR);
     }
@@ -360,22 +369,27 @@
   /* here res is always >= 0 */
   if (res == 0)
   {
-    if (!(thd->master_access & NO_ACCESS)) // authentication is OK 
+    if (!(thd->main_security_ctx.master_access &
+          NO_ACCESS)) // authentication is OK
     {
       DBUG_PRINT("info",
                  ("Capabilities: %d  packet_length: %ld  Host: '%s'  "
                   "Login user: '%s' Priv_user: '%s'  Using password: %s "
                   "Access: %u  db: '%s'",
-                  thd->client_capabilities, thd->max_client_packet_length,
-                  thd->host_or_ip, thd->user, thd->priv_user,
+                  thd->client_capabilities,
+                  thd->max_client_packet_length,
+                  thd->main_security_ctx.host_or_ip,
+                  thd->main_security_ctx.user,
+                  thd->main_security_ctx.priv_user,
                   passwd_len ? "yes": "no",
-                  thd->master_access, thd->db ? thd->db : "*none*"));
+                  thd->main_security_ctx.master_access,
+                  (thd->db ? thd->db : "*none*")));
 
       if (check_count)
       {
         VOID(pthread_mutex_lock(&LOCK_thread_count));
         bool count_ok= thread_count <= max_connections + delayed_insert_threads
-                       || (thd->master_access & SUPER_ACL);
+                       || (thd->main_security_ctx.master_access & SUPER_ACL);
         VOID(pthread_mutex_unlock(&LOCK_thread_count));
         if (!count_ok)
         {                                         // too many connections
@@ -385,11 +399,13 @@
       }
 
       /* Why logging is performed before all checks've passed? */
-      mysql_log.write(thd,command,
-                      (thd->priv_user == thd->user ?
+      mysql_log.write(thd, command,
+                      (thd->main_security_ctx.priv_user ==
+                       thd->main_security_ctx.user ?
                        (char*) "%s@%s on %s" :
                        (char*) "%s@%s as anonymous on %s"),
-                      thd->user, thd->host_or_ip,
+                      thd->main_security_ctx.user,
+                      thd->main_security_ctx.host_or_ip,
                       db ? db : (char*) "");
 
       /*
@@ -397,14 +413,16 @@
         set to 0 here because we don't have an active database yet (and we
         may not have an active database to set.
       */
-      thd->db_access=0;
+      thd->main_security_ctx.db_access=0;
 
       /* Don't allow user to connect if he has done too many queries */
       if ((ur.questions || ur.updates || ur.conn_per_hour || ur.user_conn ||
 	   max_user_connections) &&
 	  get_or_create_user_conn(thd,
-            opt_old_style_user_limits ? thd->user : thd->priv_user,
-            opt_old_style_user_limits ? thd->host_or_ip : thd->priv_host,
+            (opt_old_style_user_limits ? thd->main_security_ctx.user :
+             thd->main_security_ctx.priv_user),
+            (opt_old_style_user_limits ? thd->main_security_ctx.host_or_ip :
+             thd->main_security_ctx.priv_host),
             &ur))
 	DBUG_RETURN(-1);
       if (thd->user_connect &&
@@ -439,12 +457,12 @@
     DBUG_RETURN(-1);
   }
   net_printf_error(thd, ER_ACCESS_DENIED_ERROR,
-                   thd->user,
-                   thd->host_or_ip,
+                   thd->main_security_ctx.user,
+                   thd->main_security_ctx.host_or_ip,
                    passwd_len ? ER(ER_YES) : ER(ER_NO));
   mysql_log.write(thd, COM_CONNECT, ER(ER_ACCESS_DENIED_ERROR),
-                  thd->user,
-                  thd->host_or_ip,
+                  thd->main_security_ctx.user,
+                  thd->main_security_ctx.host_or_ip,
                   passwd_len ? ER(ER_YES) : ER(ER_NO));
   DBUG_RETURN(-1);
 #endif /* NO_EMBEDDED_ACCESS_CHECKS */
@@ -768,41 +786,45 @@
   DBUG_PRINT("info",
              ("New connection received on %s", vio_description(net->vio)));
 
-  if (!thd->host)                           // If TCP/IP connection
+  if (!thd->main_security_ctx.host)         // If TCP/IP connection
   {
     char ip[30];
 
     if (vio_peer_addr(net->vio, ip, &thd->peer_port))
       return (ER_BAD_HOST_ERROR);
-    if (!(thd->ip= my_strdup(ip,MYF(0))))
+    if (!(thd->main_security_ctx.ip= my_strdup(ip,MYF(0))))
       return (ER_OUT_OF_RESOURCES);
-    thd->host_or_ip= thd->ip;
+    thd->main_security_ctx.host_or_ip= thd->main_security_ctx.ip;
     vio_in_addr(net->vio,&thd->remote.sin_addr);
     if (!(specialflag & SPECIAL_NO_RESOLVE))
     {
       vio_in_addr(net->vio,&thd->remote.sin_addr);
-      thd->host=ip_to_hostname(&thd->remote.sin_addr,&connect_errors);
+      thd->main_security_ctx.host=
+        ip_to_hostname(&thd->remote.sin_addr, &connect_errors);
       /* Cut very long hostnames to avoid possible overflows */
-      if (thd->host)
+      if (thd->main_security_ctx.host)
       {
-        if (thd->host != my_localhost)
-          thd->host[min(strlen(thd->host), HOSTNAME_LENGTH)]= 0;
-        thd->host_or_ip= thd->host;
+        if (thd->main_security_ctx.host != my_localhost)
+          thd->main_security_ctx.host[min(strlen(thd->main_security_ctx.host),
+                                          HOSTNAME_LENGTH)]= 0;
+        thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host;
       }
       if (connect_errors > max_connect_errors)
         return(ER_HOST_IS_BLOCKED);
     }
     DBUG_PRINT("info",("Host: %s  ip: %s",
-		       thd->host ? thd->host : "unknown host",
-		       thd->ip ? thd->ip : "unknown ip"));
-    if (acl_check_host(thd->host,thd->ip))
+		       (thd->main_security_ctx.host ?
+                        thd->main_security_ctx.host : "unknown host"),
+		       (thd->main_security_ctx.ip ?
+                        thd->main_security_ctx.ip : "unknown ip")));
+    if (acl_check_host(thd->main_security_ctx.host, thd->main_security_ctx.ip))
       return(ER_HOST_NOT_PRIVILEGED);
   }
   else /* Hostname given means that the connection was on a socket */
   {
-    DBUG_PRINT("info",("Host: %s",thd->host));
-    thd->host_or_ip= thd->host;
-    thd->ip= 0;
+    DBUG_PRINT("info",("Host: %s", thd->main_security_ctx.host));
+    thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host;
+    thd->main_security_ctx.ip= 0;
     /* Reset sin_addr */
     bzero((char*) &thd->remote, sizeof(thd->remote));
   }
@@ -985,9 +1007,9 @@
                              thd->charset(), &dummy_errors)]= '\0';
   user= user_buff;
 
-  if (thd->user)
-    x_free(thd->user);
-  if (!(thd->user= my_strdup(user, MYF(0))))
+  if (thd->main_security_ctx.user)
+    x_free(thd->main_security_ctx.user);
+  if (!(thd->main_security_ctx.user= my_strdup(user, MYF(0))))
     return (ER_OUT_OF_RESOURCES);
   return check_user(thd, COM_CONNECT, passwd, passwd_len, db, TRUE);
 }
@@ -1075,13 +1097,14 @@
   {
     int error;
     NET *net= &thd->net;
+    Security_context *sctx= thd->security_ctx;
     thd->thread_stack= (char*) &thd;
     net->no_send_error= 0;
 
     if ((error=check_connection(thd)))
     {						// Wrong permissions
       if (error > 0)
-	net_printf_error(thd, error, thd->host_or_ip);
+	net_printf_error(thd, error, sctx->host_or_ip);
 #ifdef __NT__
       if (vio_type(net->vio) == VIO_TYPE_NAMEDPIPE)
 	my_sleep(1000);				/* must wait after eof() */
@@ -1090,7 +1113,7 @@
       goto end_thread;
     }
 #ifdef __NETWARE__
-    netware_reg_user(thd->ip, thd->user, "MySQL");
+    netware_reg_user(sctx->ip, sctx->user, "MySQL");
 #endif
     if (thd->variables.max_join_size == HA_POS_ERROR)
       thd->options |= OPTION_BIG_SELECTS;
@@ -1103,7 +1126,7 @@
     thd->set_time();
     thd->init_for_queries();
 
-    if (sys_init_connect.value_length && !(thd->master_access & SUPER_ACL))
+    if (sys_init_connect.value_length && !(sctx->master_access & SUPER_ACL))
     {
       execute_init_command(thd, &sys_init_connect, &LOCK_sys_init_connect);
       if (thd->query_error)
@@ -1127,8 +1150,8 @@
       if (!thd->killed && thd->variables.log_warnings > 1)
 	sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION),
                           thd->thread_id,(thd->db ? thd->db : "unconnected"),
-                          thd->user ? thd->user : "unauthenticated",
-                          thd->host_or_ip,
+                          sctx->user ? sctx->user : "unauthenticated",
+                          sctx->host_or_ip,
                           (net->last_errno ? ER(net->last_errno) :
                            ER(ER_UNKNOWN_ERROR)));
       net_send_error(thd, net->last_errno, NullS);
@@ -1191,7 +1214,8 @@
 
   thd->proc_info=0;
   thd->version=refresh_version;
-  thd->priv_user=thd->user=(char*) my_strdup("boot", MYF(MY_WME));
+  thd->security_ctx->priv_user=
+    thd->security_ctx->user= (char*) my_strdup("boot", MYF(MY_WME));
 
   buff= (char*) thd->net.buff;
   thd->init_for_queries();
@@ -1350,6 +1374,12 @@
     my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
     DBUG_RETURN(1);
   }
+  if (thd->transaction.xid_state.xa_state != XA_NOTR)
+  {
+    my_error(ER_XAER_RMFAIL, MYF(0),
+             xa_state_names[thd->transaction.xid_state.xa_state]);
+    DBUG_RETURN(1);
+  }
   switch (completion) {
   case COMMIT:
     /*
@@ -1586,17 +1616,14 @@
     db= db_buff;
 
     /* Save user and privileges */
-    uint save_master_access= thd->master_access;
-    uint save_db_access= thd->db_access;
     uint save_db_length= thd->db_length;
-    char *save_user= thd->user;
-    char *save_priv_user= thd->priv_user;
     char *save_db= thd->db;
+    Security_context save_security_ctx= *thd->security_ctx;
     USER_CONN *save_user_connect= thd->user_connect;
-    
-    if (!(thd->user= my_strdup(user, MYF(0))))
+
+    if (!(thd->security_ctx->user= my_strdup(user, MYF(0))))
     {
-      thd->user= save_user;
+      thd->security_ctx->user= save_security_ctx.user;
       my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
       break;
     }
@@ -1610,12 +1637,9 @@
       /* authentication failure, we shall restore old user */
       if (res > 0)
         my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
-      x_free(thd->user);
-      thd->user= save_user;
-      thd->priv_user= save_priv_user;
+      x_free(thd->security_ctx->user);
+      *thd->security_ctx= save_security_ctx;
       thd->user_connect= save_user_connect;
-      thd->master_access= save_master_access;
-      thd->db_access= save_db_access;
       thd->db= save_db;
       thd->db_length= save_db_length;
     }
@@ -1625,7 +1649,7 @@
       if (save_user_connect)
 	decrease_user_connections(save_user_connect);
       x_free((gptr) save_db);
-      x_free((gptr) save_user);
+      x_free((gptr)  save_security_ctx.user);
     }
     break;
   }
@@ -1776,7 +1800,7 @@
     remove_escape(table_list.table_name);	// This can't have wildcards
 
     if (check_access(thd,SELECT_ACL,table_list.db,&table_list.grant.privilege,
-		     0, 0))
+		     0, 0, test(table_list.schema_table)))
       break;
     if (grant_option &&
 	check_grant(thd, SELECT_ACL, &table_list, 2, UINT_MAX, 0))
@@ -1817,7 +1841,7 @@
 	my_error(ER_WRONG_DB_NAME, MYF(0), db ? db : "NULL");
 	break;
       }
-      if (check_access(thd,CREATE_ACL,db,0,1,0))
+      if (check_access(thd,CREATE_ACL,db,0,1,0,is_schema_db(db)))
 	break;
       mysql_log.write(thd,command,packet);
       bzero(&create_info, sizeof(create_info));
@@ -1836,7 +1860,7 @@
 	my_error(ER_WRONG_DB_NAME, MYF(0), db ? db : "NULL");
 	break;
       }
-      if (check_access(thd,DROP_ACL,db,0,1,0))
+      if (check_access(thd,DROP_ACL,db,0,1,0,is_schema_db(db)))
 	break;
       if (thd->locked_tables || thd->active_transaction())
       {
@@ -1967,12 +1991,13 @@
   case COM_PROCESS_INFO:
     statistic_increment(thd->status_var.com_stat[SQLCOM_SHOW_PROCESSLIST],
 			&LOCK_status);
-    if (!thd->priv_user[0] && check_global_access(thd,PROCESS_ACL))
+    if (!thd->security_ctx->priv_user[0] &&
+        check_global_access(thd, PROCESS_ACL))
       break;
     mysql_log.write(thd,command,NullS);
     mysqld_list_processes(thd,
-			  thd->master_access & PROCESS_ACL ? 
-			  NullS : thd->priv_user, 0);
+			  thd->security_ctx->master_access & PROCESS_ACL ? 
+			  NullS : thd->security_ctx->priv_user, 0);
     break;
   case COM_PROCESS_KILL:
   {
@@ -2134,12 +2159,14 @@
         my_error(ER_WRONG_DB_NAME, MYF(0), db);
         DBUG_RETURN(1);
       }
-      if (check_access(thd,SELECT_ACL,db,&thd->col_access,0,0))
+      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->priv_user, thd->priv_host, db);
+                 thd->security_ctx->priv_user, thd->security_ctx->priv_host,
+                 db);
 	DBUG_RETURN(1);
       }
       /*
@@ -2173,7 +2200,8 @@
       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))
+                       &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))
@@ -2396,7 +2424,8 @@
     Except for the replication thread and the 'super' users.
   */
   if (opt_readonly &&
-      !(thd->slave_thread || (thd->master_access & SUPER_ACL)) &&
+      !(thd->slave_thread ||
+        (thd->security_ctx->master_access & SUPER_ACL)) &&
       uc_update_queries[lex->sql_command])
   {
     my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
@@ -2430,7 +2459,7 @@
     else
       res= check_access(thd,
 			lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL,
-			any_db, 0, 0, 0);
+			any_db, 0, 0, 0, 0);
     if (res)
       goto error;
 
@@ -2612,7 +2641,8 @@
     DBUG_ASSERT(first_table == all_tables && first_table != 0);
     if (check_db_used(thd, all_tables) ||
         check_access(thd, INDEX_ACL, first_table->db,
-                     &first_table->grant.privilege, 0, 0))
+                     &first_table->grant.privilege, 0, 0,
+                     test(first_table->schema_table)))
       goto error;
     res= mysql_assign_to_keycache(thd, first_table, &lex->ident);
     break;
@@ -2622,7 +2652,8 @@
     DBUG_ASSERT(first_table == all_tables && first_table != 0);
     if (check_db_used(thd, all_tables) ||
 	check_access(thd, INDEX_ACL, first_table->db,
-                     &first_table->grant.privilege, 0, 0))
+                     &first_table->grant.privilege, 0, 0,
+                     test(first_table->schema_table)))
       goto error;
     res = mysql_preload_keys(thd, first_table);
     break;
@@ -2665,6 +2696,13 @@
       res = load_master_data(thd);
     break;
 #endif /* HAVE_REPLICATION */
+#ifdef HAVE_NDBCLUSTER_DB
+  case SQLCOM_SHOW_NDBCLUSTER_STATUS:
+    {
+      res = ndbcluster_show_status(thd);
+      break;
+    }
+#endif
 #ifdef HAVE_INNOBASE_DB
   case SQLCOM_SHOW_INNODB_STATUS:
     {
@@ -2688,7 +2726,8 @@
     if (!first_table->db)
       first_table->db= thd->db;
     if (check_access(thd, CREATE_ACL, first_table->db,
-		     &first_table->grant.privilege, 0, 0))
+		     &first_table->grant.privilege, 0, 0,
+                     test(first_table->schema_table)))
       goto error;				/* purecov: inspected */
     if (grant_option)
     {
@@ -2953,8 +2992,10 @@
           select_lex->db= first_table->db;
       }
       if (check_access(thd, ALTER_ACL, first_table->db,
-		       &first_table->grant.privilege, 0, 0) ||
-	  check_access(thd,INSERT_ACL | CREATE_ACL,select_lex->db,&priv,0,0)||
+		       &first_table->grant.privilege, 0, 0,
+                       test(first_table->schema_table)) ||
+	  check_access(thd,INSERT_ACL | CREATE_ACL,select_lex->db,&priv,0,0,
+                       is_schema_db(select_lex->db))||
 	  check_merge_table_access(thd, first_table->db,
 				   (TABLE_LIST *)
 				   lex->create_info.merge_list.first))
@@ -3004,9 +3045,10 @@
     for (table= first_table; table; table= table->next_local->next_local)
     {
       if (check_access(thd, ALTER_ACL | DROP_ACL, table->db,
-		       &table->grant.privilege,0,0) ||
+		       &table->grant.privilege,0,0, test(table->schema_table)) ||
 	  check_access(thd, INSERT_ACL | CREATE_ACL, table->next_local->db,
-		       &table->next_local->grant.privilege, 0, 0))
+		       &table->next_local->grant.privilege, 0, 0,
+                       test(table->next_local->schema_table)))
 	goto error;
       if (grant_option)
       {
@@ -3058,7 +3100,8 @@
 
       if (check_db_used(thd, all_tables) ||
 	  check_access(thd, SELECT_ACL | EXTRA_ACL, first_table->db,
-		       &first_table->grant.privilege, 0, 0))
+		       &first_table->grant.privilege, 0, 0, 
+                       test(first_table->schema_table)))
 	goto error;
       if (grant_option && check_grant(thd, SELECT_ACL, all_tables, 2, UINT_MAX, 0))
 	goto error;
@@ -3368,11 +3411,14 @@
       res = mysql_drop_index(thd, first_table, &lex->alter_info);
     break;
   case SQLCOM_SHOW_PROCESSLIST:
-    if (!thd->priv_user[0] && check_global_access(thd,PROCESS_ACL))
+    if (!thd->security_ctx->priv_user[0] &&
+        check_global_access(thd,PROCESS_ACL))
       break;
     mysqld_list_processes(thd,
-			  thd->master_access & PROCESS_ACL ? NullS :
-			  thd->priv_user,lex->verbose);
+			  (thd->security_ctx->master_access & PROCESS_ACL ?
+                           NullS :
+                           thd->security_ctx->priv_user),
+                          lex->verbose);
     break;
   case SQLCOM_SHOW_STORAGE_ENGINES:
     res= mysqld_show_storage_engines(thd);
@@ -3390,7 +3436,7 @@
     goto error;
 #else
     {
-      if (grant_option && check_access(thd, FILE_ACL, any_db,0,0,0))
+      if (grant_option && check_access(thd, FILE_ACL, any_db,0,0,0,0))
 	goto error;
       res= mysqld_show_logs(thd);
       break;
@@ -3519,7 +3565,7 @@
       break;
     }
 #endif
-    if (check_access(thd,CREATE_ACL,lex->name,0,1,0))
+    if (check_access(thd,CREATE_ACL,lex->name,0,1,0,is_schema_db(lex->name)))
       break;
     res= mysql_create_db(thd,(lower_case_table_names == 2 ? alias : lex->name),
 			 &lex->create_info, 0);
@@ -3553,7 +3599,7 @@
       break;
     }
 #endif
-    if (check_access(thd,DROP_ACL,lex->name,0,1,0))
+    if (check_access(thd,DROP_ACL,lex->name,0,1,0,is_schema_db(lex->name)))
       break;
     if (thd->locked_tables || thd->active_transaction())
     {
@@ -3593,7 +3639,7 @@
       break;
     }
 #endif
-    if (check_access(thd, ALTER_ACL, db, 0, 1, 0))
+    if (check_access(thd, ALTER_ACL, db, 0, 1, 0, is_schema_db(db)))
       break;
     if (thd->locked_tables || thd->active_transaction())
     {
@@ -3611,14 +3657,14 @@
       my_error(ER_WRONG_DB_NAME, MYF(0), lex->name);
       break;
     }
-    if (check_access(thd,SELECT_ACL,lex->name,0,1,0))
+    if (check_access(thd,SELECT_ACL,lex->name,0,1,0,is_schema_db(lex->name)))
       break;
     res=mysqld_show_create_db(thd,lex->name,&lex->create_info);
     break;
   }
   case SQLCOM_CREATE_FUNCTION:                  // UDF function
   {
-    if (check_access(thd,INSERT_ACL,"mysql",0,1,0))
+    if (check_access(thd,INSERT_ACL,"mysql",0,1,0,0))
       break;
 #ifdef HAVE_DLOPEN
     if (sp_find_function(thd, lex->spname))
@@ -3637,7 +3683,7 @@
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
   case SQLCOM_CREATE_USER:
   {
-    if (check_access(thd, INSERT_ACL, "mysql", 0, 1, 1) &&
+    if (check_access(thd, INSERT_ACL, "mysql", 0, 1, 1, 0) &&
         check_global_access(thd,CREATE_USER_ACL))
       break;
     if (!(res= mysql_create_user(thd, lex->users_list)))
@@ -3653,7 +3699,7 @@
   }
   case SQLCOM_DROP_USER:
   {
-    if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 1) &&
+    if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 1, 0) &&
         check_global_access(thd,CREATE_USER_ACL))
       break;
     if (!(res= mysql_drop_user(thd, lex->users_list)))
@@ -3669,7 +3715,7 @@
   }
   case SQLCOM_RENAME_USER:
   {
-    if (check_access(thd, UPDATE_ACL, "mysql", 0, 1, 1) &&
+    if (check_access(thd, UPDATE_ACL, "mysql", 0, 1, 1, 0) &&
         check_global_access(thd,CREATE_USER_ACL))
       break;
     if (!(res= mysql_rename_user(thd, lex->users_list)))
@@ -3685,7 +3731,7 @@
   }
   case SQLCOM_REVOKE_ALL:
   {
-    if (check_access(thd, UPDATE_ACL, "mysql", 0, 1, 1) &&
+    if (check_access(thd, UPDATE_ACL, "mysql", 0, 1, 1, 0) &&
         check_global_access(thd,CREATE_USER_ACL))
       break;
     if (!(res = mysql_revoke_all(thd, lex->users_list)))
@@ -3705,10 +3751,12 @@
     if (check_access(thd, lex->grant | lex->grant_tot_col | GRANT_ACL,
 		     first_table ?  first_table->db : select_lex->db,
 		     first_table ? &first_table->grant.privilege : 0,
-		     first_table ? 0 : 1, 0))
+		     first_table ? 0 : 1, 0,
+                     first_table ? (bool) first_table->schema_table :
+                     select_lex->db ? is_schema_db(select_lex->db) : 0))
       goto error;
 
-    if (thd->user)				// If not replication
+    if (thd->security_ctx->user)              // If not replication
     {
       LEX_USER *user;
       uint counter;
@@ -3724,13 +3772,13 @@
                               user->host.str);
         // Are we trying to change a password of another user
         DBUG_ASSERT(user->host.str != 0);
-        if (strcmp(thd->user, user->user.str) ||
+        if (strcmp(thd->security_ctx->user, user->user.str) ||
             my_strcasecmp(system_charset_info,
-                          user->host.str, thd->host_or_ip))
+                          user->host.str, thd->security_ctx->host_or_ip))
         {
           // TODO: use check_change_password()
           if (check_acl_user(user, &counter) && user->password.str &&
-              check_access(thd, UPDATE_ACL,"mysql",0,1,1))
+              check_access(thd, UPDATE_ACL,"mysql",0,1,1,0))
           {
             my_message(ER_PASSWORD_NOT_ALLOWED,
                        ER(ER_PASSWORD_NOT_ALLOWED), MYF(0));
@@ -3853,9 +3901,9 @@
   }
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
   case SQLCOM_SHOW_GRANTS:
-    if ((thd->priv_user &&
-	 !strcmp(thd->priv_user,lex->grant_user->user.str)) ||
-	!check_access(thd, SELECT_ACL, "mysql",0,1,0))
+    if ((thd->security_ctx->priv_user &&
+	 !strcmp(thd->security_ctx->priv_user, lex->grant_user->user.str)) ||
+	!check_access(thd, SELECT_ACL, "mysql",0,1,0,0))
     {
       res = mysql_show_grants(thd,lex->grant_user);
     }
@@ -3890,6 +3938,12 @@
     break;
 
   case SQLCOM_BEGIN:
+    if (thd->transaction.xid_state.xa_state != XA_NOTR)
+    {
+      my_error(ER_XAER_RMFAIL, MYF(0),
+               xa_state_names[thd->transaction.xid_state.xa_state]);
+      break;
+    }
     if (begin_trans(thd))
       goto error;
     send_ok(thd);
@@ -4010,13 +4064,17 @@
 
     DBUG_ASSERT(lex->sphead != 0);
 
-    if (check_access(thd, CREATE_PROC_ACL, lex->sphead->m_db.str, 0, 0, 0))
+    if (check_access(thd, CREATE_PROC_ACL, lex->sphead->m_db.str, 0, 0, 0,
+                     is_schema_db(lex->sphead->m_db.str)))
     {
       delete lex->sphead;
       lex->sphead= 0;
       goto error;
     }
 
+    if (end_active_trans(thd)) 
+      goto error;
+
     if (!lex->sphead->m_db.str || !lex->sphead->m_db.str[0])
     {
       lex->sphead->m_db.length= strlen(thd->db);
@@ -4124,7 +4182,7 @@
       else
       {
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
-	st_sp_security_context save_ctx;
+	Security_context *save_ctx;
 #endif
 	ha_rows select_limit;
         /* bits that should be cleared in thd->server_status */
@@ -4170,23 +4228,23 @@
 	}
 
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
-	if (check_routine_access(thd, EXECUTE_ACL, 
-				 sp->m_db.str, sp->m_name.str, TRUE, 0))
+	if (check_routine_access(thd, EXECUTE_ACL,
+				 sp->m_db.str, sp->m_name.str, TRUE, 0) ||
+          sp_change_security_context(thd, sp, &save_ctx))
 	{
 #ifndef EMBEDDED_LIBRARY
 	  thd->net.no_send_ok= nsok;
 #endif
 	  goto error;
 	}
-	sp_change_security_context(thd, sp, &save_ctx);
-	if (save_ctx.changed && 
-	    check_routine_access(thd, EXECUTE_ACL, 
-				   sp->m_db.str, sp->m_name.str, TRUE, 0))
+	if (save_ctx &&
+            check_routine_access(thd, EXECUTE_ACL,
+                                 sp->m_db.str, sp->m_name.str, TRUE, 0))
 	{
 #ifndef EMBEDDED_LIBRARY
 	  thd->net.no_send_ok= nsok;
 #endif
-	  sp_restore_security_context(thd, sp, &save_ctx);
+	  sp_restore_security_context(thd, save_ctx);
 	  goto error;
 	}
 
@@ -4226,7 +4284,7 @@
 
 	thd->variables.select_limit= select_limit;
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
-	sp_restore_security_context(thd, sp, &save_ctx);
+	sp_restore_security_context(thd, save_ctx);
 #endif
 
 #ifndef EMBEDDED_LIBRARY
@@ -4271,6 +4329,9 @@
 				 sp->m_name.str,
                                  lex->sql_command == SQLCOM_ALTER_PROCEDURE, 0))
 	  goto error;
+
+        if (end_active_trans(thd)) 
+          goto error;
 	memcpy(&lex->sp_chistics, &chistics, sizeof(lex->sp_chistics));
         if (!trust_routine_creators &&  mysql_bin_log.is_open() &&
             !sp->m_chistics->detistic &&
@@ -4330,6 +4391,9 @@
 	if (check_routine_access(thd, ALTER_PROC_ACL, db, name,
                                  lex->sql_command == SQLCOM_DROP_PROCEDURE, 0))
           goto error;
+
+        if (end_active_trans(thd)) 
+          goto error;
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
 	if (sp_automatic_privileges && !opt_noacl &&
 	    sp_revoke_privileges(thd, db, name, 
@@ -4354,7 +4418,7 @@
                                    lex->spname->m_name.length);
           if (udf)
           {
-	    if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 0))
+	    if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 0, 0))
 	      goto error;
 	    if (!(res = mysql_drop_function(thd, &lex->spname->m_name)))
 	    {
@@ -4451,8 +4515,29 @@
       if (!(res= mysql_create_view(thd, thd->lex->create_view_mode)) &&
           mysql_bin_log.is_open())
       {
+        String buff;
+        const LEX_STRING command[3]=
+          {{(char *)STRING_WITH_LEN("CREATE ")},
+           {(char *)STRING_WITH_LEN("ALTER ")},
+           {(char *)STRING_WITH_LEN("CREATE OR REPLACE ")}};
         thd->clear_error();
-        Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
+
+        buff.append(command[thd->lex->create_view_mode].str,
+                    command[thd->lex->create_view_mode].length);
+        view_store_options(thd, first_table, &buff);
+        buff.append("VIEW ", 5);
+        if (!first_table->current_db_used)
+        {
+          append_identifier(thd, &buff, first_table->db,
+                            first_table->db_length);
+          buff.append('.');
+        }
+        append_identifier(thd, &buff, first_table->table_name,
+                          first_table->table_name_length);
+        buff.append(" AS ", 4);
+        buff.append(first_table->source.str, first_table->source.length);
+
+        Query_log_event qinfo(thd, buff.ptr(), buff.length(), 0, FALSE);
         mysql_bin_log.write(&qinfo);
       }
       break;
@@ -4719,7 +4804,8 @@
 bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *all_tables)
 {
   if (check_access(thd, privilege, all_tables->db,
-		   &all_tables->grant.privilege, 0, 0))
+		   &all_tables->grant.privilege, 0, 0,
+                   test(all_tables->schema_table)))
     return 1;
 
   /* Show only 1 table for check_grant */
@@ -4758,16 +4844,18 @@
 
 bool
 check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
-	     bool dont_check_global_grants, bool no_errors)
+	     bool dont_check_global_grants, bool no_errors, bool schema_db)
 {
+  Security_context *sctx= thd->security_ctx;
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
   ulong db_access;
   bool  db_is_pattern= test(want_access & GRANT_ACL);
 #endif
   ulong dummy;
+  const char *db_name;
   DBUG_ENTER("check_access");
   DBUG_PRINT("enter",("db: %s  want_access: %lu  master_access: %lu",
-                      db ? db : "", want_access, thd->master_access));
+                      db ? db : "", want_access, sctx->master_access));
   if (save_priv)
     *save_priv=0;
   else
@@ -4782,31 +4870,50 @@
     DBUG_RETURN(TRUE);				/* purecov: tested */
   }
 
+  db_name= db ? db : thd->db;
+  if (schema_db)
+  {
+    if (want_access & ~(SELECT_ACL | EXTRA_ACL))
+    {
+      if (!no_errors)
+        my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
+                 sctx->priv_user,
+                 sctx->priv_host, db_name);
+      DBUG_RETURN(TRUE);
+    }
+    else
+    {
+      *save_priv= SELECT_ACL;
+      DBUG_RETURN(FALSE);
+    }
+  }
+
 #ifdef NO_EMBEDDED_ACCESS_CHECKS
   DBUG_RETURN(0);
 #else
-  if ((thd->master_access & want_access) == want_access)
+  if ((sctx->master_access & want_access) == want_access)
   {
     /*
       If we don't have a global SELECT privilege, we have to get the database
       specific access rights to be able to handle queries of type
       UPDATE t1 SET a=1 WHERE b > 0
     */
-    db_access= thd->db_access;
-    if (!(thd->master_access & SELECT_ACL) &&
+    db_access= sctx->db_access;
+    if (!(sctx->master_access & SELECT_ACL) &&
 	(db && (!thd->db || db_is_pattern || strcmp(db,thd->db))))
-      db_access=acl_get(thd->host, thd->ip, thd->priv_user, db, db_is_pattern);
-    *save_priv=thd->master_access | db_access;
+      db_access=acl_get(sctx->host, sctx->ip, sctx->priv_user, db,
+                        db_is_pattern);
+    *save_priv=sctx->master_access | db_access;
     DBUG_RETURN(FALSE);
   }
-  if (((want_access & ~thd->master_access) & ~(DB_ACLS | EXTRA_ACL)) ||
+  if (((want_access & ~sctx->master_access) & ~(DB_ACLS | EXTRA_ACL)) ||
       ! db && dont_check_global_grants)
   {						// We can never grant this
     DBUG_PRINT("error",("No possible access"));
     if (!no_errors)
       my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
-               thd->priv_user,
-               thd->priv_host,
+               sctx->priv_user,
+               sctx->priv_host,
                (thd->password ?
                 ER(ER_YES) :
                 ER(ER_NO)));                    /* purecov: tested */
@@ -4817,15 +4924,16 @@
     DBUG_RETURN(FALSE);				// Allow select on anything
 
   if (db && (!thd->db || db_is_pattern || strcmp(db,thd->db)))
-    db_access=acl_get(thd->host, thd->ip, thd->priv_user, db, db_is_pattern);
+    db_access= acl_get(sctx->host, sctx->ip, sctx->priv_user, db,
+                       db_is_pattern);
   else
-    db_access=thd->db_access;
+    db_access= sctx->db_access;
   DBUG_PRINT("info",("db_access: %lu", db_access));
   /* Remove SHOW attribute and access rights we already have */
-  want_access &= ~(thd->master_access | EXTRA_ACL);
+  want_access &= ~(sctx->master_access | EXTRA_ACL);
   DBUG_PRINT("info",("db_access: %lu  want_access: %lu",
                      db_access, want_access));
-  db_access= ((*save_priv=(db_access | thd->master_access)) & want_access);
+  db_access= ((*save_priv=(db_access | sctx->master_access)) & want_access);
 
   /* grant_option is set if there exists a single table or column grant */
   if (db_access == want_access ||
@@ -4836,8 +4944,7 @@
   DBUG_PRINT("error",("Access denied"));
   if (!no_errors)
     my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
-             thd->priv_user,
-             thd->priv_host,
+             sctx->priv_user, sctx->priv_host,
              (db ? db : (thd->db ?
                          thd->db :
                          "unknown")));          /* purecov: tested */
@@ -4871,7 +4978,7 @@
   return 0;
 #else
   char command[128];
-  if ((thd->master_access & want_access))
+  if ((thd->security_ctx->master_access & want_access))
     return 0;
   get_privilege_desc(command, sizeof(command), want_access);
   my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command);
@@ -4894,12 +5001,22 @@
   TABLE_LIST *org_tables=tables;
   for (; tables; tables= tables->next_global)
   {
+    if (tables->schema_table && 
+        (want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL)))
+    {
+      if (!no_errors)
+        my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
+                 thd->security_ctx->priv_user, thd->security_ctx->priv_host,
+                 information_schema_name.str);
+      return TRUE;
+    }
     if (tables->derived || tables->schema_table || tables->belong_to_view ||
         (tables->table && (int)tables->table->s->tmp_table) ||
         my_tz_check_n_skip_implicit_tables(&tables,
                                            thd->lex->time_zone_tables_used))
       continue;
-    if ((thd->master_access & want_access) == (want_access & ~EXTRA_ACL) &&
+    if ((thd->security_ctx->master_access & want_access) ==
+        (want_access & ~EXTRA_ACL) &&
 	thd->db)
       tables->grant.privilege= want_access;
     else if (tables->db && tables->db == thd->db)
@@ -4909,14 +5026,14 @@
       else
       {
 	if (check_access(thd,want_access,tables->db,&tables->grant.privilege,
-			 0, no_errors))
+			 0, no_errors, test(tables->schema_table)))
 	  return TRUE;				// Access denied
 	found_access=tables->grant.privilege;
 	found=1;
       }
     }
     else if (check_access(thd,want_access,tables->db,&tables->grant.privilege,
-			  0, no_errors))
+			  0, no_errors, test(tables->schema_table)))
       return TRUE;
   }
   if (grant_option)
@@ -4936,10 +5053,11 @@
   tables->db= db;
   tables->table_name= tables->alias= name;
   
-  if ((thd->master_access & want_access) == want_access && !thd->db)
+  if ((thd->security_ctx->master_access & want_access) == want_access &&
+      !thd->db)
     tables->grant.privilege= want_access;
   else if (check_access(thd,want_access,db,&tables->grant.privilege,
-			0, no_errors))
+			0, no_errors, test(tables->schema_table)))
     return TRUE;
   
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -4969,9 +5087,13 @@
                                bool is_proc)
 {
   ulong save_priv;
-  if (thd->master_access & SHOW_PROC_ACLS)
+  if (thd->security_ctx->master_access & SHOW_PROC_ACLS)
     return FALSE;
-  if (!check_access(thd, SHOW_PROC_ACLS, db, &save_priv, 0, 1) ||
+  /*
+    There are no routines in information_schema db. So we can safely
+    pass zero to last paramter of check_access function
+  */
+  if (!check_access(thd, SHOW_PROC_ACLS, db, &save_priv, 0, 1, 0) ||
       (save_priv & SHOW_PROC_ACLS))
     return FALSE;
   return check_routine_level_acl(thd, db, name, is_proc);
@@ -5003,7 +5125,8 @@
     if (access & want_access)
     {
       if (!check_access(thd, access, table->db,
-                        &table->grant.privilege, 0, 1) &&
+                        &table->grant.privilege, 0, 1,
+                        test(table->schema_table)) &&
           !grant_option || !check_grant(thd, access, table, 0, 1, 1))
         DBUG_RETURN(0);
     }
@@ -5161,6 +5284,7 @@
   thd->server_status&= ~ (SERVER_MORE_RESULTS_EXISTS | 
                           SERVER_QUERY_NO_INDEX_USED |
                           SERVER_QUERY_NO_GOOD_INDEX_USED);
+  DBUG_ASSERT(thd->security_ctx== &thd->main_security_ctx);
   thd->tmp_table_used= 0;
   if (!thd->in_sub_stmt)
   {
@@ -5538,8 +5662,7 @@
        and so on, the display width is ignored.
     */
     char buf[32];
-    my_snprintf(buf, sizeof(buf),
-                "TIMESTAMP(%s)", length, system_charset_info);
+    my_snprintf(buf, sizeof(buf), "TIMESTAMP(%s)", length);
     push_warning_printf(thd,MYSQL_ERROR::WARN_LEVEL_WARN,
                         ER_WARN_DEPRECATED_SYNTAX,
                         ER(ER_WARN_DEPRECATED_SYNTAX),
@@ -5645,7 +5768,7 @@
     }
     if (new_field->length < new_field->decimals)
     {
-      my_error(ER_SCALE_BIGGER_THAN_PRECISION, MYF(0), field_name);
+      my_error(ER_M_BIGGER_THAN_D, MYF(0), field_name);
       DBUG_RETURN(NULL);
     }
     new_field->length=
@@ -5708,19 +5831,31 @@
       new_field->decimals= NOT_FIXED_DEC;
       break;
     }
-    if (!length)
+    if (!length && !decimals)
     {
       new_field->length =  FLT_DIG+6;
       new_field->decimals= NOT_FIXED_DEC;
     }
+    if (new_field->length < new_field->decimals &&
+        new_field->decimals != NOT_FIXED_DEC)
+    {
+      my_error(ER_M_BIGGER_THAN_D, MYF(0), field_name);
+      DBUG_RETURN(NULL);
+    }
     break;
   case FIELD_TYPE_DOUBLE:
     allowed_type_modifier= AUTO_INCREMENT_FLAG;
-    if (!length)
+    if (!length && !decimals)
     {
       new_field->length = DBL_DIG+7;
       new_field->decimals=NOT_FIXED_DEC;
     }
+    if (new_field->length < new_field->decimals &&
+        new_field->decimals != NOT_FIXED_DEC)
+    {
+      my_error(ER_M_BIGGER_THAN_D, MYF(0), field_name);
+      DBUG_RETURN(NULL);
+    }
     break;
   case FIELD_TYPE_TIMESTAMP:
     if (!length)
@@ -6009,12 +6144,14 @@
   {
     ptr->db= thd->db;
     ptr->db_length= thd->db_length;
+    ptr->current_db_used= 1;
   }
   else
   {
     /* The following can't be "" as we may do 'casedn_str()' on it */
     ptr->db= empty_c_string;
     ptr->db_length= 0;
+    ptr->current_db_used= 1;
   }
   if (thd->stmt_arena->is_stmt_prepare_or_first_sp_execute())
     ptr->db= thd->strdup(ptr->db);
@@ -6683,8 +6820,8 @@
   VOID(pthread_mutex_unlock(&LOCK_thread_count));
   if (tmp)
   {
-    if ((thd->master_access & SUPER_ACL) ||
-	!strcmp(thd->user,tmp->user))
+    if ((thd->security_ctx->master_access & SUPER_ACL) ||
+	!strcmp(thd->security_ctx->user, tmp->security_ctx->user))
     {
       tmp->awake(only_kill_query ? THD::KILL_QUERY : THD::KILL_CONNECTION);
       error=0;
@@ -6811,10 +6948,11 @@
   {
     TABLE_LIST *save= table->next_local;
     table->next_local= 0;
-    if ((check_access(thd, UPDATE_ACL, table->db, &table->grant.privilege,0,1) ||
-        (grant_option && check_grant(thd, UPDATE_ACL, table,0,1,1))) &&
+    if ((check_access(thd, UPDATE_ACL, table->db, 
+                      &table->grant.privilege,0,1, test(table->schema_table)) ||
+         (grant_option && check_grant(thd, UPDATE_ACL, table,0,1,1))) &&
 	check_one_table_access(thd, SELECT_ACL, table))
-	goto error;
+      goto error;
     table->next_local= save;
   }
     
@@ -6979,11 +7117,13 @@
     if (table->derived)
       table->grant.privilege= SELECT_ACL;
     else if ((check_access(thd, UPDATE_ACL, table->db,
-                           &table->grant.privilege, 0, 1) ||
+                           &table->grant.privilege, 0, 1,
+                           test(table->schema_table)) ||
               grant_option &&
               check_grant(thd, UPDATE_ACL, table, 0, 1, 1)) &&
              (check_access(thd, SELECT_ACL, table->db,
-                           &table->grant.privilege, 0, 0) ||
+                           &table->grant.privilege, 0, 0,
+                           test(table->schema_table)) ||
               grant_option && check_grant(thd, SELECT_ACL, table, 0, 1, 0)))
       DBUG_RETURN(TRUE);
 
@@ -7002,7 +7142,8 @@
           !table->table_in_first_from_clause)
       {
 	if (check_access(thd, SELECT_ACL, table->db,
-			 &table->grant.privilege, 0, 0) ||
+			 &table->grant.privilege, 0, 0,
+                         test(table->schema_table)) ||
 	    grant_option && check_grant(thd, SELECT_ACL, table, 0, 1, 0))
 	  DBUG_RETURN(TRUE);
       }
@@ -7097,6 +7238,12 @@
                target_tbl->table_name, "MULTI DELETE");
       DBUG_RETURN(TRUE);
     }
+    if (!walk->derived)
+    {
+      target_tbl->table_name= walk->table_name;
+      target_tbl->table_name_length= walk->table_name_length;
+    }
+    walk->updating= target_tbl->updating;
     walk->lock_type= target_tbl->lock_type;
     target_tbl->correspondent_table= walk;	// Remember corresponding table
   }
@@ -7219,7 +7366,8 @@
               CREATE_TMP_ACL : CREATE_ACL);
   lex->create_info.alias= create_table->alias;
   if (check_access(thd, want_priv, create_table->db,
-		   &create_table->grant.privilege, 0, 0) ||
+		   &create_table->grant.privilege, 0, 0,
+                   test(create_table->schema_table)) ||
       check_merge_table_access(thd, create_table->db,
 			       (TABLE_LIST *)
 			       lex->create_info.merge_list.first))
@@ -7296,4 +7444,35 @@
   if ((negated= expr->neg_transformer(thd)) != 0)
     return negated;
   return new Item_func_not(expr);
+}
+
+
+/*
+  Assign as view definer current user
+
+  SYNOPSIS
+    default_definer()
+    Secytity_context     current decurity context
+    definer              structure where it should be assigned
+
+  RETURN
+    FALSE   OK
+    TRUE    Error
+*/
+
+bool default_view_definer(Security_context *sctx, st_lex_user *definer)
+{
+  definer->user.str= sctx->priv_user;
+  definer->user.length= strlen(sctx->priv_user);
+  if (*sctx->priv_host != 0)
+  {
+    definer->host.str= sctx->priv_host;
+    definer->host.length= strlen(sctx->priv_host);
+  }
+  else
+  {
+    my_error(ER_NO_VIEW_USER, MYF(0));
+    return TRUE;
+  }
+  return FALSE;
 }
Thread
bk commit into 5.0 tree (monty:1.2030)monty7 Oct