summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorkonstantin@mysql.com <>2003-12-05 00:00:02 +0300
committerkonstantin@mysql.com <>2003-12-05 00:00:02 +0300
commita8c811e2db1bf419489fb66614c1d08ac12838e4 (patch)
tree75ef1d3db7fc0e32e48aa6b7c2368d365be3527c /sql
parentcf192063d14e9121e6f74ee11957f3fb9f989020 (diff)
parent5217a5e8fcd230da3994bbbd848a4af5bc3593a6 (diff)
downloadmariadb-git-a8c811e2db1bf419489fb66614c1d08ac12838e4.tar.gz
Merge mysql.com:/home/kostja/mysql/mysql-4.0-root
into mysql.com:/home/kostja/mysql/mysql-4.0-1790
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc76
-rw-r--r--sql/item_strfunc.cc4
-rw-r--r--sql/item_strfunc.h4
-rw-r--r--sql/log_event.h2
-rw-r--r--sql/mysqld.cc2
-rw-r--r--sql/slave.cc31
-rw-r--r--sql/sql_acl.cc5
-rw-r--r--sql/uniques.cc14
8 files changed, 97 insertions, 41 deletions
diff --git a/sql/field.cc b/sql/field.cc
index 43481ca0963..1070d0f7b7d 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -2520,31 +2520,60 @@ void Field_timestamp::store(double nr)
** function.
*/
-static longlong fix_datetime(longlong nr)
+static longlong fix_datetime(longlong nr, TIME *time_res)
{
+ long part1,part2;
+
if (nr == LL(0) || nr >= LL(10000101000000))
- return nr; // Normal datetime >= Year 1000
+ goto ok;
if (nr < 101)
goto err;
if (nr <= (YY_PART_YEAR-1)*10000L+1231L)
- return (nr+20000000L)*1000000L; // YYMMDD, year: 2000-2069
+ {
+ nr= (nr+20000000L)*1000000L; // YYMMDD, year: 2000-2069
+ goto ok;
+ }
if (nr < (YY_PART_YEAR)*10000L+101L)
goto err;
if (nr <= 991231L)
- return (nr+19000000L)*1000000L; // YYMMDD, year: 1970-1999
+ {
+ nr= (nr+19000000L)*1000000L; // YYMMDD, year: 1970-1999
+ goto ok;
+ }
if (nr < 10000101L)
goto err;
if (nr <= 99991231L)
- return nr*1000000L;
+ {
+ nr= nr*1000000L;
+ goto ok;
+ }
if (nr < 101000000L)
goto err;
if (nr <= (YY_PART_YEAR-1)*LL(10000000000)+LL(1231235959))
- return nr+LL(20000000000000); // YYMMDDHHMMSS, 2000-2069
+ {
+ nr= nr+LL(20000000000000); // YYMMDDHHMMSS, 2000-2069
+ goto ok;
+ }
if (nr < YY_PART_YEAR*LL(10000000000)+ LL(101000000))
goto err;
if (nr <= LL(991231235959))
- return nr+LL(19000000000000); // YYMMDDHHMMSS, 1970-1999
-
+ nr= nr+LL(19000000000000); // YYMMDDHHMMSS, 1970-1999
+
+ ok:
+ part1=(long) (nr/LL(1000000));
+ part2=(long) (nr - (longlong) part1*LL(1000000));
+ time_res->year= (int) (part1/10000L); part1%=10000L;
+ time_res->month= (int) part1 / 100;
+ time_res->day= (int) part1 % 100;
+ time_res->hour= (int) (part2/10000L); part2%=10000L;
+ time_res->minute=(int) part2 / 100;
+ time_res->second=(int) part2 % 100;
+
+ if (time_res->year <= 9999 && time_res->month <= 12 &&
+ time_res->day <= 31 && time_res->hour <= 23 &&
+ time_res->minute <= 59 && time_res->second <= 59)
+ return nr;
+
err:
current_thd->cuted_fields++;
return LL(0);
@@ -2555,20 +2584,18 @@ void Field_timestamp::store(longlong nr)
{
TIME l_time;
time_t timestamp;
- long part1,part2;
- if ((nr=fix_datetime(nr)))
+ if ((nr= fix_datetime(nr, &l_time)))
{
long not_used;
- part1=(long) (nr/LL(1000000));
- part2=(long) (nr - (longlong) part1*LL(1000000));
- l_time.year= (int) (part1/10000L); part1%=10000L;
- l_time.month= (int) part1 / 100;
- l_time.day= (int) part1 % 100;
- l_time.hour= (int) (part2/10000L); part2%=10000L;
- l_time.minute=(int) part2 / 100;
- l_time.second=(int) part2 % 100;
- timestamp=my_gmt_sec(&l_time, &not_used);
+
+ if (l_time.year >= TIMESTAMP_MAX_YEAR || l_time.year < 1900+YY_PART_YEAR)
+ {
+ current_thd->cuted_fields++;
+ timestamp=0;
+ }
+ else
+ timestamp=my_gmt_sec(&l_time, &not_used);
}
else
timestamp=0;
@@ -3406,13 +3433,10 @@ void Field_datetime::store(double nr)
void Field_datetime::store(longlong nr)
{
- if (nr < 0 || nr > LL(99991231235959))
- {
- nr=0;
- current_thd->cuted_fields++;
- }
- else
- nr=fix_datetime(nr);
+ TIME not_used;
+
+ nr= fix_datetime(nr, &not_used);
+
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
{
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index fe9c8b9e099..dd1ec6bd2da 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -1806,7 +1806,7 @@ String *Item_func_rpad::val_str(String *str)
const char *ptr_pad;
int32 count= (int32) args[1]->val_int();
String *res =args[0]->val_str(str);
- String *rpad = args[2]->val_str(str);
+ String *rpad = args[2]->val_str(&rpad_str);
if (!res || args[1]->null_value || !rpad || count < 0)
goto err;
@@ -1866,7 +1866,7 @@ String *Item_func_lpad::val_str(String *str)
const char *ptr_pad;
ulong count= (long) args[1]->val_int();
String *res= args[0]->val_str(str);
- String *lpad= args[2]->val_str(str);
+ String *lpad= args[2]->val_str(&lpad_str);
if (!res || args[1]->null_value || !lpad)
goto err;
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index 5c9706ed633..fc98ebfe67d 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -436,7 +436,7 @@ public:
class Item_func_rpad :public Item_str_func
{
- String tmp_value;
+ String tmp_value, rpad_str;
public:
Item_func_rpad(Item *arg1,Item *arg2,Item *arg3)
:Item_str_func(arg1,arg2,arg3) {}
@@ -449,7 +449,7 @@ public:
class Item_func_lpad :public Item_str_func
{
- String tmp_value;
+ String tmp_value, lpad_str;
public:
Item_func_lpad(Item *arg1,Item *arg2,Item *arg3)
:Item_str_func(arg1,arg2,arg3) {}
diff --git a/sql/log_event.h b/sql/log_event.h
index 2e6b7373dc2..929d550951e 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -529,7 +529,7 @@ public:
#ifndef MYSQL_CLIENT
Intvar_log_event(THD* thd_arg,uchar type_arg, ulonglong val_arg)
- :Log_event(),val(val_arg),type(type_arg)
+ :Log_event(thd_arg,0,0),val(val_arg),type(type_arg)
{}
void pack_info(String* packet);
int exec_event(struct st_relay_log_info* rli);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 4c6cf1d5039..2e87ade9174 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -2573,7 +2573,7 @@ default_service_handling(char **argv,
}
/* We must have servicename last */
*pos++= ' ';
- strmake(pos, servicename, (uint) (end+2 - pos));
+ (void) add_quoted_string(pos, servicename, end);
if (Service.got_service_option(argv, "install"))
{
diff --git a/sql/slave.cc b/sql/slave.cc
index 6816d968007..5bc31fd6a21 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -3497,8 +3497,20 @@ rli->relay_log_pos=%s rli->pending=%lu",
sizeof(rli->relay_log_name)-1);
flush_relay_log_info(rli);
}
-
- // next log is hot
+
+ /*
+ Now we want to open this next log. To know if it's a hot log (the one
+ being written by the I/O thread now) or a cold log, we can use
+ is_active(); if it is hot, we use the I/O cache; if it's cold we open
+ the file normally. But if is_active() reports that the log is hot, this
+ may change between the test and the consequence of the test. So we may
+ open the I/O cache whereas the log is now cold, which is nonsense.
+ To guard against this, we need to have LOCK_log.
+ */
+
+ DBUG_PRINT("info",("hot_log: %d",hot_log));
+ if (!hot_log) /* if hot_log, we already have this mutex */
+ pthread_mutex_lock(log_lock);
if (rli->relay_log.is_active(rli->linfo.log_file_name))
{
#ifdef EXTRA_DEBUG
@@ -3511,15 +3523,24 @@ rli->relay_log_pos=%s rli->pending=%lu",
/*
Read pointer has to be at the start since we are the only
- reader
+ reader.
+ We must keep the LOCK_log to read the 4 first bytes, as this is a hot
+ log (same as when we call read_log_event() above: for a hot log we
+ take the mutex).
*/
if (check_binlog_magic(cur_log,&errmsg))
+ {
+ if (!hot_log) pthread_mutex_unlock(log_lock);
goto err;
+ }
+ if (!hot_log) pthread_mutex_unlock(log_lock);
continue;
}
+ if (!hot_log) pthread_mutex_unlock(log_lock);
/*
- if we get here, the log was not hot, so we will have to
- open it ourselves
+ if we get here, the log was not hot, so we will have to open it
+ ourselves. We are sure that the log is still not hot now (a log can get
+ from hot to cold, but not from cold to hot). No need for LOCK_log.
*/
#ifdef EXTRA_DEBUG
sql_print_error("next log '%s' is not active",
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 065394c87d0..03a359d44e7 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -588,6 +588,11 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
/* Prepare certificate (if exists) */
DBUG_PRINT("info",("checkpoint 1"));
X509* cert=SSL_get_peer_certificate(ssl);
+ if (!cert)
+ {
+ user_access=NO_ACCESS;
+ break;
+ }
DBUG_PRINT("info",("checkpoint 2"));
/* If X509 issuer is speified, we check it... */
if (acl_user->x509_issuer)
diff --git a/sql/uniques.cc b/sql/uniques.cc
index d00893a8605..967392d12d5 100644
--- a/sql/uniques.cc
+++ b/sql/uniques.cc
@@ -37,14 +37,20 @@
int unique_write_to_file(gptr key, element_count count, Unique *unique)
{
+ /*
+ Use unique->size (size of element stored in the tree) and not
+ unique->tree.size_of_element. The latter is different from unique->size
+ when tree implementation chooses to store pointer to key in TREE_ELEMENT
+ (instead of storing the element itself there)
+ */
return my_b_write(&unique->file, (byte*) key,
- unique->tree.size_of_element) ? 1 : 0;
+ unique->size) ? 1 : 0;
}
int unique_write_to_ptrs(gptr key, element_count count, Unique *unique)
{
- memcpy(unique->record_pointers, key, unique->tree.size_of_element);
- unique->record_pointers+=unique->tree.size_of_element;
+ memcpy(unique->record_pointers, key, unique->size);
+ unique->record_pointers+=unique->size;
return 0;
}
@@ -132,7 +138,7 @@ bool Unique::get(TABLE *table)
bzero((char*) &sort_param,sizeof(sort_param));
sort_param.max_rows= elements;
sort_param.sort_form=table;
- sort_param.sort_length=sort_param.ref_length=tree.size_of_element;
+ sort_param.sort_length=sort_param.ref_length=size;
sort_param.keys= max_in_memory_size / sort_param.sort_length;
sort_param.not_killable=1;