MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Alexander Nozdrin Date:May 26 2010 10:18am
Subject:bzr commit into mysql-trunk-bugfixing branch (alik:3057) Bug#27480
View as plain text  
#At file:///mnt/raid/alik/MySQL/bzr/00/bug27480/mysql-trunk-bf-bug27480/ based on revid:jon.hauglid@stripped

 3057 Alexander Nozdrin	2010-05-26
      Preliminary patch for Bug#27480 (Extend CREATE TEMPORARY TABLES
      privilege to allow temp table operations). All tests pass.

    modified:
      sql/sql_acl.cc
      sql/sql_base.cc
      sql/sql_base.h
      sql/sql_class.h
      sql/sql_insert.cc
      sql/sql_parse.cc
=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc	2010-04-28 10:04:11 +0000
+++ b/sql/sql_acl.cc	2010-05-26 10:18:31 +0000
@@ -3988,6 +3988,19 @@ end:
   DBUG_RETURN(return_val);
 }
 
+static bool check_grant_for_temp_table(THD *thd, TABLE_LIST *tl)
+{
+  TABLE *table= tl->table;
+
+  if (!table && tl->correspondent_table)
+    table= tl->correspondent_table->table;
+
+  return
+    !(table && table->s &&
+      table->s->tmp_table != NO_TMP_TABLE &&
+      !check_access(thd, CREATE_TMP_ACL, table->s->db.str, NULL, NULL, 0, TRUE));
+}
+
 
 /**
   @brief Check table level grants
@@ -4117,9 +4130,24 @@ bool check_grant(THD *thd, ulong want_ac
       }
       continue;
     }
-    if (!(grant_table= table_hash_search(sctx->host, sctx->ip,
-                                         table->get_db_name(), sctx->priv_user,
-                                         table->get_table_name(), FALSE)))
+
+    grant_table= table_hash_search(sctx->host, sctx->ip,
+                                   table->get_db_name(), sctx->priv_user,
+                                   table->get_table_name(), FALSE);
+
+    if (grant_table)
+    {
+      table->grant.grant_table=grant_table;	// Remember for column test
+      table->grant.version=grant_version;
+      table->grant.privilege|= grant_table->privs;
+      table->grant.want_privilege= ((want_access & COL_ACLS)
+                                    & ~table->grant.privilege);
+    }
+
+    if (!check_grant_for_temp_table(thd, table))
+      continue;
+
+    if (!grant_table)
     {
       want_access &= ~table->grant.privilege;
       goto err;					// No grants
@@ -4132,12 +4160,6 @@ bool check_grant(THD *thd, ulong want_ac
     if (any_combination_will_do)
       continue;
 
-    table->grant.grant_table=grant_table;	// Remember for column test
-    table->grant.version=grant_version;
-    table->grant.privilege|= grant_table->privs;
-    table->grant.want_privilege= ((want_access & COL_ACLS)
-				  & ~table->grant.privilege);
-
     if (!(~table->grant.privilege & want_access))
       continue;
 
@@ -4294,6 +4316,9 @@ bool check_column_grant_in_table_ref(THD
     table_name= table->s->table_name.str;
   }
 
+  if (!check_grant_for_temp_table(thd, table_ref))
+    return FALSE;
+
   if (grant->want_privilege)
     return check_grant_column(thd, grant, db_name, table_name, name,
                               length, sctx);
@@ -4340,6 +4365,11 @@ bool check_grant_all_columns(THD *thd, u
   for (; !fields->end_of_fields(); fields->next())
   {
     const char *field_name= fields->name();
+    bool is_tmp_table= FALSE;
+    Field *field= fields->field();
+
+    if (field && field->table && field->table->s)
+      is_tmp_table= field->table->s->tmp_table != NO_TMP_TABLE;
 
     if (table_name != fields->get_table_name())
     {
@@ -4361,19 +4391,27 @@ bool check_grant_all_columns(THD *thd, u
         }
 
         grant_table= grant->grant_table;
-        DBUG_ASSERT (grant_table);
+        DBUG_ASSERT(grant_table || !grant_table && is_tmp_table);
       }
     }
 
     if (want_access)
     {
-      GRANT_COLUMN *grant_column= 
-        column_hash_search(grant_table, field_name,
-                           (uint) strlen(field_name));
-      if (grant_column)
-        using_column_privileges= TRUE;
-      if (!grant_column || (~grant_column->rights & want_access))
-        goto err;
+      if (is_tmp_table)
+      {
+        if (check_access(thd, CREATE_TMP_ACL, db_name, NULL, NULL, 0, TRUE))
+          goto err;
+      }
+      else
+      {
+        GRANT_COLUMN *grant_column=
+          column_hash_search(grant_table, field_name,
+            (uint) strlen(field_name));
+        if (grant_column)
+          using_column_privileges= TRUE;
+        if (!grant_column || (~grant_column->rights & want_access))
+          goto err;
+      }
     }
   }
   mysql_rwlock_unlock(&LOCK_grant);

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2010-05-21 12:41:24 +0000
+++ b/sql/sql_base.cc	2010-05-26 10:18:31 +0000
@@ -1969,9 +1969,12 @@ TABLE *find_temporary_table(THD *thd, co
 {
   TABLE_LIST table_list;
 
+  DBUG_ENTER("find_temporary_table(db_name, table_name)");
+
   table_list.db= (char*) db;
   table_list.table_name= (char*) table_name;
-  return find_temporary_table(thd, &table_list);
+
+  DBUG_RETURN(find_temporary_table(thd, &table_list));
 }
 
 
@@ -1979,16 +1982,26 @@ TABLE *find_temporary_table(THD *thd, TA
 {
   char	key[MAX_DBKEY_LENGTH];
   uint	key_length;
-  TABLE *table;
-  DBUG_ENTER("find_temporary_table");
+
+  DBUG_ENTER("find_temporary_table(TABLE_LIST)");
   DBUG_PRINT("enter", ("table: '%s'.'%s'",
                        table_list->db, table_list->table_name));
 
   key_length= create_table_def_key(thd, key, table_list, 1);
-  for (table=thd->temporary_tables ; table ; table= table->next)
+  DBUG_RETURN(find_temporary_table(thd, key, key_length));
+}
+
+
+TABLE *find_temporary_table(THD *thd,
+                            const char *table_key,
+                            uint table_key_length)
+{
+
+  DBUG_ENTER("find_temporary_table(table_key)");
+  for (TABLE *table= thd->temporary_tables; table; table= table->next)
   {
-    if (table->s->table_cache_key.length == key_length &&
-	!memcmp(table->s->table_cache_key.str, key, key_length))
+    if (table->s->table_cache_key.length == table_key_length &&
+        !memcmp(table->s->table_cache_key.str, table_key, table_key_length))
     {
       DBUG_PRINT("info",
                  ("Found table. server_id: %u  pseudo_thread_id: %lu",
@@ -1997,7 +2010,7 @@ TABLE *find_temporary_table(THD *thd, TA
       DBUG_RETURN(table);
     }
   }
-  DBUG_RETURN(0);                               // Not a temporary table
+  DBUG_RETURN(NULL);  // Not a temporary table
 }
 
 
@@ -2051,6 +2064,7 @@ int drop_temporary_table(THD *thd, TABLE
   */
   mysql_lock_remove(thd, thd->lock, table);
   close_temporary_table(thd, table, 1, 1);
+  table_list->table= NULL;
   DBUG_RETURN(0);
 }
 
@@ -2152,6 +2166,157 @@ bool rename_temporary_table(THD* thd, TA
 }
 
 
+static void update_table_flags(THD *thd, TABLE_LIST *table_list, TABLE *table)
+{
+  DBUG_ASSERT(table->s->ref_count > 0 || table->s->tmp_table != NO_TMP_TABLE);
+
+  if (thd->lex->need_correct_ident())
+    table->alias_name_used= my_strcasecmp(table_alias_charset,
+                                          table->s->table_name.str,
+                                          table_list->alias);
+  /* Fix alias if table name changes */
+  if (strcmp(table->alias, table_list->alias))
+  {
+    uint length=(uint) strlen(table_list->alias)+1;
+    table->alias= (char*) my_realloc((char*) table->alias, length,
+                                     MYF(MY_WME));
+    memcpy((char*) table->alias, table_list->alias, length);
+  }
+  table->tablenr=thd->current_tablenr++;
+  table->used_fields=0;
+  table->const_table=0;
+  table->null_row= table->maybe_null= 0;
+  table->force_index= table->force_index_order= table->force_index_group= 0;
+  table->status=STATUS_NO_RECORD;
+  table->insert_values= 0;
+  table->fulltext_searched= 0;
+  table->file->ft_handler= 0;
+  table->reginfo.impossible_range= 0;
+  /* Catch wrong handling of the auto_increment_field_not_null. */
+  DBUG_ASSERT(!table->auto_increment_field_not_null);
+  table->auto_increment_field_not_null= FALSE;
+  if (table->timestamp_field)
+    table->timestamp_field_type= table->timestamp_field->get_auto_set_type();
+  table->pos_in_table_list= table_list;
+  table_list->updatable= 1; // It is not derived table nor non-updatable VIEW
+  table->clear_column_bitmaps();
+  table_list->table= table;
+  DBUG_ASSERT(table->key_read == 0);
+  /* Tables may be reused in a sub statement. */
+  if (table->file->extra(HA_EXTRA_IS_ATTACHED_CHILDREN))
+    table->file->extra(HA_EXTRA_DETACH_CHILDREN);
+}
+
+bool open_tmp_table_public(THD *thd, TABLE_LIST *tl)
+{
+  DBUG_ENTER("open_tmp_table_public");
+
+  if (open_tmp_table(thd, tl, &tl->table, 0))
+    DBUG_RETURN(TRUE);
+
+  if (!tl->table)
+    DBUG_RETURN(FALSE);
+
+  /* Non-MERGE tables ignore this call. */
+  if (tl->table->file->extra(HA_EXTRA_ADD_CHILDREN_LIST))
+    DBUG_RETURN(TRUE); // XXX: if error, should not the just acquired tmp table be freed?
+
+  /* Check and update metadata version of a base table. */
+  if (check_and_update_table_version(thd, tl, tl->table->s))
+    DBUG_RETURN(TRUE);
+
+  DBUG_RETURN(FALSE);
+}
+
+bool open_tmp_table(THD *thd, TABLE_LIST *tl, TABLE **tmp_table, uint flags)
+{
+  /*
+    If TABLE_LIST::schema_table is set, TABLE_LIST::table_name may be
+    corrupted.
+
+    TABLE_LIST::db may be an empty string, and TABLE_LIST::table_name
+    is corrupted in this case.
+  */
+
+  if (tl->schema_table || !tl->db[0])
+    return FALSE;
+
+  char key[MAX_DBKEY_LENGTH];
+  uint key_length;
+
+  key_length= create_table_def_key(thd, key, tl, 1);
+
+  return open_tmp_table(thd, key, key_length, tl, tmp_table, flags);
+}
+
+
+/*
+  Unless requested otherwise, try to resolve this table in the list
+  of temporary tables of this thread. In MySQL temporary tables
+  are always thread-local and "shadow" possible base tables with the
+  same name. This block implements the behaviour.
+
+  @return FALSE if success, TRUE - otherwise.
+  @retval FALSE if tmp_table is NULL, temporary table does not exist for
+  the specified key; if tmp_table is not NULL, the temporary table was
+  found.
+  @retval TRUE on error.
+
+*/
+bool open_tmp_table(THD *thd,
+                    const char *table_key,
+                    uint table_key_length,
+                    TABLE_LIST *table_list,
+                    TABLE **tmp_table,
+                    uint flags)
+{
+  DBUG_ENTER("open_tmp_table");
+  DBUG_PRINT("enter", ("table: '%s'.'%s'",
+                       table_list->db, table_list->table_name));
+
+  *tmp_table= NULL;
+
+  if (table_list->open_type == OT_BASE_ONLY ||
+      (flags & MYSQL_OPEN_SKIP_TEMPORARY))
+  {
+    DBUG_PRINT("info", ("skip_temporary is set"));
+    DBUG_RETURN(FALSE);
+  }
+
+  TABLE *table= find_temporary_table(thd, table_key, table_key_length);
+
+  if (!table)
+    DBUG_RETURN(FALSE);
+
+  if (table->query_id)
+  {
+    /*
+      We're trying to use the same temporary table twice in a query.
+      Right now we don't support this because a temporary table is always
+      represented by only one TABLE object in THD, and it can not be
+      cloned. Emit an error for an unsupported behaviour.
+    */
+
+    DBUG_PRINT("error",
+               ("query_id: %lu  server_id: %u  pseudo_thread_id: %lu",
+                (ulong) table->query_id, (uint) thd->server_id,
+                (ulong) thd->variables.pseudo_thread_id));
+    my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
+    DBUG_RETURN(TRUE);
+  }
+
+  table->query_id= thd->query_id;
+  thd->thread_specific_used= TRUE;
+
+  update_table_flags(thd, table_list, table);
+
+  DBUG_PRINT("info", ("Using temporary table"));
+  *tmp_table= table;
+
+  DBUG_RETURN(FALSE);
+}
+
+
 /**
    Force all other threads to stop using the table by upgrading
    metadata lock on it and remove unused TABLE instances from cache.
@@ -2486,7 +2651,7 @@ open_table_get_mdl_lock(THD *thd, TABLE_
 bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
                 Open_table_context *ot_ctx, uint flags)
 {
-  reg1	TABLE *table;
+  TABLE *table;
   char	key[MAX_DBKEY_LENGTH];
   uint	key_length;
   char	*alias= table_list->alias;
@@ -2532,45 +2697,12 @@ bool open_table(THD *thd, TABLE_LIST *ta
       DBUG_RETURN(TRUE);
     }
   }
-  /*
-    Unless requested otherwise, try to resolve this table in the list
-    of temporary tables of this thread. In MySQL temporary tables
-    are always thread-local and "shadow" possible base tables with the
-    same name. This block implements the behaviour.
-    TODO: move this block into a separate function.
-  */
-  if (table_list->open_type != OT_BASE_ONLY &&
-      ! (flags & MYSQL_OPEN_SKIP_TEMPORARY))
-  {
-    for (table= thd->temporary_tables; table ; table=table->next)
-    {
-      if (table->s->table_cache_key.length == key_length +
-          TMP_TABLE_KEY_EXTRA &&
-	  !memcmp(table->s->table_cache_key.str, key,
-		  key_length + TMP_TABLE_KEY_EXTRA))
-      {
-        /*
-          We're trying to use the same temporary table twice in a query.
-          Right now we don't support this because a temporary table
-          is always represented by only one TABLE object in THD, and
-          it can not be cloned. Emit an error for an unsupported behaviour.
-        */
-	if (table->query_id)
-	{
-          DBUG_PRINT("error",
-                     ("query_id: %lu  server_id: %u  pseudo_thread_id: %lu",
-                      (ulong) table->query_id, (uint) thd->server_id,
-                      (ulong) thd->variables.pseudo_thread_id));
-	  my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
-	  DBUG_RETURN(TRUE);
-	}
-	table->query_id= thd->query_id;
-	thd->thread_specific_used= TRUE;
-        DBUG_PRINT("info",("Using temporary table"));
-        goto reset;
-      }
-    }
-  }
+
+  if (open_tmp_table(thd, table_list, &table, flags))
+    DBUG_RETURN(TRUE);
+
+  if (table)
+    goto reset;
 
   if (table_list->open_type == OT_TEMPORARY_ONLY ||
       (flags & MYSQL_OPEN_TEMPORARY_ONLY))
@@ -2959,42 +3091,43 @@ bool open_table(THD *thd, TABLE_LIST *ta
   table->reginfo.lock_type=TL_READ;		/* Assume read */
 
  reset:
-  DBUG_ASSERT(table->s->ref_count > 0 || table->s->tmp_table != NO_TMP_TABLE);
-
-  if (thd->lex->need_correct_ident())
-    table->alias_name_used= my_strcasecmp(table_alias_charset,
-                                          table->s->table_name.str, alias);
-  /* Fix alias if table name changes */
-  if (strcmp(table->alias, alias))
-  {
-    uint length=(uint) strlen(alias)+1;
-    table->alias= (char*) my_realloc((char*) table->alias, length,
-                                     MYF(MY_WME));
-    memcpy((char*) table->alias, alias, length);
-  }
-  table->tablenr=thd->current_tablenr++;
-  table->used_fields=0;
-  table->const_table=0;
-  table->null_row= table->maybe_null= 0;
-  table->force_index= table->force_index_order= table->force_index_group= 0;
-  table->status=STATUS_NO_RECORD;
-  table->insert_values= 0;
-  table->fulltext_searched= 0;
-  table->file->ft_handler= 0;
-  table->reginfo.impossible_range= 0;
-  /* Catch wrong handling of the auto_increment_field_not_null. */
-  DBUG_ASSERT(!table->auto_increment_field_not_null);
-  table->auto_increment_field_not_null= FALSE;
-  if (table->timestamp_field)
-    table->timestamp_field_type= table->timestamp_field->get_auto_set_type();
-  table->pos_in_table_list= table_list;
-  table_list->updatable= 1; // It is not derived table nor non-updatable VIEW
-  table->clear_column_bitmaps();
-  table_list->table= table;
-  DBUG_ASSERT(table->key_read == 0);
-  /* Tables may be reused in a sub statement. */
-  if (table->file->extra(HA_EXTRA_IS_ATTACHED_CHILDREN))
-    table->file->extra(HA_EXTRA_DETACH_CHILDREN);
+//  DBUG_ASSERT(table->s->ref_count > 0 || table->s->tmp_table != NO_TMP_TABLE);
+//
+//  if (thd->lex->need_correct_ident())
+//    table->alias_name_used= my_strcasecmp(table_alias_charset,
+//                                          table->s->table_name.str, alias);
+//  /* Fix alias if table name changes */
+//  if (strcmp(table->alias, alias))
+//  {
+//    uint length=(uint) strlen(alias)+1;
+//    table->alias= (char*) my_realloc((char*) table->alias, length,
+//                                     MYF(MY_WME));
+//    memcpy((char*) table->alias, alias, length);
+//  }
+//  table->tablenr=thd->current_tablenr++;
+//  table->used_fields=0;
+//  table->const_table=0;
+//  table->null_row= table->maybe_null= 0;
+//  table->force_index= table->force_index_order= table->force_index_group= 0;
+//  table->status=STATUS_NO_RECORD;
+//  table->insert_values= 0;
+//  table->fulltext_searched= 0;
+//  table->file->ft_handler= 0;
+//  table->reginfo.impossible_range= 0;
+//  /* Catch wrong handling of the auto_increment_field_not_null. */
+//  DBUG_ASSERT(!table->auto_increment_field_not_null);
+//  table->auto_increment_field_not_null= FALSE;
+//  if (table->timestamp_field)
+//    table->timestamp_field_type= table->timestamp_field->get_auto_set_type();
+//  table->pos_in_table_list= table_list;
+//  table_list->updatable= 1; // It is not derived table nor non-updatable VIEW
+//  table->clear_column_bitmaps();
+//  table_list->table= table;
+//  DBUG_ASSERT(table->key_read == 0);
+//  /* Tables may be reused in a sub statement. */
+//  if (table->file->extra(HA_EXTRA_IS_ATTACHED_CHILDREN))
+//    table->file->extra(HA_EXTRA_DETACH_CHILDREN);
+  update_table_flags(thd, table_list, table);
   DBUG_RETURN(FALSE);
 
 err_unlock:
@@ -4192,6 +4325,21 @@ open_and_process_table(THD *thd, LEX *le
   bool safe_to_ignore_table= FALSE;
   DBUG_ENTER("open_and_process_table");
 
+  if ((tables->open_type == OT_BASE_ONLY ||
+      (flags & MYSQL_OPEN_SKIP_TEMPORARY)) &&
+      tables->table && tables->table->s->tmp_table != NO_TMP_TABLE)
+  {
+    tables->table->query_id= 0;
+    tables->table= NULL;
+    // XXX: what to do with THD::thread_specific_used?
+  }
+
+  if (tables->table &&
+      tables->table->s->tmp_table != NO_TMP_TABLE)
+  {
+    goto end;
+  }
+
   /*
     Ignore placeholders for derived tables. After derived tables
     processing, link to created temporary table will be put here.
@@ -4380,6 +4528,8 @@ open_and_process_table(THD *thd, LEX *le
   /* MERGE tables need to access parent and child TABLE_LISTs. */
   DBUG_ASSERT(tables->table->pos_in_table_list == tables);
   /* Non-MERGE tables ignore this call. */
+  DBUG_PRINT("info", ("calling HA_EXTRA_ADD_CHILDREN_LIST (%s)...",
+      (char *) tables->table_name));
   if (tables->table->file->extra(HA_EXTRA_ADD_CHILDREN_LIST))
   {
     error= TRUE;

=== modified file 'sql/sql_base.h'
--- a/sql/sql_base.h	2010-05-13 09:36:49 +0000
+++ b/sql/sql_base.h	2010-05-26 10:18:31 +0000
@@ -132,8 +132,13 @@ TABLE_LIST *find_table_in_list(TABLE_LIS
                                TABLE_LIST *TABLE_LIST::*link,
                                const char *db_name,
                                const char *table_name);
+
 TABLE *find_temporary_table(THD *thd, const char *db, const char *table_name);
 TABLE *find_temporary_table(THD *thd, TABLE_LIST *table_list);
+TABLE *find_temporary_table(THD *thd,
+                            const char *table_key,
+                            uint table_key_length);
+
 void close_thread_tables(THD *thd);
 bool fill_record_n_invoke_before_triggers(THD *thd, List<Item> &fields,
                                           List<Item> &values,
@@ -231,6 +236,17 @@ void close_temporary_table(THD *thd, TAB
 void close_temporary(TABLE *table, bool free_share, bool delete_table);
 bool rename_temporary_table(THD* thd, TABLE *table, const char *new_db,
 			    const char *table_name);
+bool open_tmp_table_public(THD *thd, TABLE_LIST *tl);
+bool open_tmp_table(THD *thd,
+                    TABLE_LIST *table_list,
+                    TABLE **tmp_table,
+                    uint flags);
+bool open_tmp_table(THD *thd,
+                    const char *table_key,
+                    uint table_key_length,
+                    TABLE_LIST *table_list,
+                    TABLE **tmp_table,
+                    uint flags);
 void mysql_wait_completed_table(ALTER_PARTITION_PARAM_TYPE *lpt, TABLE *my_table);
 void remove_db_from_cache(const char *db);
 void flush_tables();

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2010-05-18 12:52:51 +0000
+++ b/sql/sql_class.h	2010-05-26 10:18:31 +0000
@@ -3610,6 +3610,8 @@ public:
  */
 #define CF_PROTECT_AGAINST_GRL  (1U << 10)
 
+#define CF_OPEN_TMP_TABLES      (1U << 11)
+
 /* Bits in server_command_flags */
 
 /**

=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc	2010-05-14 05:28:51 +0000
+++ b/sql/sql_insert.cc	2010-05-26 10:18:31 +0000
@@ -3628,6 +3628,7 @@ static TABLE *create_table_from_items(TH
       else
       {
         Open_table_context ot_ctx_unused(thd, LONG_TIMEOUT);
+// debug        if (open_tmp_table(thd, create_table, &table, 0))
         if (open_table(thd, create_table, thd->mem_root, &ot_ctx_unused,
                        MYSQL_OPEN_TEMPORARY_ONLY))
         {
@@ -3639,7 +3640,10 @@ static TABLE *create_table_from_items(TH
           drop_temporary_table(thd, create_table);
         }
         else
+        {
+// debug          create_table->table= table;
           table= create_table->table;
+        }
       }
     }
     if (!table)                                   // open failed

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2010-05-18 12:52:51 +0000
+++ b/sql/sql_parse.cc	2010-05-26 10:18:31 +0000
@@ -248,10 +248,12 @@ void init_update_queries(void)
   memset(sql_command_flags, 0, sizeof(sql_command_flags));
 
   sql_command_flags[SQLCOM_CREATE_TABLE]=   CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
-                                            CF_AUTO_COMMIT_TRANS | CF_PROTECT_AGAINST_GRL;
+                                            CF_AUTO_COMMIT_TRANS | CF_PROTECT_AGAINST_GRL |
+                                            CF_OPEN_TMP_TABLES;
   sql_command_flags[SQLCOM_CREATE_INDEX]=   CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
   sql_command_flags[SQLCOM_ALTER_TABLE]=    CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND |
-                                            CF_AUTO_COMMIT_TRANS | CF_PROTECT_AGAINST_GRL;
+                                            CF_AUTO_COMMIT_TRANS | CF_PROTECT_AGAINST_GRL |
+                                            CF_OPEN_TMP_TABLES;
   sql_command_flags[SQLCOM_TRUNCATE]=       CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND |
                                             CF_AUTO_COMMIT_TRANS;
   sql_command_flags[SQLCOM_DROP_TABLE]=     CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
@@ -275,22 +277,24 @@ void init_update_queries(void)
   sql_command_flags[SQLCOM_DROP_TRIGGER]=   CF_AUTO_COMMIT_TRANS;
 
   sql_command_flags[SQLCOM_UPDATE]=	    CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
-                                            CF_PROTECT_AGAINST_GRL;
+                                            CF_PROTECT_AGAINST_GRL | CF_OPEN_TMP_TABLES;
   sql_command_flags[SQLCOM_UPDATE_MULTI]=   CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
-                                            CF_PROTECT_AGAINST_GRL;
+                                            CF_PROTECT_AGAINST_GRL | CF_OPEN_TMP_TABLES;
   sql_command_flags[SQLCOM_INSERT]=	    CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
-                                            CF_PROTECT_AGAINST_GRL;
+                                            CF_PROTECT_AGAINST_GRL | CF_OPEN_TMP_TABLES;
   sql_command_flags[SQLCOM_INSERT_SELECT]=  CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
-                                            CF_PROTECT_AGAINST_GRL;
+                                            CF_PROTECT_AGAINST_GRL | CF_OPEN_TMP_TABLES;
   sql_command_flags[SQLCOM_DELETE]=         CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
-                                            CF_PROTECT_AGAINST_GRL;
+                                            CF_PROTECT_AGAINST_GRL | CF_OPEN_TMP_TABLES;
   sql_command_flags[SQLCOM_DELETE_MULTI]=   CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
-                                            CF_PROTECT_AGAINST_GRL;
-  sql_command_flags[SQLCOM_REPLACE]=        CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE;
-  sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE;
-  sql_command_flags[SQLCOM_SELECT]=         CF_REEXECUTION_FRAGILE;
+                                            CF_PROTECT_AGAINST_GRL | CF_OPEN_TMP_TABLES;
+  sql_command_flags[SQLCOM_REPLACE]=        CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
+                                            CF_OPEN_TMP_TABLES;
+  sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
+                                            CF_OPEN_TMP_TABLES;
+  sql_command_flags[SQLCOM_SELECT]=         CF_REEXECUTION_FRAGILE | CF_OPEN_TMP_TABLES;
   sql_command_flags[SQLCOM_SET_OPTION]=     CF_REEXECUTION_FRAGILE | CF_AUTO_COMMIT_TRANS;
-  sql_command_flags[SQLCOM_DO]=             CF_REEXECUTION_FRAGILE;
+  sql_command_flags[SQLCOM_DO]=             CF_REEXECUTION_FRAGILE | CF_OPEN_TMP_TABLES;
 
   sql_command_flags[SQLCOM_SHOW_STATUS_PROC]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
   sql_command_flags[SQLCOM_SHOW_STATUS]=      CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
@@ -320,7 +324,7 @@ void init_update_queries(void)
   sql_command_flags[SQLCOM_SHOW_PROCESSLIST]= CF_STATUS_COMMAND;
   sql_command_flags[SQLCOM_SHOW_GRANTS]=      CF_STATUS_COMMAND;
   sql_command_flags[SQLCOM_SHOW_CREATE_DB]=   CF_STATUS_COMMAND;
-  sql_command_flags[SQLCOM_SHOW_CREATE]=  CF_STATUS_COMMAND;
+  sql_command_flags[SQLCOM_SHOW_CREATE]=      CF_STATUS_COMMAND | CF_OPEN_TMP_TABLES;
   sql_command_flags[SQLCOM_SHOW_MASTER_STAT]= CF_STATUS_COMMAND;
   sql_command_flags[SQLCOM_SHOW_SLAVE_STAT]=  CF_STATUS_COMMAND;
   sql_command_flags[SQLCOM_SHOW_CREATE_PROC]= CF_STATUS_COMMAND;
@@ -388,6 +392,8 @@ void init_update_queries(void)
   sql_command_flags[SQLCOM_FLUSH]=              CF_AUTO_COMMIT_TRANS;
   sql_command_flags[SQLCOM_RESET]=              CF_AUTO_COMMIT_TRANS;
   sql_command_flags[SQLCOM_CHECK]=              CF_AUTO_COMMIT_TRANS;
+
+  sql_command_flags[SQLCOM_LOCK_TABLES]=        CF_OPEN_TMP_TABLES;
 }
 
 
@@ -2184,6 +2190,15 @@ mysql_execute_command(THD *thd)
     DEBUG_SYNC(thd,"before_execute_sql_command");
 #endif
 
+  if (sql_command_flags[lex->sql_command] & CF_OPEN_TMP_TABLES)
+  {
+    for (TABLE_LIST *tl= all_tables; tl; tl= tl->next_global)
+    {
+      if (open_tmp_table_public(thd, tl))
+        goto error;
+    }
+  }
+
   switch (lex->sql_command) {
 
   case SQLCOM_SHOW_EVENTS:
@@ -2260,7 +2275,7 @@ mysql_execute_command(THD *thd)
     res= execute_sqlcom_select(thd, all_tables);
     break;
   }
-case SQLCOM_PREPARE:
+  case SQLCOM_PREPARE:
   {
     mysql_sql_stmt_prepare(thd);
     break;
@@ -2944,7 +2959,7 @@ end_with_restore_list:
           contains any table-specific privilege.
         */
         DBUG_PRINT("debug", ("first_table->grant.privilege: %x",
-                             first_table->grant.privilege));
+                             (unsigned int) first_table->grant.privilege));
         if (check_some_access(thd, SHOW_CREATE_TABLE_ACLS, first_table) ||
             (first_table->grant.privilege & SHOW_CREATE_TABLE_ACLS) == 0)
         {
@@ -4719,6 +4734,7 @@ finish:
     close_thread_tables(thd);
     thd->mdl_context.release_transactional_locks();
   }
+// debug  sql_print_information("---> query done.");
 
   DBUG_RETURN(res || thd->is_error());
 }
@@ -6038,8 +6054,17 @@ TABLE_LIST *st_select_lex::add_table_to_
   DBUG_ENTER("add_table_to_list");
   LINT_INIT(previous_table_ref);
 
+  if (alias)
+    DBUG_PRINT("info", ("alias: '%.*s'", (int) alias->length, (char *) alias->str));
+  else
+    DBUG_PRINT("info", ("alias: NULL"));
+
   if (!table)
+  {
+    DBUG_PRINT("info", ("table: NULL"));
     DBUG_RETURN(0);				// End of memory
+  }
+  DBUG_PRINT("info", ("table: '%s'", (char *) table->table.str));
   alias_str= alias ? alias->str : table->table.str;
   if (!test(table_options & TL_OPTION_ALIAS) && 
       check_table_name(table->table.str, table->table.length))
@@ -6178,6 +6203,10 @@ TABLE_LIST *st_select_lex::add_table_to_
   ptr->mdl_request.init(MDL_key::TABLE, ptr->db, ptr->table_name,
                         (ptr->lock_type >= TL_WRITE_ALLOW_WRITE) ?
                         MDL_SHARED_WRITE : MDL_SHARED_READ);
+
+  DBUG_PRINT("info", ("lex->query_tables (all_tables):"));
+  for (TABLE_LIST *tl= lex->query_tables; tl; tl= tl->next_global)
+    DBUG_PRINT("info", ("  - '%s'.'%s'", (char *) tl->db, (char *) tl->table_name));
   DBUG_RETURN(ptr);
 }
 


Attachment: [text/bzr-bundle] bzr/alik@sun.com-20100526101831-w9cekl2wvrdhy3a2.bundle
Thread
bzr commit into mysql-trunk-bugfixing branch (alik:3057) Bug#27480Alexander Nozdrin26 May