Commit 7d7a248d authored by monty@mashka.mysql.fi's avatar monty@mashka.mysql.fi

Merge work:/home/bk/mysql-4.1 into mashka.mysql.fi:/home/my/mysql-4.1

parents 474d0136 acf89934
...@@ -597,3 +597,4 @@ vio/test-sslclient ...@@ -597,3 +597,4 @@ vio/test-sslclient
vio/test-sslserver vio/test-sslserver
vio/viotest-ssl vio/viotest-ssl
scripts/fill_help_tables.sql scripts/fill_help_tables.sql
scripts/fill_help_tables
...@@ -991,7 +991,8 @@ int do_sync_with_master2(const char* p) ...@@ -991,7 +991,8 @@ int do_sync_with_master2(const char* p)
mysql_errno(mysql), mysql_error(mysql)); mysql_errno(mysql), mysql_error(mysql));
if (!(last_result = res = mysql_store_result(mysql))) if (!(last_result = res = mysql_store_result(mysql)))
die("line %u: mysql_store_result() returned NULL", start_lineno); die("line %u: mysql_store_result() returned NULL for '%s'", start_lineno,
query_buf);
if (!(row = mysql_fetch_row(res))) if (!(row = mysql_fetch_row(res)))
die("line %u: empty result in %s", start_lineno, query_buf); die("line %u: empty result in %s", start_lineno, query_buf);
if (!row[0]) if (!row[0])
...@@ -1021,17 +1022,19 @@ int do_save_master_pos() ...@@ -1021,17 +1022,19 @@ int do_save_master_pos()
MYSQL_RES* res; MYSQL_RES* res;
MYSQL_ROW row; MYSQL_ROW row;
MYSQL* mysql = &cur_con->mysql; MYSQL* mysql = &cur_con->mysql;
const char *query;
int rpl_parse; int rpl_parse;
rpl_parse = mysql_rpl_parse_enabled(mysql); rpl_parse = mysql_rpl_parse_enabled(mysql);
mysql_disable_rpl_parse(mysql); mysql_disable_rpl_parse(mysql);
if (mysql_query(mysql, "show master status")) if (mysql_query(mysql, query= "show master status"))
die("At line %u: failed in show master status: %d: %s", start_lineno, die("At line %u: failed in show master status: %d: %s", start_lineno,
mysql_errno(mysql), mysql_error(mysql)); mysql_errno(mysql), mysql_error(mysql));
if (!(last_result =res = mysql_store_result(mysql))) if (!(last_result =res = mysql_store_result(mysql)))
die("line %u: mysql_store_result() retuned NULL", start_lineno); die("line %u: mysql_store_result() retuned NULL for '%s'", start_lineno,
query);
if (!(row = mysql_fetch_row(res))) if (!(row = mysql_fetch_row(res)))
die("line %u: empty result in show master status", start_lineno); die("line %u: empty result in show master status", start_lineno);
strnmov(master_pos.file, row[0], sizeof(master_pos.file)-1); strnmov(master_pos.file, row[0], sizeof(master_pos.file)-1);
......
This diff is collapsed.
...@@ -373,13 +373,22 @@ bool Protocol::send_fields(List<Item> *list, uint flag) ...@@ -373,13 +373,22 @@ bool Protocol::send_fields(List<Item> *list, uint flag)
Send_field server_field; Send_field server_field;
item->make_field(&server_field); item->make_field(&server_field);
client_field->db= strdup_root(alloc, server_field.db_name);
client_field->table= strdup_root(alloc, server_field.table_name); client_field->table= strdup_root(alloc, server_field.table_name);
client_field->name= strdup_root(alloc,server_field.col_name); client_field->name= strdup_root(alloc, server_field.col_name);
client_field->org_table= strdup_root(alloc, server_field.org_table_name);
client_field->org_name= strdup_root(alloc, server_field.org_col_name);
client_field->length= server_field.length; client_field->length= server_field.length;
client_field->type= server_field.type; client_field->type= server_field.type;
client_field->flags= server_field.flags; client_field->flags= server_field.flags;
client_field->decimals= server_field.decimals; client_field->decimals= server_field.decimals;
client_field->db_length= strlen(client_field->db);
client_field->table_length= strlen(client_field->table);
client_field->name_length= strlen(client_field->name);
client_field->org_name_length= strlen(client_field->org_name);
client_field->org_table_length= strlen(client_field->org_table);
client_field->charsetnr= server_field.charsetnr;
if (INTERNAL_NUM_FIELD(client_field)) if (INTERNAL_NUM_FIELD(client_field))
client_field->flags|= NUM_FLAG; client_field->flags|= NUM_FLAG;
......
...@@ -4,9 +4,6 @@ reset master; ...@@ -4,9 +4,6 @@ reset master;
reset slave; reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave; start slave;
stop slave;
reset master;
drop table if exists t1;
create table t1(n char(30)); create table t1(n char(30));
set @i1:=12345678901234, @i2:=-12345678901234, @i3:=0, @i4:=-1; set @i1:=12345678901234, @i2:=-12345678901234, @i3:=0, @i4:=-1;
set @s1:='This is a test', @r1:=12.5, @r2:=-12.5; set @s1:='This is a test', @r1:=12.5, @r2:=-12.5;
...@@ -23,7 +20,6 @@ set @q:='abc'; ...@@ -23,7 +20,6 @@ set @q:='abc';
insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2')); insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2'));
set @a:=5; set @a:=5;
insert into t1 values (@a),(@a); insert into t1 values (@a),(@a);
start slave;
select * from t1; select * from t1;
n n
12345678901234 12345678901234
...@@ -59,20 +55,20 @@ slave-bin.000001 396 User var 2 396 @r1=12.5 ...@@ -59,20 +55,20 @@ slave-bin.000001 396 User var 2 396 @r1=12.5
slave-bin.000001 439 User var 2 439 @r2=-12.5 slave-bin.000001 439 User var 2 439 @r2=-12.5
slave-bin.000001 482 Query 1 482 use `test`; insert into t1 values (@r1), (@r2) slave-bin.000001 482 Query 1 482 use `test`; insert into t1 values (@r1), (@r2)
slave-bin.000001 551 User var 2 551 @s1='This is a test' slave-bin.000001 551 User var 2 551 @s1='This is a test'
slave-bin.000001 601 User var 2 601 @s2='' slave-bin.000001 600 User var 2 600 @s2=''
slave-bin.000001 637 User var 2 637 @s3='abc'def' slave-bin.000001 635 User var 2 635 @s3='abc'def'
slave-bin.000001 680 User var 2 680 @s4='abc\def' slave-bin.000001 677 User var 2 677 @s4='abc\def'
slave-bin.000001 723 User var 2 723 @s5='abc'def' slave-bin.000001 719 User var 2 719 @s5='abc'def'
slave-bin.000001 766 Query 1 766 use `test`; insert into t1 values (@s1), (@s2), (@s3), (@s4), (@s5) slave-bin.000001 761 Query 1 761 use `test`; insert into t1 values (@s1), (@s2), (@s3), (@s4), (@s5)
slave-bin.000001 856 User var 2 856 @n1=NULL slave-bin.000001 851 User var 2 851 @n1=NULL
slave-bin.000001 882 Query 1 882 use `test`; insert into t1 values (@n1) slave-bin.000001 877 Query 1 877 use `test`; insert into t1 values (@n1)
slave-bin.000001 944 Query 1 944 use `test`; insert into t1 values (@n2) slave-bin.000001 939 Query 1 939 use `test`; insert into t1 values (@n2)
slave-bin.000001 1006 Query 1 1006 use `test`; insert into t1 values (@a:=0), (@a:=@a+1), (@a:=@a+1) slave-bin.000001 1001 Query 1 1001 use `test`; insert into t1 values (@a:=0), (@a:=@a+1), (@a:=@a+1)
slave-bin.000001 1094 User var 2 1094 @a='2' slave-bin.000001 1089 User var 2 1089 @a='2'
slave-bin.000001 1130 Query 1 1130 use `test`; insert into t1 values (@a+(@b:=@a+1)) slave-bin.000001 1124 Query 1 1124 use `test`; insert into t1 values (@a+(@b:=@a+1))
slave-bin.000001 1202 User var 2 1202 @q='abc' slave-bin.000001 1196 User var 2 1196 @q='abc'
slave-bin.000001 1240 Query 1 1240 use `test`; insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2')) slave-bin.000001 1233 Query 1 1233 use `test`; insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2'))
slave-bin.000001 1344 User var 2 1344 @a=5 slave-bin.000001 1337 User var 2 1337 @a=5
slave-bin.000001 1386 Query 1 1386 use `test`; insert into t1 values (@a),(@a) slave-bin.000001 1379 Query 1 1379 use `test`; insert into t1 values (@a),(@a)
drop table t1; drop table t1;
stop slave; stop slave;
...@@ -130,6 +130,10 @@ select d from t1 having d like "%HELLO%"; ...@@ -130,6 +130,10 @@ select d from t1 having d like "%HELLO%";
d d
HELLO HELLO
HELLO MY HELLO MY
select d from t1 having d like "%HE%LLO%";
d
HELLO
HELLO MY
select t from t1 order by t; select t from t1 order by t;
t t
NULL NULL
......
#
# Test of replicating user variables
#
source include/master-slave.inc; source include/master-slave.inc;
connection master;
save_master_pos;
connection slave;
sync_with_master;
stop slave;
reset master;
connection master;
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1(n char(30)); create table t1(n char(30));
set @i1:=12345678901234, @i2:=-12345678901234, @i3:=0, @i4:=-1; set @i1:=12345678901234, @i2:=-12345678901234, @i3:=0, @i4:=-1;
set @s1:='This is a test', @r1:=12.5, @r2:=-12.5; set @s1:='This is a test', @r1:=12.5, @r2:=-12.5;
...@@ -27,7 +21,6 @@ set @a:=5; ...@@ -27,7 +21,6 @@ set @a:=5;
insert into t1 values (@a),(@a); insert into t1 values (@a),(@a);
save_master_pos; save_master_pos;
connection slave; connection slave;
start slave;
sync_with_master; sync_with_master;
select * from t1; select * from t1;
show binlog events from 141; show binlog events from 141;
......
...@@ -87,6 +87,7 @@ select b from t1 where b like "%HELLO%"; ...@@ -87,6 +87,7 @@ select b from t1 where b like "%HELLO%";
select d from t1 where d like "%HELLO%"; select d from t1 where d like "%HELLO%";
select c from t1 having c like "%HELLO%"; select c from t1 having c like "%HELLO%";
select d from t1 having d like "%HELLO%"; select d from t1 having d like "%HELLO%";
select d from t1 having d like "%HE%LLO%";
select t from t1 order by t; select t from t1 order by t;
select c from t1 order by c; select c from t1 order by c;
select b from t1 order by b; select b from t1 order by b;
......
...@@ -1203,18 +1203,22 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) ...@@ -1203,18 +1203,22 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
max_length= (*ref)->max_length; max_length= (*ref)->max_length;
maybe_null= (*ref)->maybe_null; maybe_null= (*ref)->maybe_null;
decimals= (*ref)->decimals; decimals= (*ref)->decimals;
set_charset((*ref)->charset());
fixed= 1; fixed= 1;
if (ref && (*ref)->check_cols(1)) if (ref && (*ref)->check_cols(1))
return 1; return 1;
return 0; return 0;
} }
bool Item_default_value::eq(const Item *item, bool binary_cmp) const bool Item_default_value::eq(const Item *item, bool binary_cmp) const
{ {
return item->type() == DEFAULT_VALUE_ITEM && return item->type() == DEFAULT_VALUE_ITEM &&
((Item_default_value *)item)->arg->eq(arg, binary_cmp); ((Item_default_value *)item)->arg->eq(arg, binary_cmp);
} }
bool Item_default_value::fix_fields(THD *thd, struct st_table_list *table_list, Item **items) bool Item_default_value::fix_fields(THD *thd, struct st_table_list *table_list, Item **items)
{ {
if (!arg) if (!arg)
......
...@@ -1129,11 +1129,16 @@ void in_string::set(uint pos,Item *item) ...@@ -1129,11 +1129,16 @@ void in_string::set(uint pos,Item *item)
String *res=item->val_str(str); String *res=item->val_str(str);
if (res && res != str) if (res && res != str)
*str= *res; *str= *res;
// BAR TODO: I'm not sure this is absolutely correct
if (!str->charset()) if (!str->charset())
str->set_charset(default_charset_info); {
CHARSET_INFO *cs;
if (!(cs= item->charset()))
cs= default_charset_info; // Should never happen for STR items
str->set_charset(cs);
}
} }
byte *in_string::get_value(Item *item) byte *in_string::get_value(Item *item)
{ {
return (byte*) item->val_str(&tmp); return (byte*) item->val_str(&tmp);
...@@ -1692,6 +1697,7 @@ longlong Item_func_isnull::val_int() ...@@ -1692,6 +1697,7 @@ longlong Item_func_isnull::val_int()
return args[0]->is_null() ? 1: 0; return args[0]->is_null() ? 1: 0;
} }
longlong Item_func_isnotnull::val_int() longlong Item_func_isnotnull::val_int()
{ {
return args[0]->is_null() ? 0 : 1; return args[0]->is_null() ? 0 : 1;
...@@ -1713,9 +1719,6 @@ longlong Item_func_like::val_int() ...@@ -1713,9 +1719,6 @@ longlong Item_func_like::val_int()
return 0; return 0;
} }
null_value=0; null_value=0;
if ((res->charset()->state & MY_CS_BINSORT) ||
(res2->charset()->state & MY_CS_BINSORT))
set_charset(&my_charset_bin);
if (canDoTurboBM) if (canDoTurboBM)
return turboBM_matches(res->ptr(), res->length()) ? 1 : 0; return turboBM_matches(res->ptr(), res->length()) ? 1 : 0;
return my_wildcmp(charset(), return my_wildcmp(charset(),
...@@ -1748,10 +1751,19 @@ bool Item_func_like::fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref) ...@@ -1748,10 +1751,19 @@ bool Item_func_like::fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref)
return 1; return 1;
/* /*
TODO--we could do it for non-const, but we'd have to Comparision is by default done according to character set of LIKE
recompute the tables for each row--probably not worth it. */
if (binary_cmp)
set_charset(&my_charset_bin);
else
set_charset(args[1]->charset());
/*
We could also do boyer-more for non-const items, but as we would have to
recompute the tables for each row it's not worth it.
*/ */
if (args[1]->const_item() && !(specialflag & SPECIAL_NO_NEW_FUNC)) if (args[1]->const_item() && !use_strnxfrm(charset()) &&
!(specialflag & SPECIAL_NO_NEW_FUNC))
{ {
String* res2 = args[1]->val_str(&tmp_value2); String* res2 = args[1]->val_str(&tmp_value2);
if (!res2) if (!res2)
......
...@@ -2083,7 +2083,8 @@ longlong ...@@ -2083,7 +2083,8 @@ longlong
Item_func_set_user_var::val_int() Item_func_set_user_var::val_int()
{ {
longlong value=args[0]->val_int(); longlong value=args[0]->val_int();
update_hash((void*) &value,sizeof(longlong),INT_RESULT, default_charset_info); update_hash((void*) &value, sizeof(longlong), INT_RESULT,
default_charset_info);
return value; return value;
} }
...@@ -2092,9 +2093,10 @@ Item_func_set_user_var::val_str(String *str) ...@@ -2092,9 +2093,10 @@ Item_func_set_user_var::val_str(String *str)
{ {
String *res=args[0]->val_str(str); String *res=args[0]->val_str(str);
if (!res) // Null value if (!res) // Null value
update_hash((void*) 0, 0, STRING_RESULT, default_charset_info); update_hash((void*) 0, 0, STRING_RESULT, &my_charset_bin);
else else
update_hash(res->c_ptr(),res->length()+1,STRING_RESULT,res->charset()); update_hash((void*) res->ptr(), res->length(), STRING_RESULT,
res->charset());
return res; return res;
} }
...@@ -2129,13 +2131,13 @@ Item_func_get_user_var::val_str(String *str) ...@@ -2129,13 +2131,13 @@ Item_func_get_user_var::val_str(String *str)
return NULL; return NULL;
switch (entry->type) { switch (entry->type) {
case REAL_RESULT: case REAL_RESULT:
str->set(*(double*) entry->value,decimals,thd_charset()); str->set(*(double*) entry->value,decimals, &my_charset_bin);
break; break;
case INT_RESULT: case INT_RESULT:
str->set(*(longlong*) entry->value,thd_charset()); str->set(*(longlong*) entry->value, &my_charset_bin);
break; break;
case STRING_RESULT: case STRING_RESULT:
if (str->copy(entry->value, entry->length-1, entry->var_charset)) if (str->copy(entry->value, entry->length, entry->var_charset))
{ {
null_value=1; null_value=1;
return NULL; return NULL;
...@@ -2191,8 +2193,6 @@ longlong Item_func_get_user_var::val_int() ...@@ -2191,8 +2193,6 @@ longlong Item_func_get_user_var::val_int()
return LL(0); // Impossible return LL(0); // Impossible
} }
/* From sql_parse.cc */
extern bool is_update_query(enum enum_sql_command command);
void Item_func_get_user_var::fix_length_and_dec() void Item_func_get_user_var::fix_length_and_dec()
{ {
...@@ -2207,13 +2207,15 @@ void Item_func_get_user_var::fix_length_and_dec() ...@@ -2207,13 +2207,15 @@ void Item_func_get_user_var::fix_length_and_dec()
if (opt_bin_log && is_update_query(thd->lex.sql_command) && if (opt_bin_log && is_update_query(thd->lex.sql_command) &&
var_entry->used_query_id != thd->query_id) var_entry->used_query_id != thd->query_id)
{ {
uint size;
/* /*
First we need to store value of var_entry, when the next situation appers: First we need to store value of var_entry, when the next situation
appers:
> set @a:=1; > set @a:=1;
> insert into t1 values (@a), (@a:=@a+1), (@a:=@a+1); > insert into t1 values (@a), (@a:=@a+1), (@a:=@a+1);
We have to write to binlog value @a= 1; We have to write to binlog value @a= 1;
*/ */
uint size= ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT)) + var_entry->length; size= ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT)) + var_entry->length;
if (!(user_var_event= (BINLOG_USER_VAR_EVENT *) thd->alloc(size))) if (!(user_var_event= (BINLOG_USER_VAR_EVENT *) thd->alloc(size)))
goto err; goto err;
...@@ -2240,6 +2242,7 @@ void Item_func_get_user_var::fix_length_and_dec() ...@@ -2240,6 +2242,7 @@ void Item_func_get_user_var::fix_length_and_dec()
} }
} }
return; return;
err: err:
thd->fatal_error(); thd->fatal_error();
return; return;
...@@ -2247,7 +2250,9 @@ void Item_func_get_user_var::fix_length_and_dec() ...@@ -2247,7 +2250,9 @@ void Item_func_get_user_var::fix_length_and_dec()
bool Item_func_get_user_var::const_item() const bool Item_func_get_user_var::const_item() const
{ return var_entry && current_thd->query_id != var_entry->update_query_id; } {
return var_entry && current_thd->query_id != var_entry->update_query_id;
}
enum Item_result Item_func_get_user_var::result_type() const enum Item_result Item_func_get_user_var::result_type() const
...@@ -2275,14 +2280,9 @@ bool Item_func_get_user_var::eq(const Item *item, bool binary_cmp) const ...@@ -2275,14 +2280,9 @@ bool Item_func_get_user_var::eq(const Item *item, bool binary_cmp) const
if (this == item) if (this == item)
return 1; // Same item is same. return 1; // Same item is same.
/* Check if other type is also a get_user_var() object */ /* Check if other type is also a get_user_var() object */
#ifdef FIX_THIS
if (item->eq == &Item_func_get_user_var::eq)
return 0;
#else
if (item->type() != FUNC_ITEM || if (item->type() != FUNC_ITEM ||
((Item_func*) item)->func_name() != func_name()) ((Item_func*) item)->func_name() != func_name())
return 0; return 0;
#endif
Item_func_get_user_var *other=(Item_func_get_user_var*) item; Item_func_get_user_var *other=(Item_func_get_user_var*) item;
return (name.length == other->name.length && return (name.length == other->name.length &&
!memcmp(name.str, other->name.str, name.length)); !memcmp(name.str, other->name.str, name.length));
......
This diff is collapsed.
...@@ -635,7 +635,7 @@ class User_var_log_event: public Log_event ...@@ -635,7 +635,7 @@ class User_var_log_event: public Log_event
ulong val_len; ulong val_len;
Item_result type; Item_result type;
uint charset_number; uint charset_number;
byte is_null; bool is_null;
#ifndef MYSQL_CLIENT #ifndef MYSQL_CLIENT
User_var_log_event(THD* thd_arg, char *name_arg, uint name_len_arg, User_var_log_event(THD* thd_arg, char *name_arg, uint name_len_arg,
char *val_arg, ulong val_len_arg, Item_result type_arg, char *val_arg, ulong val_len_arg, Item_result type_arg,
......
...@@ -830,13 +830,15 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user, ...@@ -830,13 +830,15 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
} }
} }
else else
{
/* /*
Real scramble is only sent to old servers. This can be blocked Real scramble is only sent to old servers. This can be blocked
by calling mysql_options(MYSQL *, MYSQL_SECURE_CONNECT, (char*) &1); by calling mysql_options(MYSQL *, MYSQL_SECURE_CONNECT, (char*) &1);
*/ */
end=scramble(strend(buff+5)+1, mysql->scramble_buff, passwd, end=scramble(strend(buff+5)+1, mysql->scramble_buff, passwd,
(my_bool) (mysql->protocol_version == 9)); (my_bool) (mysql->protocol_version == 9));
}
/* Add database if needed */ /* Add database if needed */
if (db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB)) if (db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB))
{ {
......
...@@ -346,6 +346,7 @@ int quick_rm_table(enum db_type base,const char *db, ...@@ -346,6 +346,7 @@ int quick_rm_table(enum db_type base,const char *db,
bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list); bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list);
bool mysql_change_db(THD *thd,const char *name); bool mysql_change_db(THD *thd,const char *name);
void mysql_parse(THD *thd,char *inBuf,uint length); void mysql_parse(THD *thd,char *inBuf,uint length);
bool is_update_query(enum enum_sql_command command);
void free_items(Item *item); void free_items(Item *item);
bool alloc_query(THD *thd, char *packet, ulong packet_length); bool alloc_query(THD *thd, char *packet, ulong packet_length);
void mysql_init_select(LEX *lex); void mysql_init_select(LEX *lex);
......
...@@ -295,11 +295,12 @@ void ...@@ -295,11 +295,12 @@ void
send_ok(THD *thd, ha_rows affected_rows, ulonglong id, const char *message) send_ok(THD *thd, ha_rows affected_rows, ulonglong id, const char *message)
{ {
NET *net= &thd->net; NET *net= &thd->net;
if (net->no_send_ok || !net->vio) // hack for re-parsing queries
return;
char buff[MYSQL_ERRMSG_SIZE+10],*pos; char buff[MYSQL_ERRMSG_SIZE+10],*pos;
DBUG_ENTER("send_ok"); DBUG_ENTER("send_ok");
if (net->no_send_ok || !net->vio) // hack for re-parsing queries
DBUG_VOID_RETURN;
buff[0]=0; // No fields buff[0]=0; // No fields
pos=net_store_length(buff+1,(ulonglong) affected_rows); pos=net_store_length(buff+1,(ulonglong) affected_rows);
pos=net_store_length(pos, (ulonglong) id); pos=net_store_length(pos, (ulonglong) id);
......
...@@ -485,7 +485,7 @@ void prepare_scramble(THD *thd, ACL_USER *acl_user,char* prepared_scramble) ...@@ -485,7 +485,7 @@ void prepare_scramble(THD *thd, ACL_USER *acl_user,char* prepared_scramble)
Get master privilges for user (priviliges for all tables). Get master privilges for user (priviliges for all tables).
Required before connecting to MySQL Required before connecting to MySQL
as we have 2 stage handshake now we cache user not to lookup As we have 2 stage handshake now we cache user not to lookup
it second time. At the second stage we do not lookup user in case it second time. At the second stage we do not lookup user in case
we already know it; we already know it;
...@@ -494,14 +494,13 @@ void prepare_scramble(THD *thd, ACL_USER *acl_user,char* prepared_scramble) ...@@ -494,14 +494,13 @@ void prepare_scramble(THD *thd, ACL_USER *acl_user,char* prepared_scramble)
ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
const char *password,const char *message,char **priv_user, const char *password,const char *message,char **priv_user,
bool old_ver, USER_RESOURCES *mqh, char *prepared_scramble, bool old_ver, USER_RESOURCES *mqh, char *prepared_scramble,
uint *cur_priv_version,ACL_USER** hint_user) uint *cur_priv_version, ACL_USER **cached_user)
{ {
ulong user_access=NO_ACCESS; ulong user_access=NO_ACCESS;
*priv_user= (char*) user; *priv_user= (char*) user;
bool password_correct= 0; bool password_correct= 0;
int stage= (*hint_user != NULL); /* NULL passed as first stage */ int stage= (*cached_user != NULL); /* NULL passed as first stage */
ACL_USER *acl_user= NULL; ACL_USER *acl_user= NULL;
DBUG_ENTER("acl_getroot"); DBUG_ENTER("acl_getroot");
bzero(mqh,sizeof(USER_RESOURCES)); bzero(mqh,sizeof(USER_RESOURCES));
...@@ -512,7 +511,6 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, ...@@ -512,7 +511,6 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
} }
VOID(pthread_mutex_lock(&acl_cache->lock)); VOID(pthread_mutex_lock(&acl_cache->lock));
/* /*
Get possible access from user_list. This is or'ed to others not Get possible access from user_list. This is or'ed to others not
fully specified fully specified
...@@ -520,9 +518,10 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, ...@@ -520,9 +518,10 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
If we have cached user use it, in other case look it up. If we have cached user use it, in other case look it up.
*/ */
if (stage && (*cur_priv_version==priv_version)) if (stage && (*cur_priv_version == priv_version))
acl_user=*hint_user; acl_user= *cached_user;
else else
{
for (uint i=0 ; i < acl_users.elements ; i++) for (uint i=0 ; i < acl_users.elements ; i++)
{ {
ACL_USER *acl_user_search=dynamic_element(&acl_users,i,ACL_USER*); ACL_USER *acl_user_search=dynamic_element(&acl_users,i,ACL_USER*);
...@@ -531,60 +530,59 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, ...@@ -531,60 +530,59 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
if (compare_hostname(&acl_user_search->host,host,ip)) if (compare_hostname(&acl_user_search->host,host,ip))
{ {
/* Found mathing user */ /* Found mathing user */
acl_user=acl_user_search; acl_user= acl_user_search;
/* Store it as a cache */ /* Store it as a cache */
*hint_user=acl_user; *cached_user= acl_user;
*cur_priv_version=priv_version; *cur_priv_version= priv_version;
break; break;
} }
} }
} }
}
/* Now we have acl_user found and may start our checks */ /* Now we have acl_user found and may start our checks */
if (acl_user) if (acl_user)
{ {
/* Password should present for both or absend for both */ /* Password should present for both or absend for both */
if (!acl_user->password && !*password || if (!acl_user->password && !*password)
(acl_user->password && *password)) password_correct=1;
else if (!acl_user->password || !*password)
{ {
/* Quick check and accept for empty passwords*/ *cached_user= 0; // Impossible to connect
if (!acl_user->password && !*password) }
password_correct=1; else
else /* Normal password presents */ {
/* New version password is checked differently */
if (acl_user->pversion)
{ {
/* New version password is checked differently */ if (stage) /* We check password only on the second stage */
if (acl_user->pversion) {
{ if (!validate_password(password,message,acl_user->salt))
if (stage) /* We check password only on the second stage */ password_correct=1;
{ }
if (!validate_password(password,message,acl_user->salt)) else /* First stage - just prepare scramble */
password_correct=1; prepare_scramble(thd,acl_user,prepared_scramble);
} }
else /* First stage - just prepare scramble */ /* Old way to check password */
prepare_scramble(thd,acl_user,prepared_scramble); else
} {
/* Old way to check password */ /* Checking the scramble at any stage. First - old clients */
else if (!check_scramble(password,message,acl_user->salt,
{ (my_bool) old_ver))
/* Checking the scramble at any stage. First - old clients */ password_correct=1;
if (!check_scramble(password,message,acl_user->salt, else if (!stage) /* Here if password incorrect */
(my_bool) old_ver)) {
password_correct=1; /* At the first stage - prepare scramble */
else if (!stage) /* Here if password incorrect */ prepare_scramble(thd,acl_user,prepared_scramble);
{ }
/* At the first stage - prepare scramble */
prepare_scramble(thd,acl_user,prepared_scramble);
}
}
} }
} }
} }
/* If user not found password_correct will also be zero */ /* If user not found password_correct will also be zero */
if (!password_correct) if (!password_correct)
goto unlock_and_exit; goto unlock_and_exit;
/* OK. User found and password checked continue validation */ /* OK. User found and password checked continue validation */
...@@ -1120,7 +1118,10 @@ bool change_password(THD *thd, const char *host, const char *user, ...@@ -1120,7 +1118,10 @@ bool change_password(THD *thd, const char *host, const char *user,
if (check_change_password(thd, host, user)) if (check_change_password(thd, host, user))
DBUG_RETURN(1); DBUG_RETURN(1);
/* password should always be 0,16 or 45 chars; simple hack to avoid cracking */ /*
password should always be 0,16 or 45 chars;
Simple hack to avoid cracking
*/
length=(uint) strlen(new_password); length=(uint) strlen(new_password);
if (length!=45) if (length!=45)
......
...@@ -225,7 +225,7 @@ class st_select_lex_node { ...@@ -225,7 +225,7 @@ class st_select_lex_node {
return (void*) sql_calloc((uint) size); return (void*) sql_calloc((uint) size);
} }
static void operator delete(void *ptr,size_t size) {} static void operator delete(void *ptr,size_t size) {}
st_select_lex_node() {} st_select_lex_node(): linkage(UNSPECIFIED_TYPE) {}
virtual ~st_select_lex_node() {} virtual ~st_select_lex_node() {}
inline st_select_lex_node* get_master() { return master; } inline st_select_lex_node* get_master() { return master; }
virtual void init_query(); virtual void init_query();
......
This diff is collapsed.
...@@ -639,9 +639,11 @@ bool str_to_time(const char *str,uint length,TIME *l_time) ...@@ -639,9 +639,11 @@ bool str_to_time(const char *str,uint length,TIME *l_time)
for (value=0; str != end && my_isdigit(&my_charset_latin1,*str) ; str++) for (value=0; str != end && my_isdigit(&my_charset_latin1,*str) ; str++)
value=value*10L + (long) (*str - '0'); value=value*10L + (long) (*str - '0');
if (*str == ' ') /* Move to last space */
if (str != end && *str == ' ')
{ {
while (++str != end && str[0] == ' ') ; while (++str != end && str[0] == ' ')
{}
str--; str--;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment