Below is the list of changes that have just been committed into a local
5.1 repository of jani. When jani does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet
1.2176 06/05/30 16:07:49 jani@stripped +46 -0
Merge a193-229-222-105.elisa-laajakaista.fi:/home/my/bk/mysql-5.0
into a193-229-222-105.elisa-laajakaista.fi:/home/my/bk/mysql-5.1-new
sql/sql_table.cc
1.336 06/05/30 16:07:40 jani@stripped +8 -13
Manual merge from 5.0
sql/sql_select.cc
1.408 06/05/30 16:07:40 jani@stripped +8 -10
Manual merge from 5.0
sql/sql_lex.cc
1.182 06/05/30 16:07:39 jani@stripped +2 -3
Manual merge from 5.0
sql/sql_base.cc
1.326 06/05/30 16:07:39 jani@stripped +3 -2
Manual merge from 5.0
sql/mysqld.cc
1.552 06/05/30 16:07:39 jani@stripped +2 -4
Manual merge from 5.0
sql/ha_ndbcluster.cc
1.310 06/05/30 16:07:39 jani@stripped +0 -3
Manual merge from 5.0
sql/field.cc
1.312 06/05/30 16:07:39 jani@stripped +7 -4
Manual merge from 5.0
server-tools/instance-manager/manager.cc
1.34 06/05/30 16:07:39 jani@stripped +7 -8
Manual merge from 5.0
mysql-test/t/rpl_insert_id.test
1.18 06/05/30 16:07:39 jani@stripped +0 -2
Manual merge from 5.0
mysql-test/t/mysqldump.test
1.100 06/05/30 16:07:39 jani@stripped +11 -12
Manual merge from 5.0
mysql-test/r/mysqldump.result
1.107 06/05/30 16:07:39 jani@stripped +37 -38
Manual merge from 5.0
configure.in
1.357 06/05/30 16:07:39 jani@stripped +0 -2
Manual merge from 5.0
client/mysqldump.c
1.238 06/05/30 16:07:39 jani@stripped +2 -3
Manual merge from 5.0
client/mysqlbinlog.cc
1.130 06/05/30 16:07:39 jani@stripped +0 -0
Manual merge from 5.0
storage/ndb/src/ndbapi/DictCache.hpp
1.16 06/05/30 14:24:28 jani@stripped +0 -0
Auto merged
storage/ndb/src/ndbapi/DictCache.cpp
1.27 06/05/30 14:24:28 jani@stripped +0 -0
Auto merged
storage/heap/hp_write.c
1.24 06/05/30 14:24:28 jani@stripped +0 -0
Auto merged
sql/table.cc
1.216 06/05/30 14:24:28 jani@stripped +0 -0
Auto merged
sql/sql_update.cc
1.191 06/05/30 14:24:28 jani@stripped +0 -0
Auto merged
sql/sql_show.cc
1.339 06/05/30 14:24:27 jani@stripped +0 -0
Auto merged
sql/sql_parse.cc
1.553 06/05/30 14:24:27 jani@stripped +0 -0
Auto merged
sql/sql_load.cc
1.98 06/05/30 14:24:26 jani@stripped +0 -0
Auto merged
sql/sql_lex.h
1.232 06/05/30 14:24:26 jani@stripped +0 -0
Auto merged
sql/sql_insert.cc
1.202 06/05/30 14:24:26 jani@stripped +0 -0
Auto merged
sql/sql_delete.cc
1.182 06/05/30 14:24:26 jani@stripped +0 -0
Auto merged
sql/sql_acl.cc
1.194 06/05/30 14:24:26 jani@stripped +0 -0
Auto merged
sql/mysql_priv.h
1.406 06/05/30 14:24:25 jani@stripped +0 -0
Auto merged
sql/lock.cc
1.92 06/05/30 14:24:25 jani@stripped +0 -0
Auto merged
sql/item_timefunc.cc
1.119 06/05/30 14:24:25 jani@stripped +0 -0
Auto merged
sql/item_subselect.cc
1.125 06/05/30 14:24:25 jani@stripped +0 -0
Auto merged
sql/item.h
1.202 06/05/30 14:24:25 jani@stripped +0 -0
Auto merged
sql/field.h
1.185 06/05/30 14:24:24 jani@stripped +0 -0
Auto merged
server-tools/instance-manager/guardian.cc
1.23 06/05/30 14:24:24 jani@stripped +0 -0
Auto merged
mysys/default.c
1.82 06/05/30 14:24:24 jani@stripped +0 -0
Auto merged
mysql-test/t/view_grant.test
1.16 06/05/30 14:24:24 jani@stripped +0 -0
Auto merged
mysql-test/t/sp.test
1.190 06/05/30 14:24:24 jani@stripped +0 -0
Auto merged
mysql-test/t/lock_multi.test
1.15 06/05/30 14:24:23 jani@stripped +0 -0
Auto merged
mysql-test/r/view_grant.result
1.19 06/05/30 14:24:23 jani@stripped +1 -1
Auto merged
mysql-test/r/subselect.result
1.147 06/05/30 14:24:22 jani@stripped +0 -0
Auto merged
mysql-test/r/sp.result
1.207 06/05/30 14:24:22 jani@stripped +0 -0
Auto merged
mysql-test/r/lock_multi.result
1.17 06/05/30 14:24:22 jani@stripped +0 -0
Auto merged
mysql-test/r/information_schema_db.result
1.16 06/05/30 14:24:22 jani@stripped +0 -0
Auto merged
mysql-test/r/heap_btree.result
1.21 06/05/30 14:24:22 jani@stripped +0 -0
Auto merged
mysql-test/r/grant.result
1.52 06/05/30 14:24:22 jani@stripped +0 -0
Auto merged
mysql-test/mysql-test-run.sh
1.322 06/05/30 14:24:22 jani@stripped +0 -0
Auto merged
mysql-test/mysql-test-run.pl
1.118 06/05/30 14:24:22 jani@stripped +1 -4
Auto merged
storage/ndb/src/ndbapi/DictCache.hpp
1.6.8.2 06/05/30 14:24:21 jani@stripped +0 -0
Merge rename: ndb/src/ndbapi/DictCache.hpp -> storage/ndb/src/ndbapi/DictCache.hpp
storage/ndb/src/ndbapi/DictCache.cpp
1.12.7.2 06/05/30 14:24:21 jani@stripped +0 -0
Merge rename: ndb/src/ndbapi/DictCache.cpp -> storage/ndb/src/ndbapi/DictCache.cpp
storage/heap/hp_write.c
1.22.1.2 06/05/30 14:24:21 jani@stripped +0 -0
Merge rename: heap/hp_write.c -> storage/heap/hp_write.c
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: jani
# Host: a193-229-222-105.elisa-laajakaista.fi
# Root: /home/my/bk/mysql-5.1-new/RESYNC
--- 1.237/client/mysqldump.c 2006-05-12 13:31:59 +03:00
+++ 1.238/client/mysqldump.c 2006-05-30 16:07:39 +03:00
@@ -3063,14 +3063,13 @@
different case (e.g. T1 vs t1)
RETURN
- int - 0 if a tablename was retrieved. 1 if not
+ pointer to the table name
+ 0 if error
*/
-static int get_actual_table_name(const char *old_table_name,
- char *new_table_name,
- int buf_size)
+static char *get_actual_table_name(const char *old_table_name, MEM_ROOT *root)
{
- int retval;
+ char *name= 0;
MYSQL_RES *table_res;
MYSQL_ROW row;
char query[50 + 2*NAME_LEN];
@@ -3087,66 +3086,55 @@
safe_exit(EX_MYSQLERR);
}
- retval = 1;
-
if ((table_res= mysql_store_result(sock)))
{
my_ulonglong num_rows= mysql_num_rows(table_res);
if (num_rows > 0)
{
+ ulong *lengths;
/*
Return first row
TODO: Return all matching rows
*/
row= mysql_fetch_row(table_res);
- strmake(new_table_name, row[0], buf_size-1);
- retval= 0;
+ lengths= mysql_fetch_lengths(table_res);
+ name= strmake_root(root, row[0], lengths[0]);
}
mysql_free_result(table_res);
}
- DBUG_RETURN(retval);
+ DBUG_PRINT("exit", ("new_table_name: %s", name));
+ DBUG_RETURN(name);
}
static int dump_selected_tables(char *db, char **table_names, int tables)
{
- uint i;
char table_buff[NAME_LEN*+3];
- char new_table_name[NAME_LEN];
DYNAMIC_STRING lock_tables_query;
- HASH dump_tables;
- char *table_name;
+ MEM_ROOT root;
+ char **dump_tables, **pos, **end;
DBUG_ENTER("dump_selected_tables");
if (init_dumping(db))
DBUG_RETURN(1);
- /* Init hash table for storing the actual name of tables to dump */
- if (hash_init(&dump_tables, charset_info, 16, 0, 0,
- (hash_get_key) get_table_key, (hash_free_key) free_table_ent,
- 0))
+ init_alloc_root(&root, 8192, 0);
+ if (!(dump_tables= pos= (char**) alloc_root(&root, tables * sizeof(char *))))
exit(EX_EOM);
init_dynamic_string(&lock_tables_query, "LOCK TABLES ", 256, 1024);
for (; tables > 0 ; tables-- , table_names++)
{
/* the table name passed on commandline may be wrong case */
- if (!get_actual_table_name(*table_names,
- new_table_name, sizeof(new_table_name)))
+ if ((*pos= get_actual_table_name(*table_names, &root)))
{
/* Add found table name to lock_tables_query */
if (lock_tables)
{
- dynstr_append(&lock_tables_query,
- quote_name(new_table_name, table_buff, 1));
+ dynstr_append(&lock_tables_query, quote_name(*pos, table_buff, 1));
dynstr_append(&lock_tables_query, " READ /*!32311 LOCAL */,");
}
-
- /* Add found table name to dump_tables list */
- if (my_hash_insert(&dump_tables,
- (byte*)my_strdup(new_table_name, MYF(0))))
- exit(EX_EOM);
-
+ pos++;
}
else
{
@@ -3156,6 +3144,7 @@
/* We shall countinue here, if --force was given */
}
}
+ end= pos;
if (lock_tables)
{
@@ -3175,24 +3164,20 @@
print_xml_tag1(md_result_file, "", "database name=", db, "\n");
/* Dump each selected table */
- for (i= 0; i < dump_tables.records; i++)
+ for (pos= dump_tables; pos < end; pos++)
{
- table_name= hash_element(&dump_tables, i);
- DBUG_PRINT("info",("Dumping table %s", table_name));
- dump_table(table_name,db);
+ DBUG_PRINT("info",("Dumping table %s", *pos));
+ dump_table(*pos, db);
if (opt_dump_triggers &&
mysql_get_server_version(sock) >= 50009)
- dump_triggers_for_table(table_name, db);
+ dump_triggers_for_table(*pos, db);
}
/* Dump each selected view */
if (was_views)
{
- for(i=0; i < dump_tables.records; i++)
- {
- table_name= hash_element(&dump_tables, i);
- get_view_structure(table_name, db);
- }
+ for (pos= dump_tables; pos < end; pos++)
+ get_view_structure(*pos, db);
}
if (opt_events && !opt_xml &&
mysql_get_server_version(sock) >= 50106)
@@ -3207,7 +3192,7 @@
DBUG_PRINT("info", ("Dumping routines for database %s", db));
dump_routines_for_db(db);
}
- hash_free(&dump_tables);
+ free_root(&root, MYF(0));
my_free(order_by, MYF(MY_ALLOW_ZERO_PTR));
order_by= 0;
if (opt_xml)
--- 1.81/mysys/default.c 2006-05-18 17:57:43 +03:00
+++ 1.82/mysys/default.c 2006-05-30 14:24:24 +03:00
@@ -763,7 +763,9 @@
value_end=value;
/* remove quotes around argument */
- if ((*value == '\"' || *value == '\'') && *value == value_end[-1])
+ if ((*value == '\"' || *value == '\'') && /* First char is quote */
+ (value + 1 < value_end ) && /* String is longer than 1 */
+ *value == value_end[-1] ) /* First char is equal to last char */
{
value++;
value_end--;
--- 1.311/sql/field.cc 2006-05-24 19:50:55 +03:00
+++ 1.312/sql/field.cc 2006-05-30 16:07:39 +03:00
@@ -1218,7 +1218,7 @@
Field::Field(char *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,
uchar null_bit_arg,
utype unireg_check_arg, const char *field_name_arg)
- :ptr(ptr_arg),null_ptr(null_ptr_arg),
+ :ptr(ptr_arg), null_ptr(null_ptr_arg),
table(0), orig_table(0), table_name(0),
field_name(field_name_arg),
query_id(0), key_start(0), part_of_key(0), part_of_sortkey(0),
@@ -9059,14 +9059,15 @@
diff= (my_ptrdiff_t) (orig_field->table->s->default_values-
orig_field->table->record[0]);
orig_field->move_field_offset(diff); // Points now at default_values
- is_null= orig_field->is_real_null();
- res= orig_field->val_str(&tmp);
- orig_field->move_field_offset(-diff); // Back to record[0]
- if (!is_null)
+ if (!orig_field->is_real_null())
{
+ char buff[MAX_FIELD_WIDTH], *pos;
+ String tmp(buff, sizeof(buff), charset), *res;
+ res= orig_field->val_str(&tmp);
pos= (char*) sql_strmake(res->ptr(), res->length());
def= new Item_string(pos, res->length(), charset);
}
+ orig_field->move_field_offset(-diff); // Back to record[0]
}
}
--- 1.184/sql/field.h 2006-05-24 19:50:55 +03:00
+++ 1.185/sql/field.h 2006-05-30 14:24:24 +03:00
@@ -55,12 +55,6 @@
char *ptr; // Position to field in record
uchar *null_ptr; // Byte where null_bit is
/*
- dflt_field is used only for the fields of temporary tables.
- It points to the default value of the field in another table
- from which this field has been created.
- */
- Field *dflt_field; // Field to copy default value from
- /*
Note that you can use table->in_use as replacement for current_thd member
only inside of val_*() and store() members (e.g. you can't use it in cons)
*/
--- 1.201/sql/item.h 2006-05-20 05:00:55 +03:00
+++ 1.202/sql/item.h 2006-05-30 14:24:25 +03:00
@@ -417,6 +417,8 @@
required, otherwise we only reading it and SELECT
privilege might be required.
*/
+ Settable_routine_parameter() {}
+ virtual ~Settable_routine_parameter() {}
virtual void set_required_privilege(bool rw) {};
/*
@@ -2289,6 +2291,7 @@
max_length= item->max_length;
decimals= item->decimals;
collation.set(item->collation);
+ unsigned_flag= item->unsigned_flag;
return 0;
};
virtual void store(Item *)= 0;
--- 1.118/sql/item_timefunc.cc 2006-05-17 21:46:14 +03:00
+++ 1.119/sql/item_timefunc.cc 2006-05-30 14:24:25 +03:00
@@ -2010,39 +2010,11 @@
bool Item_date_add_interval::eq(const Item *item, bool binary_cmp) const
{
- INTERVAL interval, other_interval;
- String val= value; // Because of const
-
- if (this == item)
- return TRUE;
-
- if ((item->type() != FUNC_ITEM) ||
- (arg_count != ((Item_func*) item)->arg_count) ||
- (func_name() != ((Item_func*) item)->func_name()))
- return FALSE;
-
Item_date_add_interval *other= (Item_date_add_interval*) item;
-
- if ((int_type != other->int_type) ||
- (!args[0]->eq(other->args[0], binary_cmp)))
- return FALSE;
-
- if (!args[1]->const_item() || !other->args[1]->const_item())
- return (args[1]->eq(other->args[1], binary_cmp));
-
- if (get_interval_value(args[1], int_type, &val, &interval))
- return FALSE;
-
- val= other->value;
-
- if ((get_interval_value(other->args[1], other->int_type, &val,
- &other_interval)) ||
- ((date_sub_interval ^ interval.neg) ^
- (other->date_sub_interval ^ other_interval.neg)))
- return FALSE;
-
- // Assume comparing same types here due to earlier check
- return memcmp(&interval, &other_interval, sizeof(INTERVAL)) == 0;
+ if (!Item_func::eq(item, binary_cmp))
+ return 0;
+ return ((int_type == other->int_type) &&
+ (date_sub_interval == other->date_sub_interval));
}
--- 1.91/sql/lock.cc 2006-04-25 11:57:27 +03:00
+++ 1.92/sql/lock.cc 2006-05-30 14:24:25 +03:00
@@ -1174,16 +1174,17 @@
if (!thd->global_read_lock)
{
+ const char *old_message;
(void) pthread_mutex_lock(&LOCK_global_read_lock);
- const char *old_message=thd->enter_cond(&COND_refresh,
&LOCK_global_read_lock,
- "Waiting to get readlock");
+ old_message=thd->enter_cond(&COND_global_read_lock,
&LOCK_global_read_lock,
+ "Waiting to get readlock");
DBUG_PRINT("info",
("waiting_for: %d protect_against: %d",
waiting_for_read_lock, protect_against_global_read_lock));
waiting_for_read_lock++;
while (protect_against_global_read_lock && !thd->killed)
- pthread_cond_wait(&COND_refresh, &LOCK_global_read_lock);
+ pthread_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock);
waiting_for_read_lock--;
if (thd->killed)
{
@@ -1205,9 +1206,15 @@
DBUG_RETURN(0);
}
+
void unlock_global_read_lock(THD *thd)
{
uint tmp;
+ DBUG_ENTER("unlock_global_read_lock");
+ DBUG_PRINT("info",
+ ("global_read_lock: %u global_read_lock_blocks_commit: %u",
+ global_read_lock, global_read_lock_blocks_commit));
+
pthread_mutex_lock(&LOCK_global_read_lock);
tmp= --global_read_lock;
if (thd->global_read_lock == MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT)
@@ -1215,8 +1222,13 @@
pthread_mutex_unlock(&LOCK_global_read_lock);
/* Send the signal outside the mutex to avoid a context switch */
if (!tmp)
- pthread_cond_broadcast(&COND_refresh);
+ {
+ DBUG_PRINT("signal", ("Broadcasting COND_global_read_lock"));
+ pthread_cond_broadcast(&COND_global_read_lock);
+ }
thd->global_read_lock= 0;
+
+ DBUG_VOID_RETURN;
}
#define must_wait (global_read_lock && \
@@ -1254,11 +1266,15 @@
*/
DBUG_RETURN(is_not_commit);
}
- old_message=thd->enter_cond(&COND_refresh, &LOCK_global_read_lock,
+ old_message=thd->enter_cond(&COND_global_read_lock,
&LOCK_global_read_lock,
"Waiting for release of readlock");
while (must_wait && ! thd->killed &&
(!abort_on_refresh || thd->version == refresh_version))
- (void) pthread_cond_wait(&COND_refresh,&LOCK_global_read_lock);
+ {
+ DBUG_PRINT("signal", ("Waiting for COND_global_read_lock"));
+ (void) pthread_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock);
+ DBUG_PRINT("signal", ("Got COND_global_read_lock"));
+ }
if (thd->killed)
result=1;
}
@@ -1287,7 +1303,7 @@
(waiting_for_read_lock || global_read_lock_blocks_commit));
(void) pthread_mutex_unlock(&LOCK_global_read_lock);
if (tmp)
- pthread_cond_broadcast(&COND_refresh);
+ pthread_cond_broadcast(&COND_global_read_lock);
DBUG_VOID_RETURN;
}
@@ -1309,10 +1325,10 @@
/* For testing we set up some blocking, to see if we can be killed */
DBUG_EXECUTE_IF("make_global_read_lock_block_commit_loop",
protect_against_global_read_lock++;);
- old_message= thd->enter_cond(&COND_refresh, &LOCK_global_read_lock,
+ old_message= thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
"Waiting for all running commits to finish");
while (protect_against_global_read_lock && !thd->killed)
- pthread_cond_wait(&COND_refresh, &LOCK_global_read_lock);
+ pthread_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock);
DBUG_EXECUTE_IF("make_global_read_lock_block_commit_loop",
protect_against_global_read_lock--;);
if ((error= test(thd->killed)))
--- 1.405/sql/mysql_priv.h 2006-05-27 08:05:13 +03:00
+++ 1.406/sql/mysql_priv.h 2006-05-30 14:24:25 +03:00
@@ -849,6 +849,7 @@
bool mysql_derived_filling(THD *thd, LEX *lex, TABLE_LIST *t);
Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
Item ***copy_func, Field **from_field,
+ Field **def_field,
bool group, bool modify_item,
bool table_cant_handle_bit_fields,
bool make_copy_field,
@@ -1106,6 +1107,13 @@
bool setup_tables(THD *thd, Name_resolution_context *context,
List<TABLE_LIST> *from_clause, TABLE_LIST *tables,
Item **conds, TABLE_LIST **leaves, bool select_insert);
+bool setup_tables_and_check_access (THD *thd,
+ Name_resolution_context *context,
+ List<TABLE_LIST> *from_clause,
+ TABLE_LIST *tables, Item **conds,
+ TABLE_LIST **leaves,
+ bool select_insert,
+ ulong want_access);
int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
List<Item> *sum_func_list, uint wild_num);
bool setup_fields(THD *thd, Item** ref_pointer_array,
@@ -1549,6 +1557,7 @@
extern int mysqld_server_started;
extern rw_lock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave;
extern pthread_cond_t COND_refresh, COND_thread_count, COND_manager;
+extern pthread_cond_t COND_global_read_lock;
extern pthread_attr_t connection_attrib;
extern I_List<THD> threads;
extern I_List<NAMED_LIST> key_caches;
--- 1.129/client/mysqlbinlog.cc 2006-05-16 15:16:18 +03:00
+++ 1.130/client/mysqlbinlog.cc 2006-05-30 16:07:39 +03:00
@@ -72,6 +72,7 @@
static const char* sock= 0;
static const char* user = 0;
static char* pass = 0;
+static char *charset= 0;
static ulonglong start_position, stop_position;
#define start_position_mot ((my_off_t)start_position)
@@ -733,6 +734,9 @@
"Extract only binlog entries created by the server having the given id.",
(gptr*) &server_id, (gptr*) &server_id, 0, GET_ULONG,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"set-charset", OPT_SET_CHARSET,
+ "Add 'SET NAMES character_set' to the output.", (gptr*) &charset,
+ (gptr*) &charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"short-form", 's', "Just show the queries, no extra info.",
(gptr*) &short_form, (gptr*) &short_form, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
0, 0},
@@ -1457,6 +1461,13 @@
"/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,"
"COMPLETION_TYPE=0*/;\n");
+ if (charset)
+ fprintf(result_file,
+ "\n/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;"
+ "\n/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;"
+ "\n/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;"
+ "\n/*!40101 SET NAMES %s */;\n", charset);
+
for (save_stop_position= stop_position, stop_position= ~(my_off_t)0 ;
(--argc >= 0) && !stop_passed ; )
{
@@ -1480,6 +1491,12 @@
"/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;\n");
if (disable_log_bin)
fprintf(result_file, "/*!32316 SET SQL_LOG_BIN=@OLD_SQL_LOG_BIN*/;\n");
+
+ if (charset)
+ fprintf(result_file,
+ "/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;\n"
+ "/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;\n"
+ "/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;\n");
if (tmpdir.list)
free_tmpdir(&tmpdir);
--- 1.551/sql/mysqld.cc 2006-05-29 16:42:55 +03:00
+++ 1.552/sql/mysqld.cc 2006-05-30 16:07:39 +03:00
@@ -605,7 +605,7 @@
pthread_mutex_t LOCK_des_key_file;
#endif
rw_lock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave;
-pthread_cond_t COND_refresh,COND_thread_count;
+pthread_cond_t COND_refresh, COND_thread_count, COND_global_read_lock;
pthread_t signal_thread;
pthread_attr_t connection_attrib;
pthread_mutex_t LOCK_server_started;
@@ -1335,6 +1335,7 @@
(void) pthread_mutex_destroy(&LOCK_prepared_stmt_count);
(void) pthread_cond_destroy(&COND_thread_count);
(void) pthread_cond_destroy(&COND_refresh);
+ (void) pthread_cond_destroy(&COND_global_read_lock);
(void) pthread_cond_destroy(&COND_thread_cache);
(void) pthread_cond_destroy(&COND_flush_thread_cache);
(void) pthread_cond_destroy(&COND_manager);
@@ -1757,13 +1758,11 @@
}
}
- DBUG_PRINT("info", ("sending a broadcast"));
-
/* Tell main we are ready */
(void) pthread_mutex_unlock(&LOCK_thread_count);
/* It's safe to broadcast outside a lock (COND... is not deleted here) */
+ DBUG_PRINT("signal", ("Broadcasting COND_thread_count"));
(void) pthread_cond_broadcast(&COND_thread_count);
- DBUG_PRINT("info", ("unlocked thread_count mutex"));
#ifdef ONE_THREAD
if (!(test_flags & TEST_NO_THREADS)) // For debugging under Linux
#endif
@@ -2859,6 +2858,7 @@
(void) my_rwlock_init(&LOCK_grant, NULL);
(void) pthread_cond_init(&COND_thread_count,NULL);
(void) pthread_cond_init(&COND_refresh,NULL);
+ (void) pthread_cond_init(&COND_global_read_lock,NULL);
(void) pthread_cond_init(&COND_thread_cache,NULL);
(void) pthread_cond_init(&COND_flush_thread_cache,NULL);
(void) pthread_cond_init(&COND_manager,NULL);
@@ -5021,7 +5021,7 @@
REQUIRED_ARG, 2/*default*/, 0/*min-value*/, 2/*max-value*/, 0, 0, 0},
{"exit-info", 'T', "Used for debugging; Use at your own risk!", 0, 0, 0,
GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0},
- {"external-locking", OPT_USE_LOCKING, "Use system (external) locking. With this option
enabled you can run myisamchk to test (not repair) tables while the MySQL server is
running.",
+ {"external-locking", OPT_USE_LOCKING, "Use system (external) locking (disabled by
default). With this option enabled you can run myisamchk to test (not repair) tables
while the MySQL server is running. Disable with --skip-external-locking.",
(gptr*) &opt_external_locking, (gptr*) &opt_external_locking,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"flush", OPT_FLUSH, "Flush tables to disk between SQL commands.", 0, 0, 0,
--- 1.193/sql/sql_acl.cc 2006-05-20 05:00:55 +03:00
+++ 1.194/sql/sql_acl.cc 2006-05-30 14:24:26 +03:00
@@ -1088,6 +1088,8 @@
sctx->master_access= 0;
sctx->db_access= 0;
+ sctx->priv_user= (char *) "";
+ *sctx->priv_host= 0;
/*
Find acl entry in user database.
@@ -3692,6 +3694,7 @@
TABLE_LIST *table, *first_not_own_table= thd->lex->first_not_own_table();
Security_context *sctx= thd->security_ctx;
uint i;
+ ulong orig_want_access= want_access;
DBUG_ENTER("check_grant");
DBUG_ASSERT(number > 0);
@@ -3713,18 +3716,22 @@
table->grant.orig_want_privilege= (want_access & ~SHOW_VIEW_ACL);
}
- want_access&= ~sctx->master_access;
- if (!want_access)
- DBUG_RETURN(0); // ok
-
rw_rdlock(&LOCK_grant);
for (table= tables;
table && number-- && table != first_not_own_table;
table= table->next_global)
{
GRANT_TABLE *grant_table;
+ sctx = test(table->security_ctx) ?
+ table->security_ctx : thd->security_ctx;
+
+ want_access= orig_want_access;
+ want_access&= ~sctx->master_access;
+ if (!want_access)
+ continue; // ok
+
if (!(~table->grant.privilege & want_access) ||
- table->derived || table->schema_table || table->belong_to_view)
+ table->derived || table->schema_table)
{
/*
It is subquery in the FROM clause. VIEW set table->derived after
--- 1.325/sql/sql_base.cc 2006-05-19 17:39:28 +03:00
+++ 1.326/sql/sql_base.cc 2006-05-30 16:07:39 +03:00
@@ -25,7 +25,7 @@
#include <m_ctype.h>
#include <my_dir.h>
#include <hash.h>
-#ifdef __WIN__
+#ifdef __WIN__
#include <io.h>
#endif
@@ -879,7 +879,7 @@
bool found=1;
/* Wait until all threads has closed all the tables we had locked */
DBUG_PRINT("info",
- ("Waiting for others threads to close their open tables"));
+ ("Waiting for other threads to close their open tables"));
while (found && ! thd->killed)
{
found=0;
@@ -890,6 +890,7 @@
((table->s->version) < refresh_version &&
table->db_stat))
{
found=1;
+ DBUG_PRINT("signal", ("Waiting for COND_refresh"));
pthread_cond_wait(&COND_refresh,&LOCK_open);
break;
}
@@ -1684,6 +1685,7 @@
thd->mysys_var->current_cond= cond;
proc_info=thd->proc_info;
thd->proc_info="Waiting for table";
+ DBUG_ENTER("wait_for_condition");
if (!thd->killed)
(void) pthread_cond_wait(cond, mutex);
@@ -1704,6 +1706,7 @@
thd->mysys_var->current_cond= 0;
thd->proc_info= proc_info;
pthread_mutex_unlock(&thd->mysys_var->mutex);
+ DBUG_VOID_RETURN;
}
@@ -1982,6 +1985,10 @@
{
if (table->s->version != refresh_version)
{
+ DBUG_PRINT("note",
+ ("Found table '%s.%s' with different refresh version",
+ table_list->db, table_list->table_name));
+
/*
Don't close tables if we are working with a log table or were
asked not to close the table explicitly
@@ -5368,6 +5375,58 @@
/*
+ prepare tables and check access for the view tables
+
+ SYNOPSIS
+ setup_tables_and_check_view_access()
+ thd Thread handler
+ context name resolution contest to setup table list there
+ from_clause Top-level list of table references in the FROM clause
+ tables Table list (select_lex->table_list)
+ conds Condition of current SELECT (can be changed by VIEW)
+ leaves List of join table leaves list (select_lex->leaf_tables)
+ refresh It is onle refresh for subquery
+ select_insert It is SELECT ... INSERT command
+ want_access what access is needed
+
+ NOTE
+ a wrapper for check_tables that will also check the resulting
+ table leaves list for access to all the tables that belong to a view
+
+ RETURN
+ FALSE ok; In this case *map will include the chosen index
+ TRUE error
+*/
+bool setup_tables_and_check_access(THD *thd,
+ Name_resolution_context *context,
+ List<TABLE_LIST> *from_clause,
+ TABLE_LIST *tables,
+ Item **conds, TABLE_LIST **leaves,
+ bool select_insert,
+ ulong want_access)
+{
+ TABLE_LIST *leaves_tmp = NULL;
+
+ if (setup_tables (thd, context, from_clause, tables, conds,
+ &leaves_tmp, select_insert))
+ return TRUE;
+
+ if (leaves)
+ *leaves = leaves_tmp;
+
+ for (; leaves_tmp; leaves_tmp= leaves_tmp->next_leaf)
+ if (leaves_tmp->belong_to_view &&
+ check_one_table_access(thd, want_access, leaves_tmp))
+ {
+ tables->hide_view_error(thd);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/*
Create a key_map from a list of index names
SYNOPSIS
@@ -6003,6 +6062,7 @@
TABLE_SHARE *share;
bool result= 0, signalled= 0;
DBUG_ENTER("remove_table_from_cache");
+ DBUG_PRINT("enter", ("Table: '%s.%s' flags: %u", db, table_name, flags));
key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1;
for (;;)
@@ -6029,7 +6089,10 @@
DBUG_PRINT("info", ("Table was in use by other thread"));
in_use->some_tables_deleted=1;
if (table->db_stat)
+ {
+ DBUG_PRINT("info", ("Found another active instance of the table"));
result=1;
+ }
/* Kill delayed insert threads */
if ((in_use->system_thread & SYSTEM_THREAD_DELAYED_INSERT) &&
! in_use->killed)
@@ -6084,6 +6147,12 @@
if (result && (flags & RTFC_WAIT_OTHER_THREAD_FLAG))
{
+ /*
+ Signal any thread waiting for tables to be freed to
+ reopen their tables
+ */
+ (void) pthread_cond_broadcast(&COND_refresh);
+ DBUG_PRINT("info", ("Waiting for refresh signal"));
if (!(flags & RTFC_CHECK_KILLED_FLAG) || !thd->killed)
{
dropping_tables++;
--- 1.181/sql/sql_delete.cc 2006-04-13 23:49:23 +03:00
+++ 1.182/sql/sql_delete.cc 2006-05-30 14:24:26 +03:00
@@ -394,10 +394,11 @@
DBUG_ENTER("mysql_prepare_delete");
thd->lex->allow_sum_func= 0;
- if (setup_tables(thd, &thd->lex->select_lex.context,
- &thd->lex->select_lex.top_join_list,
- table_list, conds, &select_lex->leaf_tables,
- FALSE) ||
+ if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
+ &thd->lex->select_lex.top_join_list,
+ table_list, conds,
+ &select_lex->leaf_tables, FALSE,
+ DELETE_ACL) ||
setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
setup_ftfuncs(select_lex))
DBUG_RETURN(TRUE);
@@ -456,10 +457,11 @@
lex->query_tables also point on local list of DELETE SELECT_LEX
*/
- if (setup_tables(thd, &thd->lex->select_lex.context,
- &thd->lex->select_lex.top_join_list,
- lex->query_tables, &lex->select_lex.where,
- &lex->select_lex.leaf_tables, FALSE))
+ if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
+ &thd->lex->select_lex.top_join_list,
+ lex->query_tables, &lex->select_lex.where,
+ &lex->select_lex.leaf_tables, FALSE,
+ DELETE_ACL))
DBUG_RETURN(TRUE);
--- 1.201/sql/sql_insert.cc 2006-05-23 10:24:59 +03:00
+++ 1.202/sql/sql_insert.cc 2006-05-30 14:24:26 +03:00
@@ -759,10 +759,11 @@
bool insert_into_view= (table_list->view != 0);
DBUG_ENTER("mysql_prepare_insert_check_table");
- if (setup_tables(thd, &thd->lex->select_lex.context,
- &thd->lex->select_lex.top_join_list,
- table_list, where, &thd->lex->select_lex.leaf_tables,
- select_insert))
+ if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
+ &thd->lex->select_lex.top_join_list,
+ table_list, where,
+ &thd->lex->select_lex.leaf_tables,
+ select_insert, INSERT_ACL))
DBUG_RETURN(TRUE);
if (insert_into_view && !fields.elements)
@@ -2588,12 +2589,13 @@
while ((item=it++))
{
create_field *cr_field;
- Field *field;
+ Field *field, *def_field;
if (item->type() == Item::FUNC_ITEM)
- field=item->tmp_table_field(&tmp_table);
+ field= item->tmp_table_field(&tmp_table);
else
- field=create_tmp_field(thd, &tmp_table, item, item->type(),
- (Item ***) 0, &tmp_field, 0, 0, 0, 0, 0);
+ field= create_tmp_field(thd, &tmp_table, item, item->type(),
+ (Item ***) 0, &tmp_field, &def_field, 0, 0, 0, 0,
+ 0);
if (!field ||
!(cr_field=new create_field(field,(item->type() == Item::FIELD_ITEM ?
((Item_field *)item)->field :
--- 1.181/sql/sql_lex.cc 2006-05-24 15:33:37 +03:00
+++ 1.182/sql/sql_lex.cc 2006-05-30 16:07:39 +03:00
@@ -152,8 +152,7 @@
lex->found_semicolon= 0;
lex->safe_to_cache_query= 1;
lex->time_zone_tables_used= 0;
- lex->leaf_tables_insert= lex->query_tables= 0;
- lex->query_tables_last= &lex->query_tables;
+ lex->leaf_tables_insert= 0;
lex->variables_used= 0;
lex->empty_field_list_on_rset= 0;
lex->select_lex.select_number= 1;
@@ -175,17 +174,12 @@
lex->sphead= NULL;
lex->spcont= NULL;
lex->proc_list.first= 0;
- lex->query_tables_own_last= 0;
lex->escape_used= lex->et_compile_phase= FALSE;
+ lex->reset_query_tables_list(FALSE);
lex->name= 0;
lex->et= NULL;
- if (lex->sroutines.records)
- my_hash_reset(&lex->sroutines);
- lex->sroutines_list.empty();
- lex->sroutines_list_own_last= lex->sroutines_list.next;
- lex->sroutines_list_own_elements= 0;
lex->nest_level=0 ;
lex->allow_sum_func= 0;
lex->in_sum_func= NULL;
@@ -1604,6 +1598,52 @@
/*
+ Initialize (or reset) Query_tables_list object.
+
+ SYNOPSIS
+ reset_query_tables_list()
+ init TRUE - we should perform full initialization of object with
+ allocating needed memory
+ FALSE - object is already initialized so we should only reset
+ its state so it can be used for parsing/processing
+ of new statement
+
+ DESCRIPTION
+ This method initializes Query_tables_list so it can be used as part
+ of LEX object for parsing/processing of statement. One can also use
+ this method to reset state of already initialized Query_tables_list
+ so it can be used for processing of new statement.
+*/
+
+void Query_tables_list::reset_query_tables_list(bool init)
+{
+ query_tables= 0;
+ query_tables_last= &query_tables;
+ query_tables_own_last= 0;
+ if (init)
+ hash_init(&sroutines, system_charset_info, 0, 0, 0, sp_sroutine_key, 0, 0);
+ else if (sroutines.records)
+ my_hash_reset(&sroutines);
+ sroutines_list.empty();
+ sroutines_list_own_last= sroutines_list.next;
+ sroutines_list_own_elements= 0;
+}
+
+
+/*
+ Destroy Query_tables_list object with freeing all resources used by it.
+
+ SYNOPSIS
+ destroy_query_tables_list()
+*/
+
+void Query_tables_list::destroy_query_tables_list()
+{
+ hash_free(&sroutines);
+}
+
+
+/*
Initialize LEX object.
SYNOPSIS
@@ -1619,12 +1659,9 @@
st_lex::st_lex()
:result(0), yacc_yyss(0), yacc_yyvs(0),
- sql_command(SQLCOM_END), query_tables_own_last(0)
+ sql_command(SQLCOM_END)
{
- hash_init(&sroutines, system_charset_info, 0, 0, 0, sp_sroutine_key, 0, 0);
- sroutines_list.empty();
- sroutines_list_own_last= sroutines_list.next;
- sroutines_list_own_elements= 0;
+ reset_query_tables_list(TRUE);
}
@@ -2008,6 +2045,11 @@
SYNOPSIS
st_lex::cleanup_after_one_table_open()
+
+ NOTE
+ This method is mostly responsible for cleaning up of selects lists and
+ derived tables state. To rollback changes in Query_tables_list one has
+ to call Query_tables_list::reset_query_tables_list(FALSE).
*/
void st_lex::cleanup_after_one_table_open()
@@ -2034,11 +2076,41 @@
select_lex.cut_subtree();
}
time_zone_tables_used= 0;
- if (sroutines.records)
- my_hash_reset(&sroutines);
- sroutines_list.empty();
- sroutines_list_own_last= sroutines_list.next;
- sroutines_list_own_elements= 0;
+}
+
+
+/*
+ Save current state of Query_tables_list for this LEX, and prepare it
+ for processing of new statemnt.
+
+ SYNOPSIS
+ reset_n_backup_query_tables_list()
+ backup Pointer to Query_tables_list instance to be used for backup
+*/
+
+void st_lex::reset_n_backup_query_tables_list(Query_tables_list *backup)
+{
+ backup->set_query_tables_list(this);
+ /*
+ We have to perform full initialization here since otherwise we
+ will damage backed up state.
+ */
+ this->reset_query_tables_list(TRUE);
+}
+
+
+/*
+ Restore state of Query_tables_list for this LEX from backup.
+
+ SYNOPSIS
+ restore_backup_query_tables_list()
+ backup Pointer to Query_tables_list instance used for backup
+*/
+
+void st_lex::restore_backup_query_tables_list(Query_tables_list *backup)
+{
+ this->destroy_query_tables_list();
+ this->set_query_tables_list(backup);
}
--- 1.231/sql/sql_lex.h 2006-05-23 21:25:02 +03:00
+++ 1.232/sql/sql_lex.h 2006-05-30 14:24:26 +03:00
@@ -752,9 +752,95 @@
enum xa_option_words {XA_NONE, XA_JOIN, XA_RESUME, XA_ONE_PHASE,
XA_SUSPEND, XA_FOR_MIGRATE};
+
+/*
+ Class representing list of all tables used by statement.
+ It also contains information about stored functions used by statement
+ since during its execution we may have to add all tables used by its
+ stored functions/triggers to this list in order to pre-open and lock
+ them.
+
+ Also used by st_lex::reset_n_backup/restore_backup_query_tables_list()
+ methods to save and restore this information.
+*/
+
+class Query_tables_list
+{
+public:
+ /* Global list of all tables used by this statement */
+ TABLE_LIST *query_tables;
+ /* Pointer to next_global member of last element in the previous list. */
+ TABLE_LIST **query_tables_last;
+ /*
+ If non-0 then indicates that query requires prelocking and points to
+ next_global member of last own element in query table list (i.e. last
+ table which was not added to it as part of preparation to prelocking).
+ 0 - indicates that this query does not need prelocking.
+ */
+ TABLE_LIST **query_tables_own_last;
+ /* Set of stored routines called by statement. */
+ HASH sroutines;
+ /*
+ List linking elements of 'sroutines' set. Allows you to add new elements
+ to this set as you iterate through the list of existing elements.
+ 'sroutines_list_own_last' is pointer to ::next member of last element of
+ this list which represents routine which is explicitly used by query.
+ 'sroutines_list_own_elements' number of explicitly used routines.
+ We use these two members for restoring of 'sroutines_list' to the state
+ in which it was right after query parsing.
+ */
+ SQL_LIST sroutines_list;
+ byte **sroutines_list_own_last;
+ uint sroutines_list_own_elements;
+
+ /*
+ These constructor and destructor serve for creation/destruction
+ of Query_tables_list instances which are used as backup storage.
+ */
+ Query_tables_list() {}
+ ~Query_tables_list() {}
+
+ /* Initializes (or resets) Query_tables_list object for "real" use. */
+ void reset_query_tables_list(bool init);
+ void destroy_query_tables_list();
+ void set_query_tables_list(Query_tables_list *state)
+ {
+ *this= *state;
+ }
+
+ void add_to_query_tables(TABLE_LIST *table)
+ {
+ *(table->prev_global= query_tables_last)= table;
+ query_tables_last= &table->next_global;
+ }
+ bool requires_prelocking()
+ {
+ return test(query_tables_own_last);
+ }
+ void mark_as_requiring_prelocking(TABLE_LIST **tables_own_last)
+ {
+ query_tables_own_last= tables_own_last;
+ }
+ /* Return pointer to first not-own table in query-tables or 0 */
+ TABLE_LIST* first_not_own_table()
+ {
+ return ( query_tables_own_last ? *query_tables_own_last : 0);
+ }
+ void chop_off_not_own_tables()
+ {
+ if (query_tables_own_last)
+ {
+ *query_tables_own_last= 0;
+ query_tables_last= query_tables_own_last;
+ query_tables_own_last= 0;
+ }
+ }
+};
+
+
/* The state of the lex parsing. This is saved in the THD struct */
-typedef struct st_lex
+typedef struct st_lex : public Query_tables_list
{
uint yylineno,yytoklen; /* Simulate lex */
LEX_YYSTYPE yylval;
@@ -787,14 +873,6 @@
gptr yacc_yyss,yacc_yyvs;
THD *thd;
CHARSET_INFO *charset;
- TABLE_LIST *query_tables; /* global list of all tables in this query */
- /*
- last element next_global of previous list (used only for list building
- during parsing and VIEW processing. This pointer could be invalid during
- processing of information schema tables(see get_schema_tables_result
- function)
- */
- TABLE_LIST **query_tables_last;
/* store original leaf_tables for INSERT SELECT and PS/SP */
TABLE_LIST *leaf_tables_insert;
/* Position (first character index) of SELECT of CREATE VIEW statement */
@@ -935,20 +1013,6 @@
bool sp_lex_in_use; /* Keep track on lex usage in SPs for error handling */
bool all_privileges;
sp_pcontext *spcont;
- /* Set of stored routines called by statement. */
- HASH sroutines;
- /*
- List linking elements of 'sroutines' set. Allows you to add new elements
- to this set as you iterate through the list of existing elements.
- 'sroutines_list_own_last' is pointer to ::next member of last element of
- this list which represents routine which is explicitly used by query.
- 'sroutines_list_own_elements' number of explicitly used routines.
- We use these two members for restoring of 'sroutines_list' to the state
- in which it was right after query parsing.
- */
- SQL_LIST sroutines_list;
- byte **sroutines_list_own_last;
- uint sroutines_list_own_elements;
st_sp_chistics sp_chistics;
@@ -989,14 +1053,6 @@
const char *stmt_definition_begin;
/*
- If non-0 then indicates that query requires prelocking and points to
- next_global member of last own element in query table list (i.e. last
- table which was not added to it as part of preparation to prelocking).
- 0 - indicates that this query does not need prelocking.
- */
- TABLE_LIST **query_tables_own_last;
-
- /*
Pointers to part of LOAD DATA statement that should be rewritten
during replication ("LOCAL 'filename' REPLACE INTO" part).
*/
@@ -1014,7 +1070,7 @@
virtual ~st_lex()
{
- hash_free(&sroutines);
+ destroy_query_tables_list();
}
inline void uncacheable(uint8 cause)
@@ -1039,11 +1095,6 @@
TABLE_LIST *unlink_first_table(bool *link_to_local);
void link_first_table_back(TABLE_LIST *first, bool link_to_local);
void first_lists_tables_same();
- inline void add_to_query_tables(TABLE_LIST *table)
- {
- *(table->prev_global= query_tables_last)= table;
- query_tables_last= &table->next_global;
- }
bool add_time_zone_tables_to_query_tables(THD *thd);
bool can_be_merged();
@@ -1075,28 +1126,7 @@
return FALSE;
}
}
- inline bool requires_prelocking()
- {
- return test(query_tables_own_last);
- }
- inline void mark_as_requiring_prelocking(TABLE_LIST **tables_own_last)
- {
- query_tables_own_last= tables_own_last;
- }
- /* Return pointer to first not-own table in query-tables or 0 */
- TABLE_LIST* first_not_own_table()
- {
- return ( query_tables_own_last ? *query_tables_own_last : 0);
- }
- void chop_off_not_own_tables()
- {
- if (query_tables_own_last)
- {
- *query_tables_own_last= 0;
- query_tables_last= query_tables_own_last;
- query_tables_own_last= 0;
- }
- }
+
void cleanup_after_one_table_open();
bool push_context(Name_resolution_context *context)
@@ -1113,6 +1143,9 @@
{
return context_stack.head();
}
+
+ void reset_n_backup_query_tables_list(Query_tables_list *backup);
+ void restore_backup_query_tables_list(Query_tables_list *backup);
} LEX;
struct st_lex_local: public st_lex
--- 1.97/sql/sql_load.cc 2006-04-16 04:17:26 +03:00
+++ 1.98/sql/sql_load.cc 2006-05-30 14:24:26 +03:00
@@ -153,10 +153,11 @@
ha_enable_transaction(thd, FALSE);
if (open_and_lock_tables(thd, table_list))
DBUG_RETURN(TRUE);
- if (setup_tables(thd, &thd->lex->select_lex.context,
- &thd->lex->select_lex.top_join_list,
- table_list, &unused_conds,
- &thd->lex->select_lex.leaf_tables, FALSE))
+ if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
+ &thd->lex->select_lex.top_join_list,
+ table_list, &unused_conds,
+ &thd->lex->select_lex.leaf_tables, FALSE,
+ INSERT_ACL | UPDATE_ACL))
DBUG_RETURN(-1);
if (!table_list->table || // do not suport join view
!table_list->updatable || // and derived tables
--- 1.552/sql/sql_parse.cc 2006-05-29 16:16:01 +03:00
+++ 1.553/sql/sql_parse.cc 2006-05-30 14:24:27 +03:00
@@ -5188,23 +5188,35 @@
bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *all_tables)
{
+ Security_context * backup_ctx= thd->security_ctx;
+
+ /* we need to switch to the saved context (if any) */
+ if (all_tables->security_ctx)
+ thd->security_ctx= all_tables->security_ctx;
+
if (check_access(thd, privilege, all_tables->db,
&all_tables->grant.privilege, 0, 0,
test(all_tables->schema_table)))
- return 1;
+ goto deny;
/* Show only 1 table for check_grant */
if (grant_option && check_grant(thd, privilege, all_tables, 0, 1, 0))
- return 1;
+ goto deny;
+
+ thd->security_ctx= backup_ctx;
/* Check rights on tables of subselects and implictly opened tables */
TABLE_LIST *subselects_tables;
if ((subselects_tables= all_tables->next_global))
{
if ((check_table_access(thd, SELECT_ACL, subselects_tables, 0)))
- return 1;
+ goto deny;
}
return 0;
+
+deny:
+ thd->security_ctx= backup_ctx;
+ return 1;
}
@@ -5385,6 +5397,7 @@
ulong found_access=0;
TABLE_LIST *org_tables= tables;
TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table();
+ Security_context *sctx= thd->security_ctx, *backup_ctx= thd->security_ctx;
/*
The check that first_not_own_table is not reached is for the case when
the given table list refers to the list for prelocking (contains tables
@@ -5392,12 +5405,17 @@
*/
for (; tables != first_not_own_table; tables= tables->next_global)
{
+ if (tables->security_ctx)
+ sctx= tables->security_ctx;
+ else
+ sctx= backup_ctx;
+
if (tables->schema_table &&
(want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL)))
{
if (!no_errors)
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
- thd->security_ctx->priv_user, thd->security_ctx->priv_host,
+ sctx->priv_user, sctx->priv_host,
information_schema_name.str);
return TRUE;
}
@@ -5406,12 +5424,13 @@
Remove SHOW_VIEW_ACL, because it will be checked during making view
*/
tables->grant.orig_want_privilege= (want_access & ~SHOW_VIEW_ACL);
- if (tables->derived || tables->schema_table || tables->belong_to_view ||
+ if (tables->derived || tables->schema_table ||
(tables->table && (int)tables->table->s->tmp_table) ||
my_tz_check_n_skip_implicit_tables(&tables,
thd->lex->time_zone_tables_used))
continue;
- if ((thd->security_ctx->master_access & want_access) ==
+ thd->security_ctx= sctx;
+ if ((sctx->master_access & want_access) ==
(want_access & ~EXTRA_ACL) &&
thd->db)
tables->grant.privilege= want_access;
@@ -5423,19 +5442,23 @@
{
if (check_access(thd,want_access,tables->db,&tables->grant.privilege,
0, no_errors, test(tables->schema_table)))
- return TRUE; // Access denied
+ goto deny; // Access denied
found_access=tables->grant.privilege;
found=1;
}
}
else if (check_access(thd,want_access,tables->db,&tables->grant.privilege,
0, no_errors, test(tables->schema_table)))
- return TRUE;
+ goto deny;
}
+ thd->security_ctx= backup_ctx;
if (grant_option)
return check_grant(thd,want_access & ~EXTRA_ACL,org_tables,
test(want_access & EXTRA_ACL), UINT_MAX, no_errors);
return FALSE;
+deny:
+ thd->security_ctx= backup_ctx;
+ return TRUE;
}
--- 1.407/sql/sql_select.cc 2006-05-25 13:58:04 +03:00
+++ 1.408/sql/sql_select.cc 2006-05-30 16:07:40 +03:00
@@ -337,9 +337,10 @@
/* Check that all tables, fields, conds and order are ok */
if ((!(select_options & OPTION_SETUP_TABLES_DONE) &&
- setup_tables(thd, &select_lex->context, join_list,
- tables_list, &conds, &select_lex->leaf_tables,
- FALSE)) ||
+ setup_tables_and_check_access(thd, &select_lex->context, join_list,
+ tables_list, &conds,
+ &select_lex->leaf_tables, FALSE,
+ SELECT_ACL)) ||
setup_wild(thd, tables_list, fields_list, &all_fields, wild_num) ||
select_lex->setup_ref_array(thd, og_num) ||
setup_fields(thd, (*rref_pointer_array), fields_list, 1,
@@ -8175,6 +8176,7 @@
in this array
from_field if field will be created using other field as example,
pointer example field will be written here
+ default_field If field has a default value field, store it here
group 1 if we are going to do a relative group by on result
modify_item 1 if item->result_field should point to new item.
This is relevent for how fill_record() is going to
@@ -8193,6 +8195,7 @@
Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
Item ***copy_func, Field **from_field,
+ Field **default_field,
bool group, bool modify_item,
bool table_cant_handle_bit_fields,
bool make_copy_field,
@@ -8260,7 +8263,7 @@
if (orig_type == Item::REF_ITEM && orig_modify)
((Item_ref*)orig_item)->set_result_field(result);
if (field->field->eq_def(result))
- result->dflt_field= field->field;
+ *default_field= field->field;
return result;
}
/* Fall through */
@@ -8349,7 +8352,7 @@
char *tmpname,path[FN_REFLEN];
byte *pos,*group_buff;
uchar *null_flags;
- Field **reg_field, **from_field;
+ Field **reg_field, **from_field, **default_field;
uint *blob_field;
Copy_field *copy=0;
KEY *keyinfo;
@@ -8419,6 +8422,7 @@
&table, sizeof(*table),
&share, sizeof(*share),
®_field, sizeof(Field*) * (field_count+1),
+ &default_field, sizeof(Field*) * (field_count),
&blob_field, sizeof(uint)*(field_count+1),
&from_field, sizeof(Field*)*field_count,
©_func, sizeof(*copy_func)*(copy_func_count+1),
@@ -8448,6 +8452,7 @@
bzero((char*) table,sizeof(*table));
bzero((char*) reg_field,sizeof(Field*)*(field_count+1));
+ bzero((char*) default_field, sizeof(Field*) * (field_count));
bzero((char*) from_field,sizeof(Field*)*field_count);
table->mem_root= own_root;
@@ -8514,9 +8519,11 @@
Item *arg= *argp;
if (!arg->const_item())
{
+ uint field_index= (uint) (reg_field - table->field);
Field *new_field=
create_tmp_field(thd, table, arg, arg->type(), ©_func,
- tmp_from_field, group != 0,not_all_columns,
+ tmp_from_field, &default_field[field_index],
+ group != 0,not_all_columns,
distinct, 0,
param->convert_blob_length);
if (!new_field)
@@ -8525,12 +8532,12 @@
reclength+=new_field->pack_length();
if (new_field->flags & BLOB_FLAG)
{
- *blob_field++= (uint) (reg_field - table->field);
+ *blob_field++= field_index;
blob_count++;
}
if (new_field->type() == FIELD_TYPE_BIT)
total_uneven_bit_length+= new_field->field_length & 7;
- new_field->field_index= (uint) (reg_field - table->field);
+ new_field->field_index= field_index;
*(reg_field++)= new_field;
if (new_field->real_type() == MYSQL_TYPE_STRING ||
new_field->real_type() == MYSQL_TYPE_VARCHAR)
@@ -8557,6 +8564,7 @@
}
else
{
+ uint field_index= (uint) (reg_field - table->field);
/*
The last parameter to create_tmp_field() is a bit tricky:
@@ -8573,7 +8581,8 @@
Field *new_field= (param->schema_table) ?
create_tmp_field_for_schema(thd, item, table) :
create_tmp_field(thd, table, item, type, ©_func,
- tmp_from_field, group != 0,
+ tmp_from_field, &default_field[field_index],
+ group != 0,
!force_copy_fields &&
(not_all_columns || group !=0),
item->marker == 4, force_copy_fields,
@@ -8595,7 +8604,7 @@
total_uneven_bit_length+= new_field->field_length & 7;
if (new_field->flags & BLOB_FLAG)
{
- *blob_field++= (uint) (reg_field - table->field);
+ *blob_field++= field_index;
blob_count++;
}
if (item->marker == 4 && item->maybe_null)
@@ -8605,7 +8614,7 @@
}
new_field->query_id= thd->query_id;
new_field->fieldnr= ++fieldnr;
- new_field->field_index= (uint) (reg_field - table->field);
+ new_field->field_index= field_index;
*(reg_field++) =new_field;
}
if (!--hidden_field_count)
@@ -8625,6 +8634,7 @@
}
DBUG_ASSERT(field_count >= (uint) (reg_field - table->field));
field_count= (uint) (reg_field - table->field);
+ *reg_field= 0;
*blob_field= 0; // End marker
share->fields= field_count;
@@ -8742,30 +8752,31 @@
}
field->reset();
- if (field->dflt_field && field->dflt_field->ptr)
+ /*
+ Test if there is a default field value. The test for ->ptr is to skip
+ 'offset' fields generated by initalize_tables
+ */
+ if (default_field[i] && default_field[i]->ptr)
{
/*
- field->dflt_field is set only in the cases when 'field' can
- inherit the default value that is defined for the field referred
- by the Item_field object from which 'field' has been created.
- For a field created not from a Item_field item dflt_field == 0.
+ default_field[i] is set only in the cases when 'field' can
+ inherit the default value that is defined for the field referred
+ by the Item_field object from which 'field' has been created.
*/
my_ptrdiff_t diff;
- Field *orig_field= field->dflt_field;
+ Field *orig_field= default_field[i];
/* Get the value from default_values */
diff= (my_ptrdiff_t) (orig_field->table->s->default_values-
orig_field->table->record[0]);
orig_field->move_field_offset(diff); // Points now at default_values
- bool is_null= orig_field->is_real_null();
- char *from= orig_field->ptr;
- orig_field->move_field_offset(-diff); // Back to record[0]
- if (is_null)
+ if (orig_field->is_real_null())
field->set_null();
else
{
field->set_notnull();
- memcpy(field->ptr, from, field->pack_length());
+ memcpy(field->ptr, orig_field->ptr, field->pack_length());
}
+ orig_field->move_field_offset(-diff); // Back to record[0]
}
if (from_field[i])
@@ -12309,6 +12320,8 @@
Item::Type order_item_type;
Item **select_item; /* The corresponding item from the SELECT clause. */
Field *from_field; /* The corresponding field from the FROM clause. */
+ uint counter;
+ bool unaliased;
/*
Local SP variables may be int but are expressions, not positions.
@@ -12330,8 +12343,6 @@
return FALSE;
}
/* Lookup the current GROUP/ORDER field in the SELECT clause. */
- uint counter;
- bool unaliased;
select_item= find_item_in_list(order_item, fields, &counter,
REPORT_EXCEPT_NOT_FOUND, &unaliased);
if (!select_item)
--- 1.338/sql/sql_show.cc 2006-05-29 16:16:02 +03:00
+++ 1.339/sql/sql_show.cc 2006-05-30 14:24:27 +03:00
@@ -2375,7 +2375,6 @@
TABLE *table= tables->table;
SELECT_LEX *select_lex= &lex->select_lex;
SELECT_LEX *old_all_select_lex= lex->all_selects_list;
- TABLE_LIST **save_query_tables_last= lex->query_tables_last;
enum_sql_command save_sql_command= lex->sql_command;
SELECT_LEX *lsel= tables->schema_select_lex;
ST_SCHEMA_TABLE *schema_table= tables->schema_table;
@@ -2394,6 +2393,7 @@
enum legacy_db_type not_used;
Open_tables_state open_tables_state_backup;
bool save_view_prepare_mode= lex->view_prepare_mode;
+ Query_tables_list query_tables_list_backup;
lex->view_prepare_mode= TRUE;
DBUG_ENTER("get_all_tables");
@@ -2406,6 +2406,8 @@
*/
lex->sql_command= SQLCOM_SHOW_FIELDS;
+ lex->reset_n_backup_query_tables_list(&query_tables_list_backup);
+
/*
We should not introduce deadlocks even if we already have some
tables open and locked, since we won't lock tables which we will
@@ -2446,8 +2448,7 @@
show_table_list->db),
show_table_list->alias));
thd->temporary_tables= 0;
- close_thread_tables(thd);
- show_table_list->table= 0;
+ close_tables_for_reopen(thd, &show_table_list);
goto err;
}
@@ -2558,9 +2559,10 @@
in this case.
*/
res= schema_table->process_table(thd, show_table_list, table,
- res, base_name,
- show_table_list->alias);
- close_thread_tables(thd);
+ res, base_name,
+ show_table_list->alias);
+ close_tables_for_reopen(thd, &show_table_list);
+ DBUG_ASSERT(!lex->query_tables_own_last);
if (res)
goto err;
}
@@ -2577,11 +2579,10 @@
error= 0;
err:
thd->restore_backup_open_tables_state(&open_tables_state_backup);
+ lex->restore_backup_query_tables_list(&query_tables_list_backup);
lex->derived_tables= derived_tables;
lex->all_selects_list= old_all_select_lex;
- lex->query_tables_last= save_query_tables_last;
lex->view_prepare_mode= save_view_prepare_mode;
- *save_query_tables_last= 0;
lex->sql_command= save_sql_command;
DBUG_RETURN(error);
}
--- 1.335/sql/sql_table.cc 2006-05-18 18:23:30 +03:00
+++ 1.336/sql/sql_table.cc 2006-05-30 16:07:40 +03:00
@@ -3896,6 +3896,7 @@
*/
ha_autocommit_or_rollback(thd, 1);
close_thread_tables(thd);
+ lex->reset_query_tables_list(FALSE);
if (protocol->write())
goto err;
continue;
@@ -3921,6 +3922,7 @@
protocol->store(buff, length, system_charset_info);
ha_autocommit_or_rollback(thd, 0);
close_thread_tables(thd);
+ lex->reset_query_tables_list(FALSE);
table->table=0; // For query cache
if (protocol->write())
goto err;
@@ -4673,7 +4675,8 @@
HA_CREATE_INFO *create_info,
ALTER_INFO *alter_info, uint order_num,
uint *index_drop_buffer, uint *index_drop_count,
- uint *index_add_buffer, uint *index_add_count)
+ uint *index_add_buffer, uint *index_add_count,
+ bool varchar)
{
Field **f_ptr, *field;
uint changes= 0, tmp;
@@ -4708,7 +4711,8 @@
create_info->used_fields & HA_CREATE_USED_CHARSET ||
create_info->used_fields & HA_CREATE_USED_DEFAULT_CHARSET ||
(alter_info->flags & (ALTER_RECREATE | ALTER_FOREIGN_KEY)) ||
- order_num)
+ order_num ||
+ (table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
DBUG_RETURN(ALTER_TABLE_DATA_CHANGED);
/*
@@ -4882,7 +4886,7 @@
uint db_create_options, used_fields;
handlerton *old_db_type, *new_db_type;
uint need_copy_table= 0;
- bool no_table_reopen= FALSE;
+ bool no_table_reopen= FALSE, varchar= FALSE;
#ifdef WITH_PARTITION_STORAGE_ENGINE
uint fast_alter_partition= 0;
bool partition_changed= FALSE;
@@ -5117,6 +5121,8 @@
Field **f_ptr,*field;
for (f_ptr=table->field ; (field= *f_ptr) ; f_ptr++)
{
+ if (field->type() == MYSQL_TYPE_STRING)
+ varchar= TRUE;
/* Check if field should be dropped */
Alter_drop *drop;
drop_it.rewind();
@@ -5452,7 +5458,8 @@
key_info_buffer, key_count,
create_info, alter_info, order_num,
index_drop_buffer, &index_drop_count,
- index_add_buffer, &index_add_count);
+ index_add_buffer, &index_add_count,
+ varchar);
}
/*
--- 1.190/sql/sql_update.cc 2006-04-05 19:12:23 +03:00
+++ 1.191/sql/sql_update.cc 2006-05-30 14:24:28 +03:00
@@ -748,9 +748,11 @@
tables.alias= table_list->alias;
thd->lex->allow_sum_func= 0;
- if (setup_tables(thd, &select_lex->context, &select_lex->top_join_list,
- table_list, conds, &select_lex->leaf_tables,
- FALSE) ||
+ if (setup_tables_and_check_access(thd, &select_lex->context,
+ &select_lex->top_join_list,
+ table_list, conds,
+ &select_lex->leaf_tables,
+ FALSE, UPDATE_ACL) ||
setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
select_lex->setup_ref_array(thd, order_num) ||
setup_order(thd, select_lex->ref_pointer_array,
@@ -841,10 +843,11 @@
call in setup_tables()).
*/
- if (setup_tables(thd, &lex->select_lex.context,
- &lex->select_lex.top_join_list,
- table_list, &lex->select_lex.where,
- &lex->select_lex.leaf_tables, FALSE))
+ if (setup_tables_and_check_access(thd, &lex->select_lex.context,
+ &lex->select_lex.top_join_list,
+ table_list, &lex->select_lex.where,
+ &lex->select_lex.leaf_tables, FALSE,
+ UPDATE_ACL))
DBUG_RETURN(TRUE);
if (setup_fields_with_no_wrap(thd, 0, *fields, 2, 0, 0))
--- 1.215/sql/table.cc 2006-05-22 22:54:55 +03:00
+++ 1.216/sql/table.cc 2006-05-30 14:24:28 +03:00
@@ -2821,7 +2821,8 @@
if (thd->net.last_errno == ER_BAD_FIELD_ERROR ||
thd->net.last_errno == ER_SP_DOES_NOT_EXIST ||
thd->net.last_errno == ER_PROCACCESS_DENIED_ERROR ||
- thd->net.last_errno == ER_COLUMNACCESS_DENIED_ERROR)
+ thd->net.last_errno == ER_COLUMNACCESS_DENIED_ERROR ||
+ thd->net.last_errno == ER_TABLEACCESS_DENIED_ERROR)
{
TABLE_LIST *top= top_table();
thd->clear_error();
@@ -3181,8 +3182,18 @@
definer.host.str,
thd->db))
{
- my_error(ER_NO_SUCH_USER, MYF(0), definer.user.str, definer.host.str);
- DBUG_RETURN(TRUE);
+ if (thd->lex->sql_command == SQLCOM_SHOW_CREATE)
+ {
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
+ ER_NO_SUCH_USER,
+ ER(ER_NO_SUCH_USER),
+ definer.user.str, definer.host.str);
+ }
+ else
+ {
+ my_error(ER_NO_SUCH_USER, MYF(0), definer.user.str, definer.host.str);
+ DBUG_RETURN(TRUE);
+ }
}
}
DBUG_RETURN(FALSE);
--- 1.20/mysql-test/r/heap_btree.result 2006-05-04 15:34:26 +03:00
+++ 1.21/mysql-test/r/heap_btree.result 2006-05-30 14:24:22 +03:00
@@ -256,3 +256,6 @@
INDEX_LENGTH
21
DROP TABLE t1;
+CREATE TABLE t1 (a INT, UNIQUE USING BTREE(a)) ENGINE=MEMORY;
+INSERT INTO t1 VALUES(NULL),(NULL);
+DROP TABLE t1;
--- 1.146/mysql-test/r/subselect.result 2006-05-20 05:00:54 +03:00
+++ 1.147/mysql-test/r/subselect.result 2006-05-30 14:24:22 +03:00
@@ -3183,3 +3183,24 @@
min(i)
1
drop table t1;
+CREATE TABLE t1 (i BIGINT UNSIGNED);
+INSERT INTO t1 VALUES (10000000000000000000);
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2 (i BIGINT UNSIGNED);
+INSERT INTO t2 VALUES (10000000000000000000);
+INSERT INTO t2 VALUES (1);
+/* simple test */
+SELECT t1.i FROM t1 JOIN t2 ON t1.i = t2.i;
+i
+10000000000000000000
+1
+/* subquery test */
+SELECT t1.i FROM t1 WHERE t1.i = (SELECT MAX(i) FROM t2);
+i
+10000000000000000000
+/* subquery test with cast*/
+SELECT t1.i FROM t1 WHERE t1.i = CAST((SELECT MAX(i) FROM t2) AS UNSIGNED);
+i
+10000000000000000000
+DROP TABLE t1;
+DROP TABLE t2;
--- 1.124/sql/item_subselect.cc 2006-05-20 05:00:55 +03:00
+++ 1.125/sql/item_subselect.cc 2006-05-30 14:24:25 +03:00
@@ -407,6 +407,7 @@
engine->fix_length_and_dec(row);
value= *row;
}
+ unsigned_flag= value->unsigned_flag;
/*
If there are not tables in subquery then ability to have NULL value
depends on SELECT list (if single row subquery have tables then it
--- 1.15/mysql-test/r/information_schema_db.result 2006-05-02 14:31:32 +03:00
+++ 1.16/mysql-test/r/information_schema_db.result 2006-05-30 14:24:22 +03:00
@@ -1,3 +1,7 @@
+drop table if exists t1,t2;
+drop view if exists v1,v2;
+drop function if exists f1;
+drop function if exists f2;
use INFORMATION_SCHEMA;
show tables;
Tables_in_information_schema
@@ -31,10 +35,12 @@
TABLE_PRIVILEGES
TRIGGERS
create database `inf%`;
+create database mbase;
use `inf%`;
show tables;
Tables_in_inf%
grant all privileges on `inf%`.* to 'mysqltest_1'@'localhost';
+grant all privileges on `mbase`.* to 'mysqltest_1'@'localhost';
create table t1 (f1 int);
create function func1(curr_int int) returns int
begin
@@ -43,9 +49,58 @@
return ret_val;
end|
create view v1 as select f1 from t1 where f1 = func1(f1);
+create function func2() returns int return 1;
+use mbase;
+create procedure p1 ()
+begin
+select table_name from information_schema.key_column_usage
+order by table_name;
+end|
+create table t1
+(f1 int(10) unsigned not null,
+f2 varchar(100) not null,
+primary key (f1), unique key (f2));
select * from information_schema.tables;
+call mbase.p1();
+call mbase.p1();
+call mbase.p1();
+use `inf%`;
drop user mysqltest_1@localhost;
+drop table t1;
+select table_name, table_type, table_comment from information_schema.tables
+where table_schema='inf%' and func2();
+table_name table_type table_comment
+v1 VIEW View 'inf%.v1' references invalid table(s) or column(s) or function(s) or define
+select table_name, table_type, table_comment from information_schema.tables
+where table_schema='inf%' and func2();
+table_name table_type table_comment
+v1 VIEW View 'inf%.v1' references invalid table(s) or column(s) or function(s) or define
drop view v1;
drop function func1;
-drop table t1;
+drop function func2;
drop database `inf%`;
+drop procedure mbase.p1;
+drop database mbase;
+use test;
+create table t1 (i int);
+create function f1 () returns int return (select max(i) from t1);
+create view v1 as select f1();
+create table t2 (id int);
+create function f2 () returns int return (select max(i) from t2);
+create view v2 as select f2();
+drop table t2;
+select table_name, table_type, table_comment from information_schema.tables
+where table_schema='test';
+table_name table_type table_comment
+t1 BASE TABLE
+v1 VIEW VIEW
+v2 VIEW View 'test.v2' references invalid table(s) or column(s) or function(s) or define
+drop table t1;
+select table_name, table_type, table_comment from information_schema.tables
+where table_schema='test';
+table_name table_type table_comment
+v1 VIEW View 'test.v1' references invalid table(s) or column(s) or function(s) or define
+v2 VIEW View 'test.v2' references invalid table(s) or column(s) or function(s) or define
+drop function f1;
+drop function f2;
+drop view v1, v2;
--- 1.18/mysql-test/r/view_grant.result 2006-05-17 16:05:48 +03:00
+++ 1.19/mysql-test/r/view_grant.result 2006-05-30 14:24:23 +03:00
@@ -535,3 +535,88 @@
v2 CREATE ALGORITHM=UNDEFINED DEFINER=`some_user`@`localhost` SQL SECURITY INVOKER VIEW
`v2` AS select 1 AS `1`
drop view v1;
drop view v2;
+CREATE DATABASE mysqltest1;
+CREATE USER readonly@localhost;
+CREATE TABLE mysqltest1.t1 (x INT);
+INSERT INTO mysqltest1.t1 VALUES (1), (2);
+CREATE SQL SECURITY INVOKER VIEW mysqltest1.v_t1 AS SELECT * FROM mysqltest1.t1;
+CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_ts AS SELECT * FROM mysqltest1.t1;
+CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_ti AS SELECT * FROM mysqltest1.t1;
+CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_tu AS SELECT * FROM mysqltest1.t1;
+CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_tus AS SELECT * FROM mysqltest1.t1;
+CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_td AS SELECT * FROM mysqltest1.t1;
+CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_tds AS SELECT * FROM mysqltest1.t1;
+GRANT SELECT, INSERT, UPDATE, DELETE ON mysqltest1.v_t1 TO readonly;
+GRANT SELECT ON mysqltest1.v_ts TO readonly;
+GRANT INSERT ON mysqltest1.v_ti TO readonly;
+GRANT UPDATE ON mysqltest1.v_tu TO readonly;
+GRANT UPDATE,SELECT ON mysqltest1.v_tus TO readonly;
+GRANT DELETE ON mysqltest1.v_td TO readonly;
+GRANT DELETE,SELECT ON mysqltest1.v_tds TO readonly;
+SELECT * FROM mysqltest1.v_t1;
+ERROR HY000: View 'mysqltest1.v_t1' references invalid table(s) or column(s) or
function(s) or definer/invoker of view lack rights to use them
+INSERT INTO mysqltest1.v_t1 VALUES(4);
+ERROR HY000: View 'mysqltest1.v_t1' references invalid table(s) or column(s) or
function(s) or definer/invoker of view lack rights to use them
+DELETE FROM mysqltest1.v_t1 WHERE x = 1;
+ERROR HY000: View 'mysqltest1.v_t1' references invalid table(s) or column(s) or
function(s) or definer/invoker of view lack rights to use them
+UPDATE mysqltest1.v_t1 SET x = 3 WHERE x = 2;
+ERROR HY000: View 'mysqltest1.v_t1' references invalid table(s) or column(s) or
function(s) or definer/invoker of view lack rights to use them
+UPDATE mysqltest1.v_t1 SET x = 3;
+ERROR HY000: View 'mysqltest1.v_t1' references invalid table(s) or column(s) or
function(s) or definer/invoker of view lack rights to use them
+DELETE FROM mysqltest1.v_t1;
+ERROR HY000: View 'mysqltest1.v_t1' references invalid table(s) or column(s) or
function(s) or definer/invoker of view lack rights to use them
+SELECT 1 FROM mysqltest1.v_t1;
+ERROR HY000: View 'mysqltest1.v_t1' references invalid table(s) or column(s) or
function(s) or definer/invoker of view lack rights to use them
+SELECT * FROM mysqltest1.t1;
+ERROR 42000: SELECT command denied to user 'readonly'@'localhost' for table 't1'
+SELECT * FROM mysqltest1.v_ts;
+x
+1
+2
+SELECT * FROM mysqltest1.v_ts, mysqltest1.t1 WHERE mysqltest1.t1.x = mysqltest1.v_ts.x;
+ERROR 42000: SELECT command denied to user 'readonly'@'localhost' for table 't1'
+SELECT * FROM mysqltest1.v_ti;
+ERROR 42000: SELECT command denied to user 'readonly'@'localhost' for table 'v_ti'
+INSERT INTO mysqltest1.v_ts VALUES (100);
+ERROR 42000: INSERT command denied to user 'readonly'@'localhost' for table 'v_ts'
+INSERT INTO mysqltest1.v_ti VALUES (100);
+UPDATE mysqltest1.v_ts SET x= 200 WHERE x = 100;
+ERROR 42000: UPDATE command denied to user 'readonly'@'localhost' for table 'v_ts'
+UPDATE mysqltest1.v_ts SET x= 200;
+ERROR 42000: UPDATE command denied to user 'readonly'@'localhost' for table 'v_ts'
+UPDATE mysqltest1.v_tu SET x= 200 WHERE x = 100;
+UPDATE mysqltest1.v_tus SET x= 200 WHERE x = 100;
+UPDATE mysqltest1.v_tu SET x= 200;
+DELETE FROM mysqltest1.v_ts WHERE x= 200;
+ERROR 42000: DELETE command denied to user 'readonly'@'localhost' for table 'v_ts'
+DELETE FROM mysqltest1.v_ts;
+ERROR 42000: DELETE command denied to user 'readonly'@'localhost' for table 'v_ts'
+DELETE FROM mysqltest1.v_td WHERE x= 200;
+ERROR 42000: SELECT command denied to user 'readonly'@'localhost' for column 'x' in table
'v_td'
+DELETE FROM mysqltest1.v_tds WHERE x= 200;
+DELETE FROM mysqltest1.v_td;
+DROP VIEW mysqltest1.v_tds;
+DROP VIEW mysqltest1.v_td;
+DROP VIEW mysqltest1.v_tus;
+DROP VIEW mysqltest1.v_tu;
+DROP VIEW mysqltest1.v_ti;
+DROP VIEW mysqltest1.v_ts;
+DROP VIEW mysqltest1.v_t1;
+DROP TABLE mysqltest1.t1;
+DROP USER readonly@localhost;
+DROP DATABASE mysqltest1;
+CREATE TABLE t1 (a INT PRIMARY KEY);
+INSERT INTO t1 VALUES (1), (2), (3);
+CREATE DEFINER = 'no-such-user'@localhost VIEW v AS SELECT a from t1;
+Warnings:
+Note 1449 There is no 'no-such-user'@'localhost' registered
+SHOW CREATE VIEW v;
+View Create View
+v CREATE ALGORITHM=UNDEFINED DEFINER=`no-such-user`@`localhost` SQL SECURITY DEFINER VIEW
`v` AS select `t1`.`a` AS `a` from `t1`
+Warnings:
+Note 1449 There is no 'no-such-user'@'localhost' registered
+SELECT * FROM v;
+ERROR HY000: There is no 'no-such-user'@'localhost' registered
+DROP VIEW v;
+DROP TABLE t1;
+USE test;
--- 1.15/mysql-test/t/view_grant.test 2006-05-02 03:12:47 +03:00
+++ 1.16/mysql-test/t/view_grant.test 2006-05-30 14:24:24 +03:00
@@ -718,3 +718,98 @@
show create view v2;
drop view v1;
drop view v2;
+
+#
+# Bug#18681: View privileges are broken
+#
+CREATE DATABASE mysqltest1;
+CREATE USER readonly@localhost;
+CREATE TABLE mysqltest1.t1 (x INT);
+INSERT INTO mysqltest1.t1 VALUES (1), (2);
+CREATE SQL SECURITY INVOKER VIEW mysqltest1.v_t1 AS SELECT * FROM mysqltest1.t1;
+CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_ts AS SELECT * FROM mysqltest1.t1;
+CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_ti AS SELECT * FROM mysqltest1.t1;
+CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_tu AS SELECT * FROM mysqltest1.t1;
+CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_tus AS SELECT * FROM mysqltest1.t1;
+CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_td AS SELECT * FROM mysqltest1.t1;
+CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_tds AS SELECT * FROM mysqltest1.t1;
+GRANT SELECT, INSERT, UPDATE, DELETE ON mysqltest1.v_t1 TO readonly;
+GRANT SELECT ON mysqltest1.v_ts TO readonly;
+GRANT INSERT ON mysqltest1.v_ti TO readonly;
+GRANT UPDATE ON mysqltest1.v_tu TO readonly;
+GRANT UPDATE,SELECT ON mysqltest1.v_tus TO readonly;
+GRANT DELETE ON mysqltest1.v_td TO readonly;
+GRANT DELETE,SELECT ON mysqltest1.v_tds TO readonly;
+
+CONNECT (n1,localhost,readonly,,);
+CONNECTION n1;
+
+--error 1356
+SELECT * FROM mysqltest1.v_t1;
+--error 1356
+INSERT INTO mysqltest1.v_t1 VALUES(4);
+--error 1356
+DELETE FROM mysqltest1.v_t1 WHERE x = 1;
+--error 1356
+UPDATE mysqltest1.v_t1 SET x = 3 WHERE x = 2;
+--error 1356
+UPDATE mysqltest1.v_t1 SET x = 3;
+--error 1356
+DELETE FROM mysqltest1.v_t1;
+--error 1356
+SELECT 1 FROM mysqltest1.v_t1;
+--error 1142
+SELECT * FROM mysqltest1.t1;
+
+SELECT * FROM mysqltest1.v_ts;
+--error 1142
+SELECT * FROM mysqltest1.v_ts, mysqltest1.t1 WHERE mysqltest1.t1.x = mysqltest1.v_ts.x;
+--error 1142
+SELECT * FROM mysqltest1.v_ti;
+
+--error 1142
+INSERT INTO mysqltest1.v_ts VALUES (100);
+INSERT INTO mysqltest1.v_ti VALUES (100);
+
+--error 1142
+UPDATE mysqltest1.v_ts SET x= 200 WHERE x = 100;
+--error 1142
+UPDATE mysqltest1.v_ts SET x= 200;
+UPDATE mysqltest1.v_tu SET x= 200 WHERE x = 100;
+UPDATE mysqltest1.v_tus SET x= 200 WHERE x = 100;
+UPDATE mysqltest1.v_tu SET x= 200;
+
+--error 1142
+DELETE FROM mysqltest1.v_ts WHERE x= 200;
+--error 1142
+DELETE FROM mysqltest1.v_ts;
+--error 1143
+DELETE FROM mysqltest1.v_td WHERE x= 200;
+DELETE FROM mysqltest1.v_tds WHERE x= 200;
+DELETE FROM mysqltest1.v_td;
+
+CONNECTION default;
+DROP VIEW mysqltest1.v_tds;
+DROP VIEW mysqltest1.v_td;
+DROP VIEW mysqltest1.v_tus;
+DROP VIEW mysqltest1.v_tu;
+DROP VIEW mysqltest1.v_ti;
+DROP VIEW mysqltest1.v_ts;
+DROP VIEW mysqltest1.v_t1;
+DROP TABLE mysqltest1.t1;
+DROP USER readonly@localhost;
+DROP DATABASE mysqltest1;
+
+#
+# BUG#14875: Bad view DEFINER makes SHOW CREATE VIEW fail
+#
+CREATE TABLE t1 (a INT PRIMARY KEY);
+INSERT INTO t1 VALUES (1), (2), (3);
+CREATE DEFINER = 'no-such-user'@localhost VIEW v AS SELECT a from t1;
+--warning 1448
+SHOW CREATE VIEW v;
+--error 1449
+SELECT * FROM v;
+DROP VIEW v;
+DROP TABLE t1;
+USE test;
--- 1.33/server-tools/instance-manager/manager.cc 2006-05-22 13:22:55 +03:00
+++ 1.34/server-tools/instance-manager/manager.cc 2006-05-30 16:07:39 +03:00
@@ -198,28 +198,6 @@
if (create_pid_file(Options::Main::pid_file_name, manager_pid))
return; /* necessary logging has been already done. */
- sigset_t mask;
- set_signals(&mask);
-
- /* create the listener */
- {
- pthread_t listener_thd_id;
- pthread_attr_t listener_thd_attr;
- int rc;
-
- pthread_attr_init(&listener_thd_attr);
- pthread_attr_setdetachstate(&listener_thd_attr, PTHREAD_CREATE_DETACHED);
- rc= set_stacksize_n_create_thread(&listener_thd_id, &listener_thd_attr,
- listener, &listener_args);
- pthread_attr_destroy(&listener_thd_attr);
- if (rc)
- {
- log_error("manager(): set_stacksize_n_create_thread(listener) failed");
- goto err;
- }
-
- }
-
/* create guardian thread */
{
pthread_t guardian_thd_id;
@@ -265,6 +243,29 @@
"the wrong config file options. For instance, missing mysqld "
"binary. Aborting.");
return;
+ }
+ }
+
+ /* Initialize signals and alarm-infrastructure. */
+
+ sigset_t mask;
+ set_signals(&mask);
+
+ /* create the listener */
+ {
+ pthread_t listener_thd_id;
+ pthread_attr_t listener_thd_attr;
+ int rc;
+
+ pthread_attr_init(&listener_thd_attr);
+ pthread_attr_setdetachstate(&listener_thd_attr, PTHREAD_CREATE_DETACHED);
+ rc= set_stacksize_n_create_thread(&listener_thd_id, &listener_thd_attr,
+ listener, &listener_args);
+ pthread_attr_destroy(&listener_thd_attr);
+ if (rc)
+ {
+ log_error("manager(): set_stacksize_n_create_thread(listener) failed");
+ goto err;
}
}
--- 1.12.7.1/ndb/src/ndbapi/DictCache.cpp 2006-05-25 14:08:30 +03:00
+++ 1.27/storage/ndb/src/ndbapi/DictCache.cpp 2006-05-30 14:24:28 +03:00
@@ -27,6 +27,7 @@
Ndb_local_table_info *
Ndb_local_table_info::create(NdbTableImpl *table_impl, Uint32 sz)
{
+ assert(! is_ndb_blob_table(table_impl));
Uint32 tot_size= sizeof(Ndb_local_table_info) - sizeof(Uint64)
+ ((sz+7) & ~7); // round to Uint64
void *data= malloc(tot_size);
@@ -44,9 +45,9 @@
Ndb_local_table_info::Ndb_local_table_info(NdbTableImpl *table_impl)
{
+ assert(! is_ndb_blob_table(table_impl));
m_table_impl= table_impl;
- m_first_tuple_id = ~(Uint64)0;
- m_last_tuple_id = ~(Uint64)0;
+ m_tuple_id_range.reset();
}
Ndb_local_table_info::~Ndb_local_table_info()
@@ -63,19 +64,24 @@
Ndb_local_table_info *
LocalDictCache::get(const char * name){
+ ASSERT_NOT_MYSQLD;
+ assert(! is_ndb_blob_table(name));
const Uint32 len = strlen(name);
return m_tableHash.getData(name, len);
}
void
LocalDictCache::put(const char * name, Ndb_local_table_info * tab_info){
- const Uint32 id = tab_info->m_table_impl->m_tableId;
-
+ ASSERT_NOT_MYSQLD;
+ assert(! is_ndb_blob_table(name));
+ const Uint32 id = tab_info->m_table_impl->m_id;
m_tableHash.insertKey(name, strlen(name), id, tab_info);
}
void
LocalDictCache::drop(const char * name){
+ ASSERT_NOT_MYSQLD;
+ assert(! is_ndb_blob_table(name));
Ndb_local_table_info *info= m_tableHash.deleteKey(name, strlen(name));
DBUG_ASSERT(info != 0);
Ndb_local_table_info::destroy(info);
@@ -98,8 +104,15 @@
Vector<TableVersion> * vers = curr->theData;
const unsigned sz = vers->size();
for(unsigned i = 0; i<sz ; i++){
- if((* vers)[i].m_impl != 0)
+ TableVersion tv= (*vers)[i];
+ DBUG_PRINT(" ", ("vers[%d]: ver: %d, refCount: %d, status: %d",
+ i, tv.m_version, tv.m_refCount, tv.m_status));
+ if(tv.m_impl != 0)
+ {
+ DBUG_PRINT(" ", ("m_impl: internalname: %s",
+ tv.m_impl->m_internalName.c_str()));
delete (* vers)[i].m_impl;
+ }
}
delete curr->theData;
curr->theData= NULL;
@@ -122,8 +135,8 @@
const unsigned sz = vers->size();
for(unsigned i = 0; i<sz ; i++){
TableVersion tv= (*vers)[i];
- DBUG_PRINT(" ", ("vers[%d]: ver: %d, refCount: %d, status: %d",
- sz, tv.m_version, tv.m_refCount, tv.m_status));
+ DBUG_PRINT(" ", ("impl: %p vers[%d]: ver: %d, refCount: %d, status: %d",
+ tv.m_impl, i, tv.m_version, tv.m_refCount, tv.m_status));
if(tv.m_impl != 0)
{
DBUG_PRINT(" ", ("m_impl: internalname: %s",
@@ -145,6 +158,7 @@
{
DBUG_ENTER("GlobalDictCache::get");
DBUG_PRINT("enter", ("name: %s", name));
+ assert(! is_ndb_blob_table(name));
const Uint32 len = strlen(name);
Vector<TableVersion> * versions = 0;
@@ -161,12 +175,29 @@
TableVersion * ver = & versions->back();
switch(ver->m_status){
case OK:
+ if (ver->m_impl->m_status == NdbDictionary::Object::Invalid)
+ {
+ ver->m_status = DROPPED;
+ retreive = true; // Break loop
+ if (ver->m_refCount == 0)
+ {
+ delete ver->m_impl;
+ versions->erase(versions->size() - 1);
+ }
+ break;
+ }
ver->m_refCount++;
+ DBUG_PRINT("info", ("Table OK tab: %p version=%x.%x refCount=%u",
+ ver->m_impl,
+ ver->m_impl->m_version & 0xFFFFFF,
+ ver->m_impl->m_version >> 24,
+ ver->m_refCount));
DBUG_RETURN(ver->m_impl);
case DROPPED:
retreive = true; // Break loop
break;
case RETREIVING:
+ DBUG_PRINT("info", ("Wait for retrieving thread"));
NdbCondition_WaitTimeout(m_waitForTableCondition, m_mutex, waitTime);
continue;
}
@@ -181,6 +212,7 @@
tmp.m_status = RETREIVING;
tmp.m_refCount = 1; // The one retreiving it
versions->push_back(tmp);
+ DBUG_PRINT("info", ("No table found"));
DBUG_RETURN(0);
}
@@ -188,8 +220,12 @@
GlobalDictCache::put(const char * name, NdbTableImpl * tab)
{
DBUG_ENTER("GlobalDictCache::put");
- DBUG_PRINT("enter", ("name: %s, internal_name: %s",
- name, tab ? tab->m_internalName.c_str() : "tab NULL"));
+ DBUG_PRINT("enter", ("tab: %p name: %s, internal_name: %s version: %x.%x",
+ tab, name,
+ tab ? tab->m_internalName.c_str() : "tab NULL",
+ tab ? tab->m_version & 0xFFFFFF : 0,
+ tab ? tab->m_version >> 24 : 0));
+ assert(! is_ndb_blob_table(name));
const Uint32 len = strlen(name);
Vector<TableVersion> * vers = m_tableHash.getData(name, len);
@@ -221,12 +257,14 @@
vers->erase(sz - 1);
}
else if (ver.m_impl == 0) {
+ DBUG_PRINT("info", ("Table OK"));
ver.m_impl = tab;
ver.m_version = tab->m_version;
ver.m_status = OK;
}
else if (ver.m_impl == &f_invalid_table)
{
+ DBUG_PRINT("info", ("Table DROPPED invalid"));
ver.m_impl = tab;
ver.m_version = tab->m_version;
ver.m_status = DROPPED;
@@ -234,6 +272,7 @@
}
else if(ver.m_impl == &f_altered_table)
{
+ DBUG_PRINT("info", ("Table DROPPED altered"));
ver.m_impl = tab;
ver.m_version = tab->m_version;
ver.m_status = DROPPED;
@@ -247,62 +286,6 @@
DBUG_RETURN(tab);
}
-void
-GlobalDictCache::drop(NdbTableImpl * tab)
-{
- DBUG_ENTER("GlobalDictCache::drop");
- DBUG_PRINT("enter", ("internal_name: %s", tab->m_internalName.c_str()));
-
- unsigned i;
- const Uint32 len = strlen(tab->m_internalName.c_str());
- Vector<TableVersion> * vers =
- m_tableHash.getData(tab->m_internalName.c_str(), len);
- if(vers == 0){
- // Should always tried to retreive it first
- // and thus there should be a record
- abort();
- }
-
- const Uint32 sz = vers->size();
- if(sz == 0){
- // Should always tried to retreive it first
- // and thus there should be a record
- abort();
- }
-
- for(i = 0; i < sz; i++){
- TableVersion & ver = (* vers)[i];
- if(ver.m_impl == tab){
- if(ver.m_refCount == 0 || ver.m_status == RETREIVING ||
- ver.m_version != tab->m_version){
- DBUG_PRINT("info", ("Dropping with refCount=%d status=%d impl=%p",
- ver.m_refCount, ver.m_status, ver.m_impl));
- break;
- }
- DBUG_PRINT("info", ("Found table to drop, i: %d, name: %s",
- i, ver.m_impl->m_internalName.c_str()));
- ver.m_refCount--;
- ver.m_status = DROPPED;
- if(ver.m_refCount == 0){
- DBUG_PRINT("info", ("refCount is zero, deleting m_impl"))
- delete ver.m_impl;
- vers->erase(i);
- }
- DBUG_VOID_RETURN;
- }
- }
-
- for(i = 0; i<sz; i++){
- TableVersion & ver = (* vers)[i];
- DBUG_PRINT("info", ("%d: version: %d refCount: %d status: %d impl: %p",
- i, ver.m_version, ver.m_refCount,
- ver.m_status, ver.m_impl));
- }
-
- abort();
-}
-
-
unsigned
GlobalDictCache::get_size()
{
@@ -312,6 +295,10 @@
sz += curr->theData->size();
curr = m_tableHash.getNext(curr);
}
+ if (sz)
+ {
+ printCache();
+ }
return sz;
}
@@ -339,10 +326,12 @@
}
void
-GlobalDictCache::release(NdbTableImpl * tab)
+GlobalDictCache::release(NdbTableImpl * tab, int invalidate)
{
DBUG_ENTER("GlobalDictCache::release");
- DBUG_PRINT("enter", ("internal_name: %s", tab->m_internalName.c_str()));
+ DBUG_PRINT("enter", ("tab: %p internal_name: %s",
+ tab, tab->m_internalName.c_str()));
+ assert(! is_ndb_blob_table(tab));
unsigned i;
const Uint32 len = strlen(tab->m_internalName.c_str());
@@ -372,15 +361,26 @@
}
ver.m_refCount--;
+ if (ver.m_impl->m_status == NdbDictionary::Object::Invalid || invalidate)
+ {
+ ver.m_impl->m_status = NdbDictionary::Object::Invalid;
+ ver.m_status = DROPPED;
+ }
+ if (ver.m_refCount == 0 && ver.m_status == DROPPED)
+ {
+ DBUG_PRINT("info", ("refCount is zero, deleting m_impl"));
+ delete ver.m_impl;
+ vers->erase(i);
+ }
DBUG_VOID_RETURN;
}
}
for(i = 0; i<sz; i++){
TableVersion & ver = (* vers)[i];
- DBUG_PRINT("info", ("%d: version: %d refCount: %d status: %d impl: %p",
- i, ver.m_version, ver.m_refCount,
- ver.m_status, ver.m_impl));
+ ndbout_c("%d: version: %d refCount: %d status: %d impl: %p",
+ i, ver.m_version, ver.m_refCount,
+ ver.m_status, ver.m_impl);
}
abort();
@@ -392,39 +392,47 @@
Uint32 tableVersion,
bool altered)
{
+ DBUG_ENTER("GlobalDictCache::alter_table_rep");
+ assert(! is_ndb_blob_table(name));
const Uint32 len = strlen(name);
Vector<TableVersion> * vers =
m_tableHash.getData(name, len);
if(vers == 0)
{
- return;
+ DBUG_VOID_RETURN;
}
const Uint32 sz = vers->size();
if(sz == 0)
{
- return;
+ DBUG_VOID_RETURN;
}
for(Uint32 i = 0; i < sz; i++)
{
TableVersion & ver = (* vers)[i];
if(ver.m_version == tableVersion && ver.m_impl &&
- ver.m_impl->m_tableId == tableId)
+ ver.m_impl->m_id == tableId)
{
ver.m_status = DROPPED;
ver.m_impl->m_status = altered ?
NdbDictionary::Object::Altered : NdbDictionary::Object::Invalid;
- return;
+ if (ver.m_refCount == 0)
+ {
+ delete ver.m_impl;
+ vers->erase(i);
+ }
+ DBUG_VOID_RETURN;
}
if(i == sz - 1 && ver.m_status == RETREIVING)
{
ver.m_impl = altered ? &f_altered_table : &f_invalid_table;
- return;
+ DBUG_VOID_RETURN;
}
}
+ DBUG_VOID_RETURN;
}
template class Vector<GlobalDictCache::TableVersion>;
--- 1.6.8.1/ndb/src/ndbapi/DictCache.hpp 2006-05-25 14:08:30 +03:00
+++ 1.16/storage/ndb/src/ndbapi/DictCache.hpp 2006-05-30 14:24:28 +03:00
@@ -35,8 +35,7 @@
NdbTableImpl *m_table_impl;
// range of cached tuple ids per thread
- Uint64 m_first_tuple_id;
- Uint64 m_last_tuple_id;
+ Ndb::TupleIdRange m_tuple_id_range;
Uint64 m_local_data[1]; // Must be last member. Used to access extra space.
private:
@@ -68,11 +67,11 @@
GlobalDictCache();
~GlobalDictCache();
+ NdbTableImpl * get(NdbTableImpl *tab);
NdbTableImpl * get(const char * name);
NdbTableImpl* put(const char * name, NdbTableImpl *);
- void drop(NdbTableImpl *);
- void release(NdbTableImpl *);
+ void release(NdbTableImpl *, int invalidate = 0);
void alter_table_rep(const char * name,
Uint32 tableId, Uint32 tableVersion, bool altered);
--- 1.16/mysql-test/r/lock_multi.result 2006-03-29 14:27:30 +03:00
+++ 1.17/mysql-test/r/lock_multi.result 2006-05-30 14:24:22 +03:00
@@ -50,3 +50,19 @@
a int(11) YES NULL
unlock tables;
drop table t1;
+use mysql;
+LOCK TABLES columns_priv WRITE, db WRITE, host WRITE, user WRITE;
+FLUSH TABLES;
+use mysql;
+ SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1;
+OPTIMIZE TABLES columns_priv, db, host, user;
+Table Op Msg_type Msg_text
+mysql.columns_priv optimize status OK
+mysql.db optimize status OK
+mysql.host optimize status OK
+mysql.user optimize status OK
+UNLOCK TABLES;
+Select_priv
+N
+use test;
+use test;
--- 1.14/mysql-test/t/lock_multi.test 2006-03-29 14:27:30 +03:00
+++ 1.15/mysql-test/t/lock_multi.test 2006-05-30 14:24:23 +03:00
@@ -126,3 +126,35 @@
connection locker;
unlock tables;
drop table t1;
+
+#
+# Bug#16986 - Deadlock condition with MyISAM tables
+#
+connection locker;
+use mysql;
+LOCK TABLES columns_priv WRITE, db WRITE, host WRITE, user WRITE;
+FLUSH TABLES;
+--sleep 1
+#
+connection reader;
+use mysql;
+#NOTE: This must be a multi-table select, otherwise the deadlock will not occur
+send SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1;
+--sleep 1
+#
+connection locker;
+# Make test case independent from earlier grants.
+--replace_result "Table is already up to date" "OK"
+OPTIMIZE TABLES columns_priv, db, host, user;
+UNLOCK TABLES;
+#
+connection reader;
+reap;
+use test;
+#
+connection locker;
+use test;
+#
+connection default;
+
+# End of 5.0 tests
--- 1.51/mysql-test/r/grant.result 2006-03-07 21:00:40 +02:00
+++ 1.52/mysql-test/r/grant.result 2006-05-30 14:24:22 +03:00
@@ -357,12 +357,12 @@
Grants for grant_user@localhost
GRANT USAGE ON *.* TO 'grant_user'@'localhost'
GRANT INSERT (a, d, c, b) ON `test`.`t1` TO 'grant_user'@'localhost'
-select Host,Db,User,Table_name,Column_name,Column_priv from mysql.columns_priv;
+select Host,Db,User,Table_name,Column_name,Column_priv from mysql.columns_priv order by
Column_name;
Host Db User Table_name Column_name Column_priv
-localhost test grant_user t1 b Insert
-localhost test grant_user t1 d Insert
localhost test grant_user t1 a Insert
+localhost test grant_user t1 b Insert
localhost test grant_user t1 c Insert
+localhost test grant_user t1 d Insert
revoke ALL PRIVILEGES on t1 from grant_user@localhost;
show grants for grant_user@localhost;
Grants for grant_user@localhost
@@ -381,13 +381,27 @@
grant select (b) on mysqltest_1.t2 to mysqltest_3@localhost;
grant select (c) on mysqltest_2.t1 to mysqltest_3@localhost;
grant update (d) on mysqltest_2.t2 to mysqltest_3@localhost;
-show grants for mysqltest_3@localhost;
-Grants for mysqltest_3@localhost
-GRANT USAGE ON *.* TO 'mysqltest_3'@'localhost'
-GRANT SELECT (b) ON `mysqltest_1`.`t2` TO 'mysqltest_3'@'localhost'
-GRANT UPDATE (a) ON `mysqltest_1`.`t1` TO 'mysqltest_3'@'localhost'
-GRANT UPDATE (d) ON `mysqltest_2`.`t2` TO 'mysqltest_3'@'localhost'
-GRANT SELECT (c) ON `mysqltest_2`.`t1` TO 'mysqltest_3'@'localhost'
+SELECT * FROM INFORMATION_SCHEMA.COLUMN_PRIVILEGES
+WHERE GRANTEE = '''mysqltest_3''@''localhost'''
+ORDER BY TABLE_NAME,COLUMN_NAME,PRIVILEGE_TYPE;
+GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME PRIVILEGE_TYPE IS_GRANTABLE
+'mysqltest_3'@'localhost' NULL mysqltest_1 t1 a UPDATE NO
+'mysqltest_3'@'localhost' NULL mysqltest_2 t1 c SELECT NO
+'mysqltest_3'@'localhost' NULL mysqltest_1 t2 b SELECT NO
+'mysqltest_3'@'localhost' NULL mysqltest_2 t2 d UPDATE NO
+SELECT * FROM INFORMATION_SCHEMA.TABLE_PRIVILEGES
+WHERE GRANTEE = '''mysqltest_3''@''localhost'''
+ORDER BY TABLE_NAME,PRIVILEGE_TYPE;
+GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PRIVILEGE_TYPE IS_GRANTABLE
+SELECT * from INFORMATION_SCHEMA.SCHEMA_PRIVILEGES
+WHERE GRANTEE = '''mysqltest_3''@''localhost'''
+ORDER BY TABLE_SCHEMA,PRIVILEGE_TYPE;
+GRANTEE TABLE_CATALOG TABLE_SCHEMA PRIVILEGE_TYPE IS_GRANTABLE
+SELECT * from INFORMATION_SCHEMA.USER_PRIVILEGES
+WHERE GRANTEE = '''mysqltest_3''@''localhost'''
+ ORDER BY TABLE_CATALOG,PRIVILEGE_TYPE;
+GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_GRANTABLE
+'mysqltest_3'@'localhost' NULL USAGE NO
update mysqltest_1.t1, mysqltest_1.t2 set q=10 where b=1;
ERROR 42000: UPDATE command denied to user 'mysqltest_3'@'localhost' for column 'q' in
table 't1'
update mysqltest_1.t2, mysqltest_2.t2 set d=20 where d=1;
--- 1.206/mysql-test/r/sp.result 2006-05-18 14:35:11 +03:00
+++ 1.207/mysql-test/r/sp.result 2006-05-30 14:24:22 +03:00
@@ -4970,4 +4970,34 @@
DROP FUNCTION bug18589_f1|
DROP PROCEDURE bug18589_p1|
DROP PROCEDURE bug18589_p2|
+DROP FUNCTION IF EXISTS bug18037_f1|
+DROP PROCEDURE IF EXISTS bug18037_p1|
+DROP PROCEDURE IF EXISTS bug18037_p2|
+CREATE FUNCTION bug18037_f1() RETURNS INT
+BEGIN
+RETURN @@server_id;
+END|
+CREATE PROCEDURE bug18037_p1()
+BEGIN
+DECLARE v INT DEFAULT @@server_id;
+END|
+CREATE PROCEDURE bug18037_p2()
+BEGIN
+CASE @@server_id
+WHEN -1 THEN
+SELECT 0;
+ELSE
+SELECT 1;
+END CASE;
+END|
+SELECT bug18037_f1()|
+bug18037_f1()
+1
+CALL bug18037_p1()|
+CALL bug18037_p2()|
+1
+1
+DROP FUNCTION bug18037_f1|
+DROP PROCEDURE bug18037_p1|
+DROP PROCEDURE bug18037_p2|
drop table t1,t2;
--- 1.189/mysql-test/t/sp.test 2006-05-18 11:53:09 +03:00
+++ 1.190/mysql-test/t/sp.test 2006-05-30 14:24:24 +03:00
@@ -5850,6 +5850,52 @@
#
+# BUG#18037: Server crash when returning system variable in stored procedures
+# BUG#19633: Stack corruption in fix_fields()/THD::rollback_item_tree_changes()
+#
+
+# Prepare.
+
+--disable_warnings
+DROP FUNCTION IF EXISTS bug18037_f1|
+DROP PROCEDURE IF EXISTS bug18037_p1|
+DROP PROCEDURE IF EXISTS bug18037_p2|
+--enable_warnings
+
+# Test case.
+
+CREATE FUNCTION bug18037_f1() RETURNS INT
+BEGIN
+ RETURN @@server_id;
+END|
+
+CREATE PROCEDURE bug18037_p1()
+BEGIN
+ DECLARE v INT DEFAULT @@server_id;
+END|
+
+CREATE PROCEDURE bug18037_p2()
+BEGIN
+ CASE @@server_id
+ WHEN -1 THEN
+ SELECT 0;
+ ELSE
+ SELECT 1;
+ END CASE;
+END|
+
+SELECT bug18037_f1()|
+CALL bug18037_p1()|
+CALL bug18037_p2()|
+
+# Cleanup.
+
+DROP FUNCTION bug18037_f1|
+DROP PROCEDURE bug18037_p1|
+DROP PROCEDURE bug18037_p2|
+
+
+#
# BUG#NNNN: New bug synopsis
#
#--disable_warnings
--- 1.22/server-tools/instance-manager/guardian.cc 2006-05-18 17:57:43 +03:00
+++ 1.23/server-tools/instance-manager/guardian.cc 2006-05-30 14:24:24 +03:00
@@ -175,9 +175,12 @@
case JUST_CRASHED:
if (current_time - current_node->crash_moment <= 2)
{
- instance->start();
- log_info("guardian: starting instance %s",
- instance->options.instance_name);
+ if (instance->is_crashed())
+ {
+ instance->start();
+ log_info("guardian: starting instance %s",
+ instance->options.instance_name);
+ }
}
else
current_node->state= CRASHED;
@@ -188,11 +191,14 @@
{
if ((current_node->restart_counter < restart_retry))
{
- instance->start();
- current_node->last_checked= current_time;
- current_node->restart_counter++;
- log_info("guardian: restarting instance %s",
- instance->options.instance_name);
+ if (instance->is_crashed())
+ {
+ instance->start();
+ current_node->last_checked= current_time;
+ current_node->restart_counter++;
+ log_info("guardian: restarting instance %s",
+ instance->options.instance_name);
+ }
}
else
{
--- 1.106/mysql-test/r/mysqldump.result 2006-05-11 04:16:39 +03:00
+++ 1.107/mysql-test/r/mysqldump.result 2006-05-30 16:07:39 +03:00
@@ -1,4 +1,4 @@
-DROP TABLE IF EXISTS t1, `"t"1`, t1aa, t2, t2aa;
+DROP TABLE IF EXISTS t1, `"t"1`, t1aa, t2, t2aa, t3;
drop database if exists mysqldump_test_db;
drop database if exists db1;
drop database if exists db2;
@@ -1509,6 +1509,7 @@
12 meg
drop table t1, t2;
drop database db1;
+--fields-optionally-enclosed-by="
CREATE DATABASE mysqldump_test_db;
USE mysqldump_test_db;
CREATE TABLE t1 ( a INT );
@@ -1738,6 +1739,43 @@
KEY `t1_name` (`t1_name`)
) ENGINE=MyISAM AUTO_INCREMENT=1003 DEFAULT CHARSET=latin1
drop table `t1`;
+create table t1(a int);
+create table t2(a int);
+create table t3(a int);
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+DROP TABLE IF EXISTS `t3`;
+CREATE TABLE `t3` (
+ `a` int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+DROP TABLE IF EXISTS `t1`;
+CREATE TABLE `t1` (
+ `a` int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+DROP TABLE IF EXISTS `t2`;
+CREATE TABLE `t2` (
+ `a` int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+drop table t1, t2, t3;
End of 4.1 tests
create table t1 (a binary(1), b blob);
insert into t1 values ('','');
--- 1.99/mysql-test/t/mysqldump.test 2006-05-12 13:32:00 +03:00
+++ 1.100/mysql-test/t/mysqldump.test 2006-05-30 16:07:39 +03:00
@@ -2,7 +2,7 @@
--source include/not_embedded.inc
--disable_warnings
-DROP TABLE IF EXISTS t1, `"t"1`, t1aa, t2, t2aa;
+DROP TABLE IF EXISTS t1, `"t"1`, t1aa, t2, t2aa, t3;
drop database if exists mysqldump_test_db;
drop database if exists db1;
drop database if exists db2;
@@ -607,6 +607,13 @@
drop database db1;
#
+# BUG#15328 Segmentation fault occured if my.cnf is invalid for escape sequence
+#
+
+--exec $MYSQL_MY_PRINT_DEFAULTS
--defaults-extra-file=$MYSQL_TEST_DIR/std_data/bug15328.cnf mysqldump
+
+
+#
# Bug #9558 mysqldump --no-data db t1 t2 format still dumps data
#
@@ -740,6 +747,17 @@
show create table `t1`;
drop table `t1`;
+
+#
+# Bug #18536: wrong table order
+#
+
+create table t1(a int);
+create table t2(a int);
+create table t3(a int);
+--error 6
+--exec $MYSQL_DUMP --skip-comments --force --no-data test t3 t1 non_existing t2
+drop table t1, t2, t3;
--echo End of 4.1 tests
# Bug #13318: Bad result with empty field and --hex-blob
| Thread |
|---|
| • bk commit into 5.1 tree (jani:1.2176) | jani | 30 May |