Commit f2a8927d authored by Sinisa@sinisa.nasamreza.org's avatar Sinisa@sinisa.nasamreza.org

Merge sinisa@work.mysql.com:/home/bk/mysql-4.1

into sinisa.nasamreza.org:/mnt/work/mysql-4.1
parents 410cbef6 d7b5238b
......@@ -597,3 +597,4 @@ vio/test-sslclient
vio/test-sslserver
vio/viotest-ssl
scripts/fill_help_tables.sql
scripts/fill_help_tables
......@@ -991,7 +991,8 @@ int do_sync_with_master2(const char* p)
mysql_errno(mysql), mysql_error(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)))
die("line %u: empty result in %s", start_lineno, query_buf);
if (!row[0])
......@@ -1021,17 +1022,19 @@ int do_save_master_pos()
MYSQL_RES* res;
MYSQL_ROW row;
MYSQL* mysql = &cur_con->mysql;
const char *query;
int rpl_parse;
rpl_parse = mysql_rpl_parse_enabled(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,
mysql_errno(mysql), mysql_error(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)))
die("line %u: empty result in show master status", start_lineno);
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)
Send_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->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->type= server_field.type;
client_field->flags= server_field.flags;
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))
client_field->flags|= NUM_FLAG;
......
......@@ -4,9 +4,6 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
stop slave;
reset master;
drop table if exists t1;
create table t1(n char(30));
set @i1:=12345678901234, @i2:=-12345678901234, @i3:=0, @i4:=-1;
set @s1:='This is a test', @r1:=12.5, @r2:=-12.5;
......@@ -23,7 +20,6 @@ set @q:='abc';
insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2'));
set @a:=5;
insert into t1 values (@a),(@a);
start slave;
select * from t1;
n
12345678901234
......@@ -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 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 601 User var 2 601 @s2=''
slave-bin.000001 637 User var 2 637 @s3='abc'def'
slave-bin.000001 680 User var 2 680 @s4='abc\def'
slave-bin.000001 723 User var 2 723 @s5='abc'def'
slave-bin.000001 766 Query 1 766 use `test`; insert into t1 values (@s1), (@s2), (@s3), (@s4), (@s5)
slave-bin.000001 856 User var 2 856 @n1=NULL
slave-bin.000001 882 Query 1 882 use `test`; insert into t1 values (@n1)
slave-bin.000001 944 Query 1 944 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 1094 User var 2 1094 @a='2'
slave-bin.000001 1130 Query 1 1130 use `test`; insert into t1 values (@a+(@b:=@a+1))
slave-bin.000001 1202 User var 2 1202 @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 1344 User var 2 1344 @a=5
slave-bin.000001 1386 Query 1 1386 use `test`; insert into t1 values (@a),(@a)
slave-bin.000001 600 User var 2 600 @s2=''
slave-bin.000001 635 User var 2 635 @s3='abc'def'
slave-bin.000001 677 User var 2 677 @s4='abc\def'
slave-bin.000001 719 User var 2 719 @s5='abc'def'
slave-bin.000001 761 Query 1 761 use `test`; insert into t1 values (@s1), (@s2), (@s3), (@s4), (@s5)
slave-bin.000001 851 User var 2 851 @n1=NULL
slave-bin.000001 877 Query 1 877 use `test`; insert into t1 values (@n1)
slave-bin.000001 939 Query 1 939 use `test`; insert into t1 values (@n2)
slave-bin.000001 1001 Query 1 1001 use `test`; insert into t1 values (@a:=0), (@a:=@a+1), (@a:=@a+1)
slave-bin.000001 1089 User var 2 1089 @a='2'
slave-bin.000001 1124 Query 1 1124 use `test`; insert into t1 values (@a+(@b:=@a+1))
slave-bin.000001 1196 User var 2 1196 @q='abc'
slave-bin.000001 1233 Query 1 1233 use `test`; insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2'))
slave-bin.000001 1337 User var 2 1337 @a=5
slave-bin.000001 1379 Query 1 1379 use `test`; insert into t1 values (@a),(@a)
drop table t1;
stop slave;
......@@ -130,6 +130,10 @@ select d from t1 having d like "%HELLO%";
d
HELLO
HELLO MY
select d from t1 having d like "%HE%LLO%";
d
HELLO
HELLO MY
select t from t1 order by t;
t
NULL
......
#
# Test of replicating user variables
#
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));
set @i1:=12345678901234, @i2:=-12345678901234, @i3:=0, @i4:=-1;
set @s1:='This is a test', @r1:=12.5, @r2:=-12.5;
......@@ -27,7 +21,6 @@ set @a:=5;
insert into t1 values (@a),(@a);
save_master_pos;
connection slave;
start slave;
sync_with_master;
select * from t1;
show binlog events from 141;
......
......@@ -87,6 +87,7 @@ select b from t1 where b like "%HELLO%";
select d from t1 where d 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 "%HE%LLO%";
select t from t1 order by t;
select c from t1 order by c;
select b from t1 order by b;
......
......@@ -1203,18 +1203,22 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
max_length= (*ref)->max_length;
maybe_null= (*ref)->maybe_null;
decimals= (*ref)->decimals;
set_charset((*ref)->charset());
fixed= 1;
if (ref && (*ref)->check_cols(1))
return 1;
return 0;
}
bool Item_default_value::eq(const Item *item, bool binary_cmp) const
{
return item->type() == DEFAULT_VALUE_ITEM &&
((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)
{
if (!arg)
......
......@@ -1129,11 +1129,16 @@ void in_string::set(uint pos,Item *item)
String *res=item->val_str(str);
if (res && res != str)
*str= *res;
// BAR TODO: I'm not sure this is absolutely correct
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)
{
return (byte*) item->val_str(&tmp);
......@@ -1692,6 +1697,7 @@ longlong Item_func_isnull::val_int()
return args[0]->is_null() ? 1: 0;
}
longlong Item_func_isnotnull::val_int()
{
return args[0]->is_null() ? 0 : 1;
......@@ -1713,9 +1719,6 @@ longlong Item_func_like::val_int()
return 0;
}
null_value=0;
if ((res->charset()->state & MY_CS_BINSORT) ||
(res2->charset()->state & MY_CS_BINSORT))
set_charset(&my_charset_bin);
if (canDoTurboBM)
return turboBM_matches(res->ptr(), res->length()) ? 1 : 0;
return my_wildcmp(charset(),
......@@ -1748,10 +1751,19 @@ bool Item_func_like::fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref)
return 1;
/*
TODO--we could do it for non-const, but we'd have to
recompute the tables for each row--probably not worth it.
Comparision is by default done according to character set of LIKE
*/
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);
if (!res2)
......
......@@ -2083,7 +2083,8 @@ longlong
Item_func_set_user_var::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;
}
......@@ -2092,9 +2093,10 @@ Item_func_set_user_var::val_str(String *str)
{
String *res=args[0]->val_str(str);
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
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;
}
......@@ -2129,13 +2131,13 @@ Item_func_get_user_var::val_str(String *str)
return NULL;
switch (entry->type) {
case REAL_RESULT:
str->set(*(double*) entry->value,decimals,thd_charset());
str->set(*(double*) entry->value,decimals, &my_charset_bin);
break;
case INT_RESULT:
str->set(*(longlong*) entry->value,thd_charset());
str->set(*(longlong*) entry->value, &my_charset_bin);
break;
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;
return NULL;
......@@ -2191,8 +2193,6 @@ longlong Item_func_get_user_var::val_int()
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()
{
......@@ -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) &&
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;
> insert into t1 values (@a), (@a:=@a+1), (@a:=@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)))
goto err;
......@@ -2240,6 +2242,7 @@ void Item_func_get_user_var::fix_length_and_dec()
}
}
return;
err:
thd->fatal_error();
return;
......@@ -2247,7 +2250,9 @@ err:
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
......@@ -2275,14 +2280,9 @@ bool Item_func_get_user_var::eq(const Item *item, bool binary_cmp) const
if (this == item)
return 1; // Same item is same.
/* 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 ||
((Item_func*) item)->func_name() != func_name())
return 0;
#endif
Item_func_get_user_var *other=(Item_func_get_user_var*) item;
return (name.length == other->name.length &&
!memcmp(name.str, other->name.str, name.length));
......
This diff is collapsed.
......@@ -635,7 +635,7 @@ public:
ulong val_len;
Item_result type;
uint charset_number;
byte is_null;
bool is_null;
#ifndef MYSQL_CLIENT
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,
......
......@@ -830,13 +830,15 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
}
}
else
{
/*
Real scramble is only sent to old servers. This can be blocked
by calling mysql_options(MYSQL *, MYSQL_SECURE_CONNECT, (char*) &1);
Real scramble is only sent to old servers. This can be blocked
by calling mysql_options(MYSQL *, MYSQL_SECURE_CONNECT, (char*) &1);
*/
end=scramble(strend(buff+5)+1, mysql->scramble_buff, passwd,
(my_bool) (mysql->protocol_version == 9));
}
/* Add database if needed */
if (db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_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_change_db(THD *thd,const char *name);
void mysql_parse(THD *thd,char *inBuf,uint length);
bool is_update_query(enum enum_sql_command command);
void free_items(Item *item);
bool alloc_query(THD *thd, char *packet, ulong packet_length);
void mysql_init_select(LEX *lex);
......
......@@ -295,11 +295,12 @@ void
send_ok(THD *thd, ha_rows affected_rows, ulonglong id, const char *message)
{
NET *net= &thd->net;
if (net->no_send_ok || !net->vio) // hack for re-parsing queries
return;
char buff[MYSQL_ERRMSG_SIZE+10],*pos;
DBUG_ENTER("send_ok");
if (net->no_send_ok || !net->vio) // hack for re-parsing queries
DBUG_VOID_RETURN;
buff[0]=0; // No fields
pos=net_store_length(buff+1,(ulonglong) affected_rows);
pos=net_store_length(pos, (ulonglong) id);
......
......@@ -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).
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
we already know it;
......@@ -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,
const char *password,const char *message,char **priv_user,
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;
*priv_user= (char*) user;
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;
DBUG_ENTER("acl_getroot");
bzero(mqh,sizeof(USER_RESOURCES));
......@@ -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));
/*
Get possible access from user_list. This is or'ed to others not
fully specified
......@@ -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 (stage && (*cur_priv_version==priv_version))
acl_user=*hint_user;
if (stage && (*cur_priv_version == priv_version))
acl_user= *cached_user;
else
{
for (uint i=0 ; i < acl_users.elements ; i++)
{
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,
if (compare_hostname(&acl_user_search->host,host,ip))
{
/* Found mathing user */
acl_user=acl_user_search;
acl_user= acl_user_search;
/* Store it as a cache */
*hint_user=acl_user;
*cur_priv_version=priv_version;
*cached_user= acl_user;
*cur_priv_version= priv_version;
break;
}
}
}
}
/* Now we have acl_user found and may start our checks */
if (acl_user)
{
/* Password should present for both or absend for both */
if (!acl_user->password && !*password ||
(acl_user->password && *password))
if (!acl_user->password && !*password)
password_correct=1;
else if (!acl_user->password || !*password)
{
/* Quick check and accept for empty passwords*/
if (!acl_user->password && !*password)
password_correct=1;
else /* Normal password presents */
*cached_user= 0; // Impossible to connect
}
else
{
/* New version password is checked differently */
if (acl_user->pversion)
{
/* New version password is checked differently */
if (acl_user->pversion)
{
if (stage) /* We check password only on the second stage */
{
if (!validate_password(password,message,acl_user->salt))
password_correct=1;
}
else /* First stage - just prepare scramble */
prepare_scramble(thd,acl_user,prepared_scramble);
}
/* Old way to check password */
else
{
/* Checking the scramble at any stage. First - old clients */
if (!check_scramble(password,message,acl_user->salt,
(my_bool) old_ver))
password_correct=1;
else if (!stage) /* Here if password incorrect */
{
/* At the first stage - prepare scramble */
prepare_scramble(thd,acl_user,prepared_scramble);
}
}
if (stage) /* We check password only on the second stage */
{
if (!validate_password(password,message,acl_user->salt))
password_correct=1;
}
else /* First stage - just prepare scramble */
prepare_scramble(thd,acl_user,prepared_scramble);
}
/* Old way to check password */
else
{
/* Checking the scramble at any stage. First - old clients */
if (!check_scramble(password,message,acl_user->salt,
(my_bool) old_ver))
password_correct=1;
else if (!stage) /* Here if password incorrect */
{
/* At the first stage - prepare scramble */
prepare_scramble(thd,acl_user,prepared_scramble);
}
}
}
}
/* If user not found password_correct will also be zero */
if (!password_correct)
goto unlock_and_exit;
goto unlock_and_exit;
/* OK. User found and password checked continue validation */
......@@ -1120,7 +1118,10 @@ bool change_password(THD *thd, const char *host, const char *user,
if (check_change_password(thd, host, user))
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);
if (length!=45)
......
......@@ -89,6 +89,7 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result,
if ((*param->item)->type() != Item::INT_ITEM ||
(*param->item)->val() < 0)
{
delete pc;
my_error(ER_WRONG_PARAMETERS_TO_PROCEDURE, MYF(0), proc_name);
DBUG_RETURN(0);
}
......@@ -103,6 +104,7 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result,
if ((*param->item)->type() != Item::INT_ITEM ||
(*param->item)->val() < 0)
{
delete pc;
my_error(ER_WRONG_PARAMETERS_TO_PROCEDURE, MYF(0), proc_name);
DBUG_RETURN(0);
}
......@@ -111,6 +113,7 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result,
else if ((*param->item)->type() != Item::INT_ITEM ||
(*param->item)->val() < 0)
{
delete pc;
my_error(ER_WRONG_PARAMETERS_TO_PROCEDURE, MYF(0), proc_name);
DBUG_RETURN(0);
}
......
......@@ -225,7 +225,7 @@ public:
return (void*) sql_calloc((uint) 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() {}
inline st_select_lex_node* get_master() { return master; }
virtual void init_query();
......
This diff is collapsed.
......@@ -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++)
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--;
}
......
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