summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <sasha@asksasha.com>2005-09-17 18:46:54 -0600
committerunknown <sasha@asksasha.com>2005-09-17 18:46:54 -0600
commitce7e95d41d7c8aa2fef96728d8b2036ff22b5e5c (patch)
tree0cfcd8670242b0eb46bc7ea586da9e4afcf86665 /sql
parentd6afdcb77c3e7959705259f33ed1ab2b73ec6ad7 (diff)
parentaba5027e81d07cefa5ced082556957cb71d13a6a (diff)
downloadmariadb-git-ce7e95d41d7c8aa2fef96728d8b2036ff22b5e5c.tar.gz
Merge spachev@bk-internal.mysql.com:/home/bk/mysql-4.1
into asksasha.com:/reiser-data/mysql-dev/mysql-4.1-bug11139 mysql-test/r/rpl_multi_delete2.result: Auto merged mysql-test/t/rpl_multi_delete2-slave.opt: Auto merged mysql-test/t/rpl_multi_delete2.test: Auto merged
Diffstat (limited to 'sql')
-rw-r--r--sql/mysql_priv.h2
-rw-r--r--sql/slave.cc9
-rw-r--r--sql/sql_parse.cc50
-rw-r--r--sql/sql_yacc.yy10
4 files changed, 46 insertions, 25 deletions
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 0d889aaf0b1..32c5861028e 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -59,6 +59,7 @@ void kill_one_thread(THD *thd, ulong id);
bool net_request_file(NET* net, const char* fname);
char* query_table_status(THD *thd,const char *db,const char *table_name);
+
#define x_free(A) { my_free((gptr) (A),MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR)); }
#define safeFree(x) { if(x) { my_free((gptr) x,MYF(0)); x = NULL; } }
#define PREV_BITS(type,A) ((type) (((type) 1 << (A)) -1))
@@ -464,6 +465,7 @@ void mysql_reset_thd_for_next_command(THD *thd);
bool mysql_new_select(LEX *lex, bool move_down);
void create_select_for_variable(const char *var_name);
void mysql_init_multi_delete(LEX *lex);
+void fix_multi_delete_lex(LEX* lex);
void init_max_user_conn(void);
void init_update_queries(void);
void free_max_user_conn(void);
diff --git a/sql/slave.cc b/sql/slave.cc
index 9ff7a432b89..1be3e3b4a17 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -746,14 +746,7 @@ static TABLE_RULE_ENT* find_wild(DYNAMIC_ARRAY *a, const char* key, int len)
rules (see code below). For that reason, users should not set conflicting
rules because they may get unpredicted results (precedence order is
explained in the manual).
- If no table of the list is marked "updating" (so far this can only happen
- if the statement is a multi-delete (SQLCOM_DELETE_MULTI) and the "tables"
- is the tables in the FROM): then we always return 0, because there is no
- reason we play this statement on this slave if it updates nothing. In the
- case of SQLCOM_DELETE_MULTI, there will be a second call to tables_ok(),
- with tables having "updating==TRUE" (those after the DELETE), so this
- second call will make the decision (because
- all_tables_not_ok() = !tables_ok(1st_list) && !tables_ok(2nd_list)).
+
RETURN VALUES
0 should not be logged/replicated
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 131fe3d691d..a2df59e56c7 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -59,6 +59,9 @@ static void remove_escape(char *name);
static void refresh_status(void);
static bool append_file_to_dir(THD *thd, const char **filename_ptr,
const char *table_name);
+
+static TABLE_LIST* get_table_by_alias(TABLE_LIST* tl, const char* db,
+ const char* alias);
const char *any_db="*any*"; // Special symbol for check_access
@@ -125,10 +128,7 @@ static bool end_active_trans(THD *thd)
*/
inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables)
{
- return (table_rules_on && tables && !tables_ok(thd,tables) &&
- ((thd->lex->sql_command != SQLCOM_DELETE_MULTI) ||
- !tables_ok(thd,
- (TABLE_LIST *)thd->lex->auxilliary_table_list.first)));
+ return (table_rules_on && tables && !tables_ok(thd,tables));
}
#endif
@@ -4245,6 +4245,40 @@ void create_select_for_variable(const char *var_name)
DBUG_VOID_RETURN;
}
+static TABLE_LIST* get_table_by_alias(TABLE_LIST* tl, const char* db,
+ const char* alias)
+{
+ for (;tl;tl= tl->next)
+ {
+ if (!strcmp(db,tl->db) &&
+ tl->alias && !my_strcasecmp(table_alias_charset,tl->alias,alias))
+ return tl;
+ }
+
+ return 0;
+}
+
+/* Sets up lex->auxilliary_table_list */
+void fix_multi_delete_lex(LEX* lex)
+{
+ TABLE_LIST *tl;
+ TABLE_LIST *good_list= (TABLE_LIST*)lex->select_lex.table_list.first;
+
+ for (tl= (TABLE_LIST*)lex->auxilliary_table_list.first; tl; tl= tl->next)
+ {
+ TABLE_LIST* good_table= get_table_by_alias(good_list,tl->db,tl->alias);
+ if (good_table && !good_table->derived)
+ {
+ /*
+ real_name points to a member of Table_ident which is
+ allocated via thd->strmake() from THD memroot
+ */
+ tl->real_name= good_table->real_name;
+ tl->real_name_length= good_table->real_name_length;
+ good_table->updating= tl->updating;
+ }
+ }
+}
void mysql_init_multi_delete(LEX *lex)
{
@@ -5567,13 +5601,7 @@ int multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count)
(*table_count)++;
/* All tables in aux_tables must be found in FROM PART */
TABLE_LIST *walk;
- for (walk= delete_tables; walk; walk= walk->next)
- {
- if (!my_strcasecmp(table_alias_charset,
- target_tbl->alias, walk->alias) &&
- !strcmp(walk->db, target_tbl->db))
- break;
- }
+ walk= get_table_by_alias(delete_tables,target_tbl->db,target_tbl->alias);
if (!walk)
{
my_error(ER_UNKNOWN_TABLE, MYF(0), target_tbl->real_name,
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 6283cad7cc8..e29aaac8f94 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -4295,12 +4295,10 @@ single_multi:
}
where_clause opt_order_clause
delete_limit_clause {}
- | table_wild_list
- { mysql_init_multi_delete(Lex); }
- FROM join_table_list where_clause
- | FROM table_wild_list
- { mysql_init_multi_delete(Lex); }
- USING join_table_list where_clause
+ | table_wild_list {mysql_init_multi_delete(Lex);}
+ FROM join_table_list {fix_multi_delete_lex(Lex);} where_clause
+ | FROM table_wild_list { mysql_init_multi_delete(Lex);}
+ USING join_table_list {fix_multi_delete_lex(Lex);} where_clause
{}
;