commit 7d386bbce216745ba28df728f45a0b796fcced98
Author: Sergei Golubchik <serg@mariadb.org>
Date:   Sat Jun 14 22:59:12 2014 +0200

    MDEV-4549 [PATCH] Clean up code working with ACL tables
    
    enum values to index different ACL tables, instead of hard-coded numbers
    (even different in diffent functions). Also factor out TABLE_LIST
    initialization into a separate function.

diff --git a/mysql-test/r/not_embedded_server.result b/mysql-test/r/not_embedded_server.result
index 2295276..6dda855 100644
--- a/mysql-test/r/not_embedded_server.result
+++ b/mysql-test/r/not_embedded_server.result
@@ -1,4 +1,4 @@
-call mtr.add_suppression("Can't open and lock privilege tables: Table 'host' was not locked with LOCK TABLES");
+call mtr.add_suppression("Can't open and lock privilege tables: Table 'roles_mapping' was not locked with LOCK TABLES");
 SHOW VARIABLES like 'slave_skip_errors';
 Variable_name	Value
 slave_skip_errors	OFF
@@ -16,7 +16,7 @@ DROP TABLE IF EXISTS t1;
 CREATE TABLE t1 (c1 INT);
 LOCK TABLES t1 READ;
 FLUSH PRIVILEGES;
-ERROR HY000: Table 'host' was not locked with LOCK TABLES
+ERROR HY000: Table 'roles_mapping' was not locked with LOCK TABLES
 UNLOCK TABLES;
 DROP TABLE t1;
 #
diff --git a/mysql-test/r/sp-destruct.result b/mysql-test/r/sp-destruct.result
index 172e40c..fe68229 100644
--- a/mysql-test/r/sp-destruct.result
+++ b/mysql-test/r/sp-destruct.result
@@ -128,11 +128,8 @@ CREATE FUNCTION f1() RETURNS INT RETURN 1;
 RENAME TABLE mysql.procs_priv TO procs_priv_backup;
 FLUSH TABLE mysql.procs_priv;
 DROP FUNCTION f1;
-ERROR 42S02: Table 'mysql.procs_priv' doesn't exist
 SHOW WARNINGS;
 Level	Code	Message
-Error	1146	Table 'mysql.procs_priv' doesn't exist
-Warning	1405	Failed to revoke all privileges to dropped routine
 # Restore the procs_priv table
 RENAME TABLE procs_priv_backup TO mysql.procs_priv;
 FLUSH TABLE mysql.procs_priv;
diff --git a/mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result b/mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result
index 550b3f5..0785491 100644
--- a/mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result
+++ b/mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result
@@ -143,43 +143,43 @@ UNLOCK TABLE;
 DROP DATABASE mysqltest2;
 LOCK TABLE t1 WRITE;
 CREATE USER test_1@localhost;
-ERROR HY000: Table 'user' was not locked with LOCK TABLES
+ERROR HY000: Table 'roles_mapping' was not locked with LOCK TABLES
 INSERT INTO t2 VALUES ("CREATE USER test_1@localhost with table locked");
 UNLOCK TABLE;
 CREATE USER test_2@localhost;
 LOCK TABLE t1 WRITE;
 GRANT SELECT ON t1 TO test_2@localhost;
-ERROR HY000: Table 'user' was not locked with LOCK TABLES
+ERROR HY000: Table 'tables_priv' was not locked with LOCK TABLES
 INSERT INTO t2 VALUES ("GRANT select on table to user with table locked");
 GRANT ALL ON f2 TO test_2@localhost;
-ERROR HY000: Table 'user' was not locked with LOCK TABLES
+ERROR HY000: Table 'tables_priv' was not locked with LOCK TABLES
 INSERT INTO t2 VALUES ("GRANT ALL ON f2 TO test_2 with table locked");
 GRANT ALL ON p2 TO test_2@localhost;
-ERROR HY000: Table 'user' was not locked with LOCK TABLES
+ERROR HY000: Table 'tables_priv' was not locked with LOCK TABLES
 INSERT INTO t2 VALUES ("GRANT ALL ON p2 TO test_2 with table locked");
 GRANT USAGE ON *.* TO test_2@localhost;
-ERROR HY000: Table 'user' was not locked with LOCK TABLES
+ERROR HY000: Table 'db' was not locked with LOCK TABLES
 INSERT INTO t2 VALUES ("GRANT USAGE ON *.* TO test_2 with table locked");
 REVOKE ALL PRIVILEGES ON f2 FROM test_2@localhost;
-ERROR HY000: Table 'user' was not locked with LOCK TABLES
+ERROR HY000: Table 'columns_priv' was not locked with LOCK TABLES
 INSERT INTO t2 VALUES ("REVOKE ALL PRIVILEGES on function to user with table locked");
 REVOKE ALL PRIVILEGES ON p2 FROM test_2@localhost;
-ERROR HY000: Table 'user' was not locked with LOCK TABLES
+ERROR HY000: Table 'columns_priv' was not locked with LOCK TABLES
 INSERT INTO t2 VALUES ("REVOKE ALL PRIVILEGES on procedure to user with table locked");
 REVOKE ALL PRIVILEGES ON t1 FROM test_2@localhost;
-ERROR HY000: Table 'user' was not locked with LOCK TABLES
+ERROR HY000: Table 'columns_priv' was not locked with LOCK TABLES
 INSERT INTO t2 VALUES ("REVOKE ALL PRIVILEGES on table to user with table locked");
 REVOKE USAGE ON *.* FROM test_2@localhost;
-ERROR HY000: Table 'user' was not locked with LOCK TABLES
+ERROR HY000: Table 'db' was not locked with LOCK TABLES
 INSERT INTO t2 VALUES ("REVOKE USAGE ON *.* TO test_2 with table locked");
 RENAME USER test_2@localhost TO test_3@localhost;
-ERROR HY000: Table 'user' was not locked with LOCK TABLES
+ERROR HY000: Table 'roles_mapping' was not locked with LOCK TABLES
 INSERT INTO t2 VALUES ("RENAME USER test_2 TO test_3 with table locked");
 UNLOCK TABLE;
 RENAME USER test_2@localhost TO test_3@localhost;
 LOCK TABLE t1 WRITE;
 DROP USER test_3@localhost;
-ERROR HY000: Table 'user' was not locked with LOCK TABLES
+ERROR HY000: Table 'roles_mapping' was not locked with LOCK TABLES
 INSERT INTO t2 VALUES ("DROP USER test_3@localhost with table locked");
 UNLOCK TABLE;
 DROP USER test_3@localhost;
diff --git a/mysql-test/t/not_embedded_server.test b/mysql-test/t/not_embedded_server.test
index e74da3a..13d2584 100644
--- a/mysql-test/t/not_embedded_server.test
+++ b/mysql-test/t/not_embedded_server.test
@@ -6,7 +6,7 @@
 
 # End of 4.1 tests
 
-call mtr.add_suppression("Can't open and lock privilege tables: Table 'host' was not locked with LOCK TABLES");
+call mtr.add_suppression("Can't open and lock privilege tables: Table 'roles_mapping' was not locked with LOCK TABLES");
 
 #
 # Bug#43835: SHOW VARIABLES does not include 0 for slave_skip_errors
diff --git a/mysql-test/t/sp-destruct.test b/mysql-test/t/sp-destruct.test
index e109f88..52bbce6 100644
--- a/mysql-test/t/sp-destruct.test
+++ b/mysql-test/t/sp-destruct.test
@@ -214,7 +214,6 @@ RENAME TABLE mysql.procs_priv TO procs_priv_backup;
 FLUSH TABLE mysql.procs_priv;
 
 # DROP FUNCTION used to cause an assert.
---error ER_NO_SUCH_TABLE
 DROP FUNCTION f1;
 SHOW WARNINGS;
 
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 5e8e0e7..442d512 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -380,7 +380,7 @@ class ACL_PROXY_USER :public ACL_ACCESS
     MYSQL_PROXIES_PRIV_PROXIED_USER,
     MYSQL_PROXIES_PRIV_WITH_GRANT,
     MYSQL_PROXIES_PRIV_GRANTOR,
-    MYSQL_PROXIES_PRIV_TIMESTAMP } old_acl_proxy_users;
+    MYSQL_PROXIES_PRIV_TIMESTAMP } proxy_table_fields;
 public:
   ACL_PROXY_USER () {};
 
@@ -760,6 +760,99 @@ static int traverse_role_graph_down(ACL_USER_BASE *, void *,
                              int (*) (ACL_USER_BASE *, ACL_ROLE *, void *));
 
 /*
+ Enumeration of ACL/GRANT tables in the mysql database
+*/
+enum enum_acl_tables
+{
+  USER_TABLE,
+  DB_TABLE,
+  TABLES_PRIV_TABLE,
+  COLUMNS_PRIV_TABLE,
+#define FIRST_OPTIONAL_TABLE HOST_TABLE
+  HOST_TABLE,
+  PROCS_PRIV_TABLE,
+  PROXIES_PRIV_TABLE,
+  ROLES_MAPPING_TABLE,
+  TABLES_MAX // <== always the last
+};
+// bits for init_priv_tables
+static const int Table_user= 1 << USER_TABLE;
+static const int Table_db= 1 << DB_TABLE;
+static const int Table_tables_priv= 1 << TABLES_PRIV_TABLE;
+static const int Table_columns_priv= 1 << COLUMNS_PRIV_TABLE;
+static const int Table_host= 1 << HOST_TABLE;
+static const int Table_procs_priv= 1 << PROCS_PRIV_TABLE;
+static const int Table_proxies_priv= 1 << PROXIES_PRIV_TABLE;
+static const int Table_roles_mapping= 1 << ROLES_MAPPING_TABLE;
+
+const LEX_STRING acl_table_names[]=     //  matches enum_acl_tables
+{
+  { C_STRING_WITH_LEN("user") },
+  { C_STRING_WITH_LEN("db") },
+  { C_STRING_WITH_LEN("tables_priv") },
+  { C_STRING_WITH_LEN("columns_priv") },
+  { C_STRING_WITH_LEN("host") },
+  { C_STRING_WITH_LEN("procs_priv") },
+  { C_STRING_WITH_LEN("proxies_priv") },
+  { C_STRING_WITH_LEN("roles_mapping") }
+};
+
+/**
+  Initialize a TABLE_LIST array to a set of acl/grant tables.
+  All tables will be opened with the same lock type, either read or write.
+
+  @retval !0 a pointer to the first initialized element in the TABLE_LIST
+  @retval  0 replication filters matched. Abort operation, but return OK (!)
+*/
+TABLE_LIST *init_priv_tables(THD *thd, TABLE_LIST *tables,
+                             enum thr_lock_type lock_type, int tables_to_open)
+{
+  int prev= -1;
+  bzero(tables, sizeof(TABLE_LIST) * TABLES_MAX);
+  for (int cur=0, mask=1; mask <= tables_to_open; cur++, mask <<= 1)
+  {
+    if ((tables_to_open & mask) == 0)
+      continue;
+    tables[cur].init_one_table(C_STRING_WITH_LEN("mysql"),
+                               acl_table_names[cur].str,
+                               acl_table_names[cur].length,
+                               acl_table_names[cur].str, lock_type);
+    tables[cur].open_type= OT_BASE_ONLY;
+    if (lock_type >= TL_WRITE_ALLOW_WRITE)
+      tables[cur].updating= 1;
+    if (cur >= FIRST_OPTIONAL_TABLE)
+      tables[cur].open_strategy= TABLE_LIST::OPEN_IF_EXISTS;
+    if (prev != -1)
+      tables[cur].next_local= tables[cur].next_global= & tables[prev];
+    prev= cur;
+  }
+
+#ifdef HAVE_REPLICATION
+  if (lock_type >= TL_WRITE_ALLOW_WRITE && thd->slave_thread && !thd->spcont)
+  {
+    /*
+      GRANT and REVOKE are applied the slave in/exclusion rules as they are
+      some kind of updates to the mysql.% tables.
+    */
+    Rpl_filter *rpl_filter= thd->system_thread_info.rpl_sql_info->rpl_filter;
+    if (rpl_filter->is_on() && !rpl_filter->tables_ok(0, tables))
+      return NULL;
+  }
+#endif
+  return & tables[prev];
+}
+
+/** check if the table was opened, issue an error otherwise */
+static int no_such_table(TABLE_LIST *tl)
+{
+  if (tl->table)
+    return 0;
+
+  my_error(ER_NO_SUCH_TABLE, MYF(0), tl->db, tl->alias);
+  return 1;
+}
+
+/*
  Enumeration of various ACL's and Hashes used in handle_grant_struct()
 */
 enum enum_acl_lists
@@ -1023,10 +1116,9 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
 
   init_sql_alloc(&acl_memroot, ACL_ALLOC_BLOCK_SIZE, 0, MYF(0));
   (void) my_init_dynamic_array(&acl_hosts,sizeof(ACL_HOST), 20, 50, MYF(0));
-  if (tables[0].table) // "host" table may not exist (e.g. in MySQL 5.6.7+)
+  if ((table= tables[HOST_TABLE].table)) // "host" table may not exist (e.g. in MySQL 5.6.7+)
   {
-    if (init_read_record(&read_record_info, thd, table= tables[0].table,
-                         NULL, 1, 1, FALSE))
+    if (init_read_record(&read_record_info, thd, table, NULL, 1, 1, FALSE))
       goto end;
     table->use_all_columns();
     while (!(read_record_info.read_record(&read_record_info)))
@@ -1080,7 +1172,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
   }
   freeze_size(&acl_hosts);
 
-  if (init_read_record(&read_record_info, thd, table=tables[1].table,
+  if (init_read_record(&read_record_info, thd, table=tables[USER_TABLE].table,
                        NULL, 1, 1, FALSE))
     goto end;
   table->use_all_columns();
@@ -1323,7 +1415,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
   end_read_record(&read_record_info);
   freeze_size(&acl_users);
 
-  if (init_read_record(&read_record_info, thd, table=tables[2].table,
+  if (init_read_record(&read_record_info, thd, table=tables[DB_TABLE].table,
                        NULL, 1, 1, FALSE))
     goto end;
   table->use_all_columns();
@@ -1391,9 +1483,9 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
 
   (void) my_init_dynamic_array(&acl_proxy_users, sizeof(ACL_PROXY_USER),
                                50, 100, MYF(0));
-  if (tables[3].table)
+  if ((table= tables[PROXIES_PRIV_TABLE].table))
   {
-    if (init_read_record(&read_record_info, thd, table= tables[3].table,
+    if (init_read_record(&read_record_info, thd, table,
                          NULL, 1, 1, FALSE))
       goto end;
     table->use_all_columns();
@@ -1421,10 +1513,9 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
   }
   freeze_size(&acl_proxy_users);
 
-  if (tables[4].table)
+  if ((table= tables[ROLES_MAPPING_TABLE].table))
   {
-    if (init_read_record(&read_record_info, thd, table= tables[4].table,
-                         NULL, 1, 1, FALSE))
+    if (init_read_record(&read_record_info, thd, table, NULL, 1, 1, FALSE))
       goto end;
     table->use_all_columns();
     /* account for every role mapping */
@@ -1518,7 +1609,7 @@ void acl_free(bool end)
 
 my_bool acl_reload(THD *thd)
 {
-  TABLE_LIST tables[5];
+  TABLE_LIST tables[TABLES_MAX], *tl;
   DYNAMIC_ARRAY old_acl_hosts, old_acl_users, old_acl_dbs, old_acl_proxy_users;
   HASH old_acl_roles, old_acl_roles_mappings;
   MEM_ROOT old_mem;
@@ -1529,28 +1620,10 @@ my_bool acl_reload(THD *thd)
     To avoid deadlocks we should obtain table locks before
     obtaining acl_cache->lock mutex.
   */
-  tables[0].init_one_table(C_STRING_WITH_LEN("mysql"),
-                           C_STRING_WITH_LEN("host"), "host", TL_READ);
-  tables[1].init_one_table(C_STRING_WITH_LEN("mysql"),
-                           C_STRING_WITH_LEN("user"), "user", TL_READ);
-  tables[2].init_one_table(C_STRING_WITH_LEN("mysql"),
-                           C_STRING_WITH_LEN("db"), "db", TL_READ);
-  tables[3].init_one_table(C_STRING_WITH_LEN("mysql"),
-                           C_STRING_WITH_LEN("proxies_priv"), 
-                           "proxies_priv", TL_READ);
-  tables[4].init_one_table(C_STRING_WITH_LEN("mysql"),
-                           C_STRING_WITH_LEN("roles_mapping"),
-                           "roles_mapping", TL_READ);
-  tables[0].next_local= tables[0].next_global= tables + 1;
-  tables[1].next_local= tables[1].next_global= tables + 2;
-  tables[2].next_local= tables[2].next_global= tables + 3;
-  tables[3].next_local= tables[3].next_global= tables + 4;
-  tables[0].open_type= tables[1].open_type= tables[2].open_type= 
-  tables[3].open_type= tables[4].open_type= OT_BASE_ONLY;
-  tables[0].open_strategy= tables[3].open_strategy=
-  tables[4].open_strategy= TABLE_LIST::OPEN_IF_EXISTS;
+  tl= init_priv_tables(thd, tables, TL_READ, Table_host | Table_user | Table_db
+                       | Table_proxies_priv | Table_roles_mapping);
  
-  if (open_and_lock_tables(thd, tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
+  if (open_and_lock_tables(thd, tl, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
   {
     /*
       Execution might have been interrupted; only print the error message
@@ -2558,9 +2631,8 @@ int check_change_password(THD *thd, const char *host, const char *user,
 bool change_password(THD *thd, const char *host, const char *user,
 		     char *new_password)
 {
-  TABLE_LIST tables;
+  TABLE_LIST tables[TABLES_MAX], *tl;
   TABLE *table;
-  Rpl_filter *rpl_filter;
   /* Buffer should be extended when password length is extended. */
   char buff[512];
   ulong query_length;
@@ -2575,27 +2647,11 @@ bool change_password(THD *thd, const char *host, const char *user,
   if (check_change_password(thd, host, user, new_password, new_password_len))
     DBUG_RETURN(1);
 
-  tables.init_one_table("mysql", 5, "user", 4, "user", TL_WRITE);
+  tl= init_priv_tables(thd, tables, TL_WRITE, Table_user);
+  if (!tl)
+    DBUG_RETURN(0);
 
-#ifdef HAVE_REPLICATION
-  /*
-    GRANT and REVOKE are applied the slave in/exclusion rules as they are
-    some kind of updates to the mysql.% tables.
-  */
-  if (thd->slave_thread &&
-      (rpl_filter= thd->system_thread_info.rpl_sql_info->rpl_filter)->is_on())
-  {
-    /*
-      The tables must be marked "updating" so that tables_ok() takes them into
-      account in tests.  It's ok to leave 'updating' set after tables_ok.
-    */
-    tables.updating= 1;
-    /* Thanks to bzero, tables.next==0 */
-    if (!(thd->spcont || rpl_filter->tables_ok(0, &tables)))
-      DBUG_RETURN(0);
-  }
-#endif
-  if (!(table= open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT)))
+  if (!(table= open_ltable(thd, tl, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT)))
     DBUG_RETURN(1);
 
   /*
@@ -5393,10 +5449,9 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
   ulong column_priv= 0;
   List_iterator <LEX_USER> str_list (user_list);
   LEX_USER *Str, *tmp_Str;
-  TABLE_LIST tables[3];
+  TABLE_LIST tables[TABLES_MAX], *tl;
   bool create_new_users=0;
   char *db_name, *table_name;
-  Rpl_filter *rpl_filter;
   DBUG_ENTER("mysql_table_grant");
 
   if (!initialized)
@@ -5466,38 +5521,19 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
     }
   }
 
-  /* open the mysql.tables_priv and mysql.columns_priv tables */
-
-  tables[0].init_one_table(C_STRING_WITH_LEN("mysql"),
-                           C_STRING_WITH_LEN("user"), "user", TL_WRITE);
-  tables[1].init_one_table(C_STRING_WITH_LEN("mysql"),
-                           C_STRING_WITH_LEN("tables_priv"),
-                           "tables_priv", TL_WRITE);
-  tables[2].init_one_table(C_STRING_WITH_LEN("mysql"),
-                           C_STRING_WITH_LEN("columns_priv"),
-                           "columns_priv", TL_WRITE);
-  tables[0].next_local= tables[0].next_global= tables+1;
-  /* Don't open column table if we don't need it ! */
-  if (column_priv || (revoke_grant && ((rights & COL_ACLS) || columns.elements)))
-    tables[1].next_local= tables[1].next_global= tables+2;
-
-#ifdef HAVE_REPLICATION
   /*
-    GRANT and REVOKE are applied the slave in/exclusion rules as they are
-    some kind of updates to the mysql.% tables.
+    Open the mysql.user and mysql.tables_priv tables.
+    Don't open column table if we don't need it !
   */
-  if (thd->slave_thread &&
-      (rpl_filter= thd->system_thread_info.rpl_sql_info->rpl_filter)->is_on())
-  {
-    /*
-      The tables must be marked "updating" so that tables_ok() takes them into
-      account in tests.
-    */
-    tables[0].updating= tables[1].updating= tables[2].updating= 1;
-    if (!(thd->spcont || rpl_filter->tables_ok(0, tables)))
-      DBUG_RETURN(FALSE);
-  }
-#endif
+  int maybe_columns_priv= 0;
+  if (column_priv ||
+      (revoke_grant && ((rights & COL_ACLS) || columns.elements)))
+    maybe_columns_priv= Table_columns_priv;
+
+  tl= init_priv_tables(thd, tables, TL_WRITE, Table_user | Table_tables_priv |
+                       maybe_columns_priv);
+  if (!tl)
+    DBUG_RETURN(0);
 
   /*
     The lock api is depending on the thd->lex variable which needs to be
@@ -5511,7 +5547,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
     this value corresponds to the statement being executed.
   */
   thd->lex->sql_command= backup.sql_command;
-  if (open_and_lock_tables(thd, tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
+  if (open_and_lock_tables(thd, tl, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
   {						// Should never happen
     thd->lex->restore_backup_query_tables_list(&backup);
     DBUG_RETURN(TRUE);				/* purecov: deadcode */
@@ -5539,7 +5575,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
     if (copy_and_check_auth(Str, tmp_Str, thd->lex))
       error= -1;
     else
-      error=replace_user_table(thd, tables[0].table, *Str,
+      error=replace_user_table(thd, tables[USER_TABLE].table, *Str,
                                0, revoke_grant, create_new_users,
                                MY_TEST(thd->variables.sql_mode &
                                        MODE_NO_AUTO_CREATE_USER));
@@ -5610,17 +5646,18 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
 
     /* update table and columns */
 
-    if (replace_table_table(thd, grant_table, tables[1].table, *Str,
-			    db_name, table_name,
+    if (replace_table_table(thd, grant_table, tables[TABLES_PRIV_TABLE].table,
+                            *Str, db_name, table_name,
 			    rights, column_priv, revoke_grant))
     {
       /* Should only happen if table is crashed */
       result= TRUE;			       /* purecov: deadcode */
     }
-    else if (tables[2].table)
+    else if (tables[COLUMNS_PRIV_TABLE].table)
     {
-      if (replace_column_table(grant_table, tables[2].table, *Str, columns,
-                               db_name, table_name, rights, revoke_grant))
+      if (replace_column_table(grant_table, tables[COLUMNS_PRIV_TABLE].table,
+                               *Str, columns, db_name, table_name, rights,
+                               revoke_grant))
       {
 	result= TRUE;
       }
@@ -5671,10 +5708,9 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
 {
   List_iterator <LEX_USER> str_list (user_list);
   LEX_USER *Str, *tmp_Str;
-  TABLE_LIST tables[2];
+  TABLE_LIST tables[TABLES_MAX], *tl;
   bool create_new_users=0, result=0;
   char *db_name, *table_name;
-  Rpl_filter *rpl_filter;
   DBUG_ENTER("mysql_routine_grant");
 
   if (!initialized)
@@ -5697,34 +5733,11 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
   }
 
   /* open the mysql.user and mysql.procs_priv tables */
+  tl= init_priv_tables(thd, tables, TL_WRITE, Table_user | Table_procs_priv);
+  if (!tl)
+    DBUG_RETURN(FALSE);
 
-  tables[0].init_one_table(C_STRING_WITH_LEN("mysql"),
-                           C_STRING_WITH_LEN("user"), "user", TL_WRITE);
-  tables[1].init_one_table(C_STRING_WITH_LEN("mysql"),
-                           C_STRING_WITH_LEN("procs_priv"), "procs_priv", TL_WRITE);
-  tables[0].next_local= tables[0].next_global= tables+1;
-
-#ifdef HAVE_REPLICATION
-  /*
-    GRANT and REVOKE are applied the slave in/exclusion rules as they are
-    some kind of updates to the mysql.% tables.
-  */
-  if (thd->slave_thread &&
-      (rpl_filter= thd->system_thread_info.rpl_sql_info->rpl_filter)->is_on())
-  {
-    /*
-      The tables must be marked "updating" so that tables_ok() takes them into
-      account in tests.
-    */
-    tables[0].updating= tables[1].updating= 1;
-    if (!(thd->spcont || rpl_filter->tables_ok(0, tables)))
-    {
-      DBUG_RETURN(FALSE);
-    }
-  }
-#endif
-
-  if (open_and_lock_tables(thd, tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
+  if (open_and_lock_tables(thd, tl, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
     DBUG_RETURN(TRUE);
 
   DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
@@ -5748,7 +5761,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
       continue;
     }
     /* Create user if needed */
-    error=replace_user_table(thd, tables[0].table, *Str,
+    error=replace_user_table(thd, tables[USER_TABLE].table, *Str,
 			     0, revoke_grant, create_new_users,
                              MY_TEST(thd->variables.sql_mode &
                                      MODE_NO_AUTO_CREATE_USER));
@@ -5783,8 +5796,9 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
       }
     }
 
-    if (replace_routine_table(thd, grant_name, tables[1].table, *Str,
-                              db_name, table_name, is_proc, rights,
+    if (no_such_table(tables + PROCS_PRIV_TABLE) ||
+        replace_routine_table(thd, grant_name, tables[PROCS_PRIV_TABLE].table,
+                              *Str, db_name, table_name, is_proc, rights,
                               revoke_grant) != 0)
     {
       result= TRUE;
@@ -5923,16 +5937,13 @@ bool mysql_grant_role(THD *thd, List <LEX_USER> &list, bool revoke)
   no_auto_create_user= MY_TEST(thd->variables.sql_mode &
                                MODE_NO_AUTO_CREATE_USER);
 
-  TABLE_LIST tables[2];
-  tables[0].init_one_table(C_STRING_WITH_LEN("mysql"),
-                           C_STRING_WITH_LEN("roles_mapping"),
-                           "roles_mapping", TL_WRITE);
-  tables[1].init_one_table(C_STRING_WITH_LEN("mysql"),
-                           C_STRING_WITH_LEN("user"), "user", TL_WRITE);
-  tables[0].next_local= tables[0].next_global= tables+1;
+  TABLE_LIST tables[TABLES_MAX], *tl;
+  tl= init_priv_tables(thd, tables, TL_WRITE, Table_user | Table_roles_mapping);
+  if (!tl)
+    DBUG_RETURN(FALSE);
 
-  if (open_and_lock_tables(thd, tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
-    DBUG_RETURN(TRUE);                          /* purecov: deadcode */
+  if (open_and_lock_tables(thd, tl, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
+    DBUG_RETURN(TRUE);
 
   mysql_rwlock_wrlock(&LOCK_grant);
   mysql_mutex_lock(&acl_cache->lock);
@@ -6028,7 +6039,7 @@ bool mysql_grant_role(THD *thd, List <LEX_USER> &list, bool revoke)
       user_combo.user = username;
 
       /* create the user if it does not exist */
-      if (replace_user_table(thd, tables[1].table, user_combo, 0,
+      if (replace_user_table(thd, tables[USER_TABLE].table, user_combo, 0,
                              false, create_new_user,
                              no_auto_create_user))
       {
@@ -6094,7 +6105,7 @@ bool mysql_grant_role(THD *thd, List <LEX_USER> &list, bool revoke)
     }
 
     /* write into the roles_mapping table */
-    if (replace_roles_mapping_table(tables[0].table,
+    if (replace_roles_mapping_table(tables[ROLES_MAPPING_TABLE].table,
                                     &username, &hostname, &rolename,
                                     thd->lex->with_admin_option,
                                     hash_entry, revoke))
@@ -6145,8 +6156,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
   LEX_USER *Str, *tmp_Str, *proxied_user= NULL;
   char tmp_db[SAFE_NAME_LEN+1];
   bool create_new_users=0;
-  TABLE_LIST tables[2];
-  Rpl_filter *rpl_filter;
+  TABLE_LIST tables[TABLES_MAX], *tl;
   DBUG_ENTER("mysql_grant");
 
   if (!initialized)
@@ -6175,40 +6185,12 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
   }
 
   /* open the mysql.user and mysql.db or mysql.proxies_priv tables */
-  tables[0].init_one_table(C_STRING_WITH_LEN("mysql"),
-                           C_STRING_WITH_LEN("user"), "user", TL_WRITE);
-  if (is_proxy)
-
-    tables[1].init_one_table(C_STRING_WITH_LEN("mysql"),
-                             C_STRING_WITH_LEN("proxies_priv"),
-                             "proxies_priv",
-                             TL_WRITE);
-  else
-    tables[1].init_one_table(C_STRING_WITH_LEN("mysql"),
-                             C_STRING_WITH_LEN("db"),
-                             "db",
-                             TL_WRITE);
-  tables[0].next_local= tables[0].next_global= tables+1;
-
-#ifdef HAVE_REPLICATION
-  /*
-    GRANT and REVOKE are applied the slave in/exclusion rules as they are
-    some kind of updates to the mysql.% tables.
-  */
-  if (thd->slave_thread &&
-      (rpl_filter= thd->system_thread_info.rpl_sql_info->rpl_filter)->is_on())
-  {
-    /*
-      The tables must be marked "updating" so that tables_ok() takes them into
-      account in tests.
-    */
-    tables[0].updating= tables[1].updating= 1;
-    if (!(thd->spcont || rpl_filter->tables_ok(0, tables)))
-      DBUG_RETURN(FALSE);
-  }
-#endif
+  tl= init_priv_tables(thd, tables, TL_WRITE, Table_user |
+                       (is_proxy ? Table_proxies_priv : Table_db));
+  if (!tl)
+    DBUG_RETURN(FALSE);
 
-  if (open_and_lock_tables(thd, tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
+  if (open_and_lock_tables(thd, tl, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
     DBUG_RETURN(TRUE);				/* purecov: deadcode */
 
   DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
@@ -6240,7 +6222,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
     if (copy_and_check_auth(Str, tmp_Str, thd->lex))
       result= -1;
     else
-    if (replace_user_table(thd, tables[0].table, *Str,
+    if (replace_user_table(thd, tables[USER_TABLE].table, *Str,
                            (!db ? rights : 0), revoke_grant, create_new_users,
                            MY_TEST(thd->variables.sql_mode &
                                    MODE_NO_AUTO_CREATE_USER)))
@@ -6250,7 +6232,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
       ulong db_rights= rights & DB_ACLS;
       if (db_rights  == rights)
       {
-	if (replace_db_table(tables[1].table, db, *Str, db_rights,
+	if (replace_db_table(tables[DB_TABLE].table, db, *Str, db_rights,
 			     revoke_grant))
 	  result= -1;
       }
@@ -6262,9 +6244,11 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
     }
     else if (is_proxy)
     {
-      if (replace_proxies_priv_table (thd, tables[1].table, Str, proxied_user,
-                                    rights & GRANT_ACL ? TRUE : FALSE,
-                                    revoke_grant))
+      if (no_such_table(tables + PROXIES_PRIV_TABLE) ||
+          replace_proxies_priv_table (thd, tables[PROXIES_PRIV_TABLE].table,
+                                      Str, proxied_user,
+                                      rights & GRANT_ACL ? TRUE : FALSE,
+                                      revoke_grant))
         result= -1;
     }
     if (Str->is_role())
@@ -6365,9 +6349,9 @@ static my_bool grant_load(THD *thd, TABLE_LIST *tables)
                       0,0,0, (my_hash_get_key) get_grant_table, 0,0);
   init_sql_alloc(&grant_memroot, ACL_ALLOC_BLOCK_SIZE, 0, MYF(0));
 
-  t_table= tables[0].table;
-  c_table= tables[1].table;
-  p_table= tables[2].table; // this can be NULL
+  t_table= tables[TABLES_PRIV_TABLE].table;
+  c_table= tables[COLUMNS_PRIV_TABLE].table;
+  p_table= tables[PROCS_PRIV_TABLE].table; // this can be NULL
 
   if (t_table->file->ha_index_init(0, 1))
     goto end_index_init;
@@ -6518,7 +6502,7 @@ my_bool role_propagate_grants_action(void *ptr, void *unused __attribute__((unus
 
 my_bool grant_reload(THD *thd)
 {
-  TABLE_LIST tables[3];
+  TABLE_LIST tables[TABLES_MAX], *tl;
   HASH old_column_priv_hash, old_proc_priv_hash, old_func_priv_hash;
   MEM_ROOT old_mem;
   my_bool return_val= 1;
@@ -6528,25 +6512,14 @@ my_bool grant_reload(THD *thd)
   if (!initialized)
     DBUG_RETURN(0);
 
-  tables[0].init_one_table(C_STRING_WITH_LEN("mysql"),
-                           C_STRING_WITH_LEN("tables_priv"),
-                           "tables_priv", TL_READ);
-  tables[1].init_one_table(C_STRING_WITH_LEN("mysql"),
-                           C_STRING_WITH_LEN("columns_priv"),
-                           "columns_priv", TL_READ);
-  tables[2].init_one_table(C_STRING_WITH_LEN("mysql"),
-                           C_STRING_WITH_LEN("procs_priv"),
-                          "procs_priv", TL_READ);
-  tables[0].next_local= tables[0].next_global= tables+1;
-  tables[1].next_local= tables[1].next_global= tables+2;
-  tables[0].open_type= tables[1].open_type= tables[2].open_type= OT_BASE_ONLY;
-  tables[2].open_strategy= TABLE_LIST::OPEN_IF_EXISTS;
+  tl= init_priv_tables(thd, tables, TL_READ, Table_tables_priv |
+                       Table_columns_priv | Table_procs_priv);
 
   /*
     To avoid deadlocks we should obtain table locks before
     obtaining LOCK_grant rwlock.
   */
-  if (open_and_lock_tables(thd, tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
+  if (open_and_lock_tables(thd, tl, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
     goto end;
 
   mysql_rwlock_wrlock(&LOCK_grant);
@@ -8210,26 +8183,15 @@ void get_mqh(const char *user, const char *host, USER_CONN *uc)
     thd                         The current thread.
     tables (out)                The 7 elements array for the opened tables.
 
-  DESCRIPTION
-    Tables are numbered as follows:
-    0 user
-    1 db
-    2 tables_priv
-    3 columns_priv
-    4 procs_priv
-    5 proxies_priv
-    6 roles_mapping
-
   RETURN
     1           Skip GRANT handling during replication.
     0           OK.
     < 0         Error.
 */
 
-#define GRANT_TABLES 7
 static int open_grant_tables(THD *thd, TABLE_LIST *tables)
 {
-  Rpl_filter *rpl_filter;
+  TABLE_LIST *tl;
   DBUG_ENTER("open_grant_tables");
 
   if (!initialized)
@@ -8238,60 +8200,14 @@ static int open_grant_tables(THD *thd, TABLE_LIST *tables)
     DBUG_RETURN(-1);
   }
 
-  tables->init_one_table(C_STRING_WITH_LEN("mysql"),
-                         C_STRING_WITH_LEN("user"), "user", TL_WRITE);
-  (tables+1)->init_one_table(C_STRING_WITH_LEN("mysql"),
-                             C_STRING_WITH_LEN("db"), "db", TL_WRITE);
-  (tables+2)->init_one_table(C_STRING_WITH_LEN("mysql"),
-                             C_STRING_WITH_LEN("tables_priv"),
-                             "tables_priv", TL_WRITE);
-  (tables+3)->init_one_table(C_STRING_WITH_LEN("mysql"),
-                             C_STRING_WITH_LEN("columns_priv"),
-                             "columns_priv", TL_WRITE);
-  (tables+4)->init_one_table(C_STRING_WITH_LEN("mysql"),
-                             C_STRING_WITH_LEN("procs_priv"),
-                             "procs_priv", TL_WRITE);
-  (tables+5)->init_one_table(C_STRING_WITH_LEN("mysql"),
-                             C_STRING_WITH_LEN("proxies_priv"),
-                             "proxies_priv", TL_WRITE);
-  (tables+5)->open_strategy= TABLE_LIST::OPEN_IF_EXISTS;
-  (tables+6)->init_one_table(C_STRING_WITH_LEN("mysql"),
-                             C_STRING_WITH_LEN("roles_mapping"),
-                             "roles_mapping", TL_WRITE);
-  (tables+6)->open_strategy= TABLE_LIST::OPEN_IF_EXISTS;
-
-
-  tables->next_local= tables->next_global= tables + 1;
-  (tables+1)->next_local= (tables+1)->next_global= tables + 2;
-  (tables+2)->next_local= (tables+2)->next_global= tables + 3;
-  (tables+3)->next_local= (tables+3)->next_global= tables + 4;
-  (tables+4)->next_local= (tables+4)->next_global= tables + 5;
-  (tables+5)->next_local= (tables+5)->next_global= tables + 6;
-
-#ifdef HAVE_REPLICATION
-  /*
-    GRANT and REVOKE are applied the slave in/exclusion rules as they are
-    some kind of updates to the mysql.% tables.
-  */
-  if (thd->slave_thread &&
-      (rpl_filter= thd->system_thread_info.rpl_sql_info->rpl_filter)->is_on())
-  {
-    /*
-      The tables must be marked "updating" so that tables_ok() takes them into
-      account in tests.
-    */
-    tables[0].updating= tables[1].updating= tables[2].updating=
-      tables[3].updating= tables[4].updating= tables[5].updating=
-      tables[6].updating= 1;
-    if (!(thd->spcont || rpl_filter->tables_ok(0, tables)))
-      DBUG_RETURN(1);
-    tables[0].updating= tables[1].updating= tables[2].updating=
-      tables[3].updating= tables[4].updating= tables[5].updating=
-      tables[6].updating= 0;
-  }
-#endif
+  tl= init_priv_tables(thd, tables, TL_WRITE, Table_user | Table_db |
+                       Table_tables_priv | Table_columns_priv |
+                       Table_procs_priv | Table_proxies_priv |
+                       Table_roles_mapping);
+  if (!tl)
+    DBUG_RETURN(1);
 
-  if (open_and_lock_tables(thd, tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
+  if (open_and_lock_tables(thd, tl, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
   {						// This should never happen
     DBUG_RETURN(-1);
   }
@@ -8371,7 +8287,7 @@ static int modify_grant_table(TABLE *table, Field *host_field,
 }
 
 /*
-  Handle the roles_mappings privilege table
+  Handle the roles_mapping privilege table
 */
 static int handle_roles_mappings_table(TABLE *table, bool drop,
                                        LEX_USER *user_from, LEX_USER *user_to)
@@ -8392,7 +8308,7 @@ static int handle_roles_mappings_table(TABLE *table, bool drop,
   Field *user_field= table->field[1];
   Field *role_field= table->field[2];
 
-  DBUG_PRINT("info", ("Rewriting entry in roles_mappings table: %s@%s",
+  DBUG_PRINT("info", ("Rewriting entry in roles_mapping table: %s@%s",
                       user_from->user.str, user_from->host.str));
   table->use_all_columns();
   if ((error= table->file->ha_rnd_init(1)))
@@ -8472,14 +8388,6 @@ static int handle_roles_mappings_table(TABLE *table, bool drop,
     Delete from grant table if drop is true.
     Update in grant table if drop is false and user_to is not NULL.
     Search in grant table if drop is false and user_to is NULL.
-    Tables are numbered as follows:
-    0 user
-    1 db
-    2 tables_priv
-    3 columns_priv
-    4 procs_priv
-    5 proxies_priv
-    6 roles_mapping
 
   RETURN
     > 0         At least one record matched.
@@ -8487,14 +8395,16 @@ static int handle_roles_mappings_table(TABLE *table, bool drop,
     < 0         Error.
 */
 
-static int handle_grant_table(TABLE_LIST *tables, uint table_no, bool drop,
+static int handle_grant_table(TABLE_LIST *tables,
+                              enum enum_acl_tables table_no, bool drop,
                               LEX_USER *user_from, LEX_USER *user_to)
 {
   int result= 0;
   int error;
   TABLE *table= tables[table_no].table;
   Field *host_field= table->field[0];
-  Field *user_field= table->field[table_no && table_no != 5 ? 2 : 1];
+  Field *user_field= table->field[table_no == USER_TABLE ||
+                                  table_no == PROXIES_PRIV_TABLE ? 1 : 2];
   const char *host_str= user_from->host.str;
   const char *user_str= user_from->user.str;
   const char *host;
@@ -8504,14 +8414,14 @@ static int handle_grant_table(TABLE_LIST *tables, uint table_no, bool drop,
   DBUG_ENTER("handle_grant_table");
   THD *thd= current_thd;
 
-  if (table_no == 6)
+  if (table_no == ROLES_MAPPING_TABLE)
   {
     result= handle_roles_mappings_table(table, drop, user_from, user_to);
     DBUG_RETURN(result);
   }
 
   table->use_all_columns();
-  if (! table_no) // mysql.user table
+  if (table_no == USER_TABLE) // mysql.user table
   {
     /*
       The 'user' table has an unique index on (host, user).
@@ -8587,7 +8497,7 @@ static int handle_grant_table(TABLE_LIST *tables, uint table_no, bool drop,
         user= safe_str(get_field(thd->mem_root, user_field));
 
 #ifdef EXTRA_DEBUG
-        if (table_no != 5)
+        if (table_no != PROXIES_PRIV_TABLE)
         {
           DBUG_PRINT("loop",("scan fields: '%s'@'%s' '%s' '%s' '%s'",
                              user, host,
@@ -9011,7 +8921,7 @@ static int handle_grant_data(TABLE_LIST *tables, bool drop,
   }
 
   /* Handle db table. */
-  if ((found= handle_grant_table(tables, 1, drop, user_from, user_to)) < 0)
+  if ((found= handle_grant_table(tables, DB_TABLE, drop, user_from, user_to)) < 0)
   {
     /* Handle of table failed, don't touch the in-memory array. */
     result= -1;
@@ -9031,7 +8941,7 @@ static int handle_grant_data(TABLE_LIST *tables, bool drop,
   }
 
   /* Handle stored routines table. */
-  if ((found= handle_grant_table(tables, 4, drop, user_from, user_to)) < 0)
+  if ((found= handle_grant_table(tables, PROCS_PRIV_TABLE, drop, user_from, user_to)) < 0)
   {
     /* Handle of table failed, don't touch in-memory array. */
     result= -1;
@@ -9059,7 +8969,7 @@ static int handle_grant_data(TABLE_LIST *tables, bool drop,
   }
 
   /* Handle tables table. */
-  if ((found= handle_grant_table(tables, 2, drop, user_from, user_to)) < 0)
+  if ((found= handle_grant_table(tables, TABLES_PRIV_TABLE, drop, user_from, user_to)) < 0)
   {
     /* Handle of table failed, don't touch columns and in-memory array. */
     result= -1;
@@ -9075,7 +8985,7 @@ static int handle_grant_data(TABLE_LIST *tables, bool drop,
     }
 
     /* Handle columns table. */
-    if ((found= handle_grant_table(tables, 3, drop, user_from, user_to)) < 0)
+    if ((found= handle_grant_table(tables, COLUMNS_PRIV_TABLE, drop, user_from, user_to)) < 0)
     {
       /* Handle of table failed, don't touch the in-memory array. */
       result= -1;
@@ -9092,9 +9002,9 @@ static int handle_grant_data(TABLE_LIST *tables, bool drop,
   }
 
   /* Handle proxies_priv table. */
-  if (tables[5].table)
+  if (tables[PROXIES_PRIV_TABLE].table)
   {
-    if ((found= handle_grant_table(tables, 5, drop, user_from, user_to)) < 0)
+    if ((found= handle_grant_table(tables, PROXIES_PRIV_TABLE, drop, user_from, user_to)) < 0)
     {
       /* Handle of table failed, don't touch the in-memory array. */
       result= -1;
@@ -9110,10 +9020,10 @@ static int handle_grant_data(TABLE_LIST *tables, bool drop,
     }
   }
 
-  /* Handle roles_mappings table. */
-  if (tables[6].table)
+  /* Handle roles_mapping table. */
+  if (tables[ROLES_MAPPING_TABLE].table)
   {
-    if ((found= handle_grant_table(tables, 6, drop, user_from, user_to)) < 0)
+    if ((found= handle_grant_table(tables, ROLES_MAPPING_TABLE, drop, user_from, user_to)) < 0)
     {
       /* Handle of table failed, don't touch the in-memory array. */
       result= -1;
@@ -9130,7 +9040,7 @@ static int handle_grant_data(TABLE_LIST *tables, bool drop,
   }
 
   /* Handle user table. */
-  if ((found= handle_grant_table(tables, 0, drop, user_from, user_to)) < 0)
+  if ((found= handle_grant_table(tables, USER_TABLE, drop, user_from, user_to)) < 0)
   {
     /* Handle of table failed, don't touch the in-memory array. */
     result= -1;
@@ -9169,7 +9079,7 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list, bool handle_as_role)
   String wrong_users;
   LEX_USER *user_name;
   List_iterator <LEX_USER> user_list(list);
-  TABLE_LIST tables[GRANT_TABLES];
+  TABLE_LIST tables[TABLES_MAX];
   bool some_users_created= FALSE;
   DBUG_ENTER("mysql_create_user");
   DBUG_PRINT("entry", ("Handle as %s", handle_as_role ? "role" : "user"));
@@ -9223,7 +9133,7 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list, bool handle_as_role)
     }
 
     some_users_created= TRUE;
-    if (replace_user_table(thd, tables[0].table, *user_name, 0, 0, 1, 0))
+    if (replace_user_table(thd, tables[USER_TABLE].table, *user_name, 0, 0, 1, 0))
     {
       append_user(thd, &wrong_users, user_name);
       result= TRUE;
@@ -9244,7 +9154,7 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list, bool handle_as_role)
       if (grantee)
         add_role_user_mapping(grantee, role);
 
-      if (replace_roles_mapping_table(tables[6].table,
+      if (replace_roles_mapping_table(tables[ROLES_MAPPING_TABLE].table,
                                       &thd->lex->definer->user,
                                       &thd->lex->definer->host,
                                       &user_name->user, true,
@@ -9295,7 +9205,7 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list, bool handle_as_role)
   String wrong_users;
   LEX_USER *user_name, *tmp_user_name;
   List_iterator <LEX_USER> user_list(list);
-  TABLE_LIST tables[GRANT_TABLES];
+  TABLE_LIST tables[TABLES_MAX];
   bool some_users_deleted= FALSE;
   ulonglong old_sql_mode= thd->variables.sql_mode;
   DBUG_ENTER("mysql_drop_user");
@@ -9385,7 +9295,7 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list)
   LEX_USER *user_from, *tmp_user_from;
   LEX_USER *user_to, *tmp_user_to;
   List_iterator <LEX_USER> user_list(list);
-  TABLE_LIST tables[GRANT_TABLES];
+  TABLE_LIST tables[TABLES_MAX];
   bool some_users_renamed= FALSE;
   DBUG_ENTER("mysql_rename_user");
 
@@ -9472,7 +9382,7 @@ bool mysql_revoke_all(THD *thd,  List <LEX_USER> &list)
   uint counter, revoked, is_proc;
   int result;
   ACL_DB *acl_db;
-  TABLE_LIST tables[GRANT_TABLES];
+  TABLE_LIST tables[TABLES_MAX];
   DBUG_ENTER("mysql_revoke_all");
 
   if ((result= open_grant_tables(thd, tables)))
@@ -9501,7 +9411,8 @@ bool mysql_revoke_all(THD *thd,  List <LEX_USER> &list)
       continue;
     }
 
-    if (replace_user_table(thd, tables[0].table, *lex_user, ~(ulong)0, 1, 0, 0))
+    if (replace_user_table(thd, tables[USER_TABLE].table, *lex_user,
+                           ~(ulong)0, 1, 0, 0))
     {
       result= -1;
       continue;
@@ -9527,7 +9438,7 @@ bool mysql_revoke_all(THD *thd,  List <LEX_USER> &list)
 	if (!strcmp(lex_user->user.str, user) &&
             !strcmp(lex_user->host.str, host))
 	{
-	  if (!replace_db_table(tables[1].table, acl_db->db, *lex_user,
+	  if (!replace_db_table(tables[DB_TABLE].table, acl_db->db, *lex_user,
                                 ~(ulong)0, 1))
 	  {
 	    /*
@@ -9557,10 +9468,10 @@ bool mysql_revoke_all(THD *thd,  List <LEX_USER> &list)
 	if (!strcmp(lex_user->user.str,user) &&
             !strcmp(lex_user->host.str, host))
 	{
-	  if (replace_table_table(thd,grant_table,tables[2].table,*lex_user,
-				  grant_table->db,
-				  grant_table->tname,
-				  ~(ulong)0, 0, 1))
+	  if (replace_table_table(thd, grant_table,
+                                  tables[TABLES_PRIV_TABLE].table,
+                                  *lex_user, grant_table->db,
+				  grant_table->tname, ~(ulong)0, 0, 1))
 	  {
 	    result= -1;
 	  }
@@ -9572,11 +9483,10 @@ bool mysql_revoke_all(THD *thd,  List <LEX_USER> &list)
 	      continue;
 	    }
 	    List<LEX_COLUMN> columns;
-	    if (!replace_column_table(grant_table,tables[3].table, *lex_user,
-				      columns,
-				      grant_table->db,
-				      grant_table->tname,
-				      ~(ulong)0, 1))
+	    if (!replace_column_table(grant_table,
+                                      tables[COLUMNS_PRIV_TABLE].table,
+                                      *lex_user, columns, grant_table->db,
+				      grant_table->tname, ~(ulong)0, 1))
 	    {
 	      revoked= 1;
 	      continue;
@@ -9601,11 +9511,10 @@ bool mysql_revoke_all(THD *thd,  List <LEX_USER> &list)
 	if (!strcmp(lex_user->user.str,user) &&
             !strcmp(lex_user->host.str, host))
 	{
-	  if (replace_routine_table(thd,grant_proc,tables[4].table,*lex_user,
-				  grant_proc->db,
-				  grant_proc->tname,
-                                  is_proc,
-				  ~(ulong)0, 1) == 0)
+	  if (replace_routine_table(thd, grant_proc,
+                                    tables[PROCS_PRIV_TABLE].table, *lex_user,
+                                    grant_proc->db, grant_proc->tname,
+                                    is_proc, ~(ulong)0, 1) == 0)
 	  {
 	    revoked= 1;
 	    continue;
@@ -9638,9 +9547,8 @@ bool mysql_revoke_all(THD *thd,  List <LEX_USER> &list)
       ROLE_GRANT_PAIR *pair = find_role_grant_pair(&lex_user->user,
                                                    &lex_user->host,
                                                    &role_grant->user);
-      if (replace_roles_mapping_table(tables[6].table,
-                                      &lex_user->user,
-                                      &lex_user->host,
+      if (replace_roles_mapping_table(tables[ROLES_MAPPING_TABLE].table,
+                                      &lex_user->user, &lex_user->host,
                                       &role_grant->user, false, pair, true))
       {
         result= -1; //Something went wrong
@@ -9769,7 +9677,7 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name,
 {
   uint counter, revoked;
   int result;
-  TABLE_LIST tables[GRANT_TABLES];
+  TABLE_LIST tables[TABLES_MAX];
   HASH *hash= is_proc ? &proc_priv_hash : &func_priv_hash;
   Silence_routine_definer_errors error_handler;
   DBUG_ENTER("sp_revoke_privileges");
@@ -9799,7 +9707,8 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name,
 	lex_user.user.length= strlen(grant_proc->user);
         lex_user.host.str= safe_str(grant_proc->host.hostname);
         lex_user.host.length= strlen(lex_user.host.str);
-	if (replace_routine_table(thd,grant_proc,tables[4].table,lex_user,
+	if (replace_routine_table(thd, grant_proc,
+                                  tables[PROCS_PRIV_TABLE].table, lex_user,
 				  grant_proc->db, grant_proc->tname,
                                   is_proc, ~(ulong)0, 1) == 0)
 	{
