#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#27480 | Alexander Nozdrin | 26 May |