Merge bk-internal:/home/bk/mysql-5.0
into serg.mylan:/usr/home/serg/Abk/mysql-5.0
This commit is contained in:
commit
da27256e12
@ -121,19 +121,36 @@
|
||||
#endif
|
||||
|
||||
/*
|
||||
Solaris include file <sys/feature_tests.h> refers to X/Open document
|
||||
Solaris 9 include file <sys/feature_tests.h> refers to X/Open document
|
||||
|
||||
System Interfaces and Headers, Issue 5
|
||||
|
||||
saying we should define _XOPEN_SOURCE=500 to get POSIX.1c prototypes
|
||||
saying we should define _XOPEN_SOURCE=500 to get POSIX.1c prototypes,
|
||||
but apparently other systems (namely FreeBSD) don't agree.
|
||||
Furthermore X/Open has since 2004 "System Interfaces, Issue 6"
|
||||
that dictates _XOPEN_SOURCE=600, but Solaris checks for 500.
|
||||
So, let's define 500 for solaris only.
|
||||
|
||||
On a newer Solaris 10, the above file recognizes also _XOPEN_SOURCE=600.
|
||||
Furthermore, it tests that if a program requires older standard
|
||||
(_XOPEN_SOURCE<600 or _POSIX_C_SOURCE<200112L) it cannot be
|
||||
run on a new compiler (that defines _STDC_C99) and issues an #error.
|
||||
It's also an #error if a program requires new standard (_XOPEN_SOURCE=600
|
||||
or _POSIX_C_SOURCE=200112L) and a compiler does not define _STDC_C99.
|
||||
|
||||
To add more to this mess, Sun Studio C compiler defines _STDC_C99 while
|
||||
C++ compiler does not!
|
||||
|
||||
So, in a desperate attempt to get correct prototypes for both
|
||||
C and C++ code, we define either _XOPEN_SOURCE=600 or _XOPEN_SOURCE=500
|
||||
depending on the compiler's announced C standard support.
|
||||
|
||||
Cleaner solutions are welcome.
|
||||
*/
|
||||
#ifdef __sun
|
||||
#if __STDC_VERSION__ - 0 >= 199901L
|
||||
#define _XOPEN_SOURCE 600
|
||||
#else
|
||||
#define _XOPEN_SOURCE 500
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(THREAD) && !defined(__WIN__) && !defined(OS2)
|
||||
#ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
|
@ -845,7 +845,8 @@ extern char *get_charsets_dir(char *buf);
|
||||
extern my_bool my_charset_same(CHARSET_INFO *cs1, CHARSET_INFO *cs2);
|
||||
extern my_bool init_compiled_charsets(myf flags);
|
||||
extern void add_compiled_collation(CHARSET_INFO *cs);
|
||||
extern ulong escape_string_for_mysql(CHARSET_INFO *charset_info, char *to,
|
||||
extern ulong escape_string_for_mysql(CHARSET_INFO *charset_info,
|
||||
char *to, ulong to_length,
|
||||
const char *from, ulong length);
|
||||
|
||||
extern void thd_increment_bytes_sent(ulong length);
|
||||
|
@ -390,8 +390,9 @@ struct trx_struct{
|
||||
dulint table_id; /* table id if the preceding field is
|
||||
TRUE */
|
||||
/*------------------------------*/
|
||||
int active_trans; /* whether a transaction in MySQL
|
||||
is active */
|
||||
int active_trans; /* 1 - if a transaction in MySQL
|
||||
is active. 2 - if prepare_commit_mutex
|
||||
was taken */
|
||||
void* mysql_thd; /* MySQL thread handle corresponding
|
||||
to this trx, or NULL */
|
||||
char** mysql_query_str;/* pointer to the field in mysqld_thd
|
||||
|
@ -1575,14 +1575,14 @@ mysql_hex_string(char *to, const char *from, ulong length)
|
||||
ulong STDCALL
|
||||
mysql_escape_string(char *to,const char *from,ulong length)
|
||||
{
|
||||
return escape_string_for_mysql(default_charset_info, to, from, length);
|
||||
return escape_string_for_mysql(default_charset_info, to, 0, from, length);
|
||||
}
|
||||
|
||||
ulong STDCALL
|
||||
mysql_real_escape_string(MYSQL *mysql, char *to,const char *from,
|
||||
ulong length)
|
||||
{
|
||||
return escape_string_for_mysql(mysql->charset, to, from, length);
|
||||
return escape_string_for_mysql(mysql->charset, to, 0, from, length);
|
||||
}
|
||||
|
||||
|
||||
|
@ -10,3 +10,4 @@ create temporary table mysqltest.t2 (n int);
|
||||
show status like 'Slave_open_temp_tables';
|
||||
Variable_name Value
|
||||
Slave_open_temp_tables 0
|
||||
drop database mysqltest;
|
||||
|
@ -11,3 +11,6 @@ disconnect master;
|
||||
connection slave;
|
||||
--real_sleep 3; # time for DROP to be written
|
||||
show status like 'Slave_open_temp_tables';
|
||||
connection default;
|
||||
drop database mysqltest;
|
||||
|
||||
|
@ -547,10 +547,10 @@ CHARSET_INFO *get_charset_by_csname(const char *cs_name,
|
||||
DBUG_PRINT("enter",("name: '%s'", cs_name));
|
||||
|
||||
(void) init_available_charsets(MYF(0)); /* If it isn't initialized */
|
||||
|
||||
|
||||
cs_number= get_charset_number(cs_name, cs_flags);
|
||||
cs= cs_number ? get_internal_charset(cs_number, flags) : NULL;
|
||||
|
||||
|
||||
if (!cs && (flags & MY_WME))
|
||||
{
|
||||
char index_file[FN_REFLEN];
|
||||
@ -561,21 +561,34 @@ CHARSET_INFO *get_charset_by_csname(const char *cs_name,
|
||||
DBUG_RETURN(cs);
|
||||
}
|
||||
|
||||
|
||||
ulong escape_string_for_mysql(CHARSET_INFO *charset_info, char *to,
|
||||
/*
|
||||
NOTE
|
||||
to keep old C API, to_length may be 0 to mean "big enough"
|
||||
RETURN
|
||||
the length of the escaped string or ~0 if it did not fit.
|
||||
*/
|
||||
ulong escape_string_for_mysql(CHARSET_INFO *charset_info,
|
||||
char *to, ulong to_length,
|
||||
const char *from, ulong length)
|
||||
{
|
||||
const char *to_start= to;
|
||||
const char *end;
|
||||
const char *end, *to_end=to_start + (to_length ? to_length-1 : 2*length);
|
||||
my_bool overflow=0;
|
||||
#ifdef USE_MB
|
||||
my_bool use_mb_flag= use_mb(charset_info);
|
||||
#endif
|
||||
for (end= from + length; from != end; from++)
|
||||
for (end= from + length; from < end; from++)
|
||||
{
|
||||
char escape=0;
|
||||
#ifdef USE_MB
|
||||
int l;
|
||||
if (use_mb_flag && (l= my_ismbchar(charset_info, from, end)))
|
||||
{
|
||||
if (to + l >= to_end)
|
||||
{
|
||||
overflow=1;
|
||||
break;
|
||||
}
|
||||
while (l--)
|
||||
*to++= *from++;
|
||||
from--;
|
||||
@ -593,45 +606,53 @@ ulong escape_string_for_mysql(CHARSET_INFO *charset_info, char *to,
|
||||
a valid GBK character, but 0xbf5c is. (0x27 = ', 0x5c = \)
|
||||
*/
|
||||
if (use_mb_flag && (l= my_mbcharlen(charset_info, *from)) > 1)
|
||||
{
|
||||
*to++= '\\';
|
||||
*to++= *from;
|
||||
continue;
|
||||
}
|
||||
escape= *from;
|
||||
else
|
||||
#endif
|
||||
switch (*from) {
|
||||
case 0: /* Must be escaped for 'mysql' */
|
||||
*to++= '\\';
|
||||
*to++= '0';
|
||||
escape= '0';
|
||||
break;
|
||||
case '\n': /* Must be escaped for logs */
|
||||
*to++= '\\';
|
||||
*to++= 'n';
|
||||
escape= 'n';
|
||||
break;
|
||||
case '\r':
|
||||
*to++= '\\';
|
||||
*to++= 'r';
|
||||
escape= 'r';
|
||||
break;
|
||||
case '\\':
|
||||
*to++= '\\';
|
||||
*to++= '\\';
|
||||
escape= '\\';
|
||||
break;
|
||||
case '\'':
|
||||
*to++= '\\';
|
||||
*to++= '\'';
|
||||
escape= '\'';
|
||||
break;
|
||||
case '"': /* Better safe than sorry */
|
||||
*to++= '\\';
|
||||
*to++= '"';
|
||||
escape= '"';
|
||||
break;
|
||||
case '\032': /* This gives problems on Win32 */
|
||||
*to++= '\\';
|
||||
*to++= 'Z';
|
||||
escape= 'Z';
|
||||
break;
|
||||
default:
|
||||
}
|
||||
if (escape)
|
||||
{
|
||||
if (to + 2 >= to_end)
|
||||
{
|
||||
overflow=1;
|
||||
break;
|
||||
}
|
||||
*to++= '\\';
|
||||
*to++= escape;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (to + 1 >= to_end)
|
||||
{
|
||||
overflow=1;
|
||||
break;
|
||||
}
|
||||
*to++= *from;
|
||||
}
|
||||
}
|
||||
*to= 0;
|
||||
return (ulong) (to - to_start);
|
||||
return overflow ? (ulong)~0 : (ulong) (to - to_start);
|
||||
}
|
||||
|
||||
|
23
sql/field.cc
23
sql/field.cc
@ -752,25 +752,22 @@ bool Field::quote_data(String *unquoted_string)
|
||||
{
|
||||
char escaped_string[IO_SIZE];
|
||||
char *unquoted_string_buffer= (char *)(unquoted_string->ptr());
|
||||
uint need_quotes;
|
||||
DBUG_ENTER("Field::quote_data");
|
||||
|
||||
// this is the same call that mysql_real_escape_string() calls
|
||||
escape_string_for_mysql(&my_charset_bin, (char *)escaped_string,
|
||||
unquoted_string->ptr(), unquoted_string->length());
|
||||
|
||||
need_quotes= needs_quotes();
|
||||
|
||||
if (need_quotes == 0)
|
||||
if (!needs_quotes())
|
||||
DBUG_RETURN(0);
|
||||
|
||||
// this is the same call that mysql_real_escape_string() calls
|
||||
if (escape_string_for_mysql(&my_charset_bin, (char *)escaped_string,
|
||||
sizeof(escaped_string), unquoted_string->ptr(),
|
||||
unquoted_string->length()) == (ulong)~0)
|
||||
DBUG_RETURN(1);
|
||||
|
||||
// reset string, then re-append with quotes and escaped values
|
||||
unquoted_string->length(0);
|
||||
if (unquoted_string->append('\''))
|
||||
DBUG_RETURN(1);
|
||||
if (unquoted_string->append((char *)escaped_string))
|
||||
DBUG_RETURN(1);
|
||||
if (unquoted_string->append('\''))
|
||||
if (unquoted_string->append('\'') ||
|
||||
unquoted_string->append((char *)escaped_string) ||
|
||||
unquoted_string->append('\''))
|
||||
DBUG_RETURN(1);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
@ -469,6 +469,7 @@ static int check_foreign_data_source(FEDERATED_SHARE *share)
|
||||
*/
|
||||
query.append("SHOW TABLES LIKE '");
|
||||
escape_string_for_mysql(&my_charset_bin, (char *)escaped_table_base_name,
|
||||
sizeof(escaped_table_base_name),
|
||||
share->table_base_name,
|
||||
share->table_base_name_length);
|
||||
query.append(escaped_table_base_name);
|
||||
|
@ -45,7 +45,8 @@ have disables the InnoDB inlining in this file. */
|
||||
|
||||
#include "ha_innodb.h"
|
||||
|
||||
pthread_mutex_t innobase_mutex;
|
||||
pthread_mutex_t innobase_share_mutex, // to protect innobase_open_files
|
||||
prepare_commit_mutex; // to force correct commit order in binlog
|
||||
bool innodb_inited= 0;
|
||||
|
||||
/* Store MySQL definition of 'byte': in Linux it is char while InnoDB
|
||||
@ -1268,7 +1269,8 @@ innobase_init(void)
|
||||
|
||||
(void) hash_init(&innobase_open_tables,system_charset_info, 32, 0, 0,
|
||||
(hash_get_key) innobase_get_key, 0, 0);
|
||||
pthread_mutex_init(&innobase_mutex, MY_MUTEX_INIT_FAST);
|
||||
pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST);
|
||||
pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
|
||||
innodb_inited= 1;
|
||||
|
||||
/* If this is a replication slave and we needed to do a crash recovery,
|
||||
@ -1322,7 +1324,8 @@ innobase_end(void)
|
||||
hash_free(&innobase_open_tables);
|
||||
my_free(internal_innobase_data_file_path,
|
||||
MYF(MY_ALLOW_ZERO_PTR));
|
||||
pthread_mutex_destroy(&innobase_mutex);
|
||||
pthread_mutex_destroy(&innobase_share_mutex);
|
||||
pthread_mutex_destroy(&prepare_commit_mutex);
|
||||
}
|
||||
|
||||
DBUG_RETURN(err);
|
||||
@ -1480,9 +1483,20 @@ innobase_commit(
|
||||
/* We were instructed to commit the whole transaction, or
|
||||
this is an SQL statement end and autocommit is on */
|
||||
|
||||
/* We need current binlog position for ibbackup to work.
|
||||
Note, the position is current because of prepare_commit_mutex */
|
||||
trx->mysql_log_file_name = mysql_bin_log.get_log_fname();
|
||||
trx->mysql_log_offset =
|
||||
(ib_longlong)mysql_bin_log.get_log_file()->pos_in_file;
|
||||
|
||||
innobase_commit_low(trx);
|
||||
|
||||
if (trx->active_trans == 2) {
|
||||
|
||||
pthread_mutex_unlock(&prepare_commit_mutex);
|
||||
}
|
||||
trx->active_trans = 0;
|
||||
|
||||
} else {
|
||||
/* We just mark the SQL statement ended and do not do a
|
||||
transaction commit */
|
||||
@ -5953,7 +5967,7 @@ static mysql_byte* innobase_get_key(INNOBASE_SHARE *share,uint *length,
|
||||
static INNOBASE_SHARE *get_share(const char *table_name)
|
||||
{
|
||||
INNOBASE_SHARE *share;
|
||||
pthread_mutex_lock(&innobase_mutex);
|
||||
pthread_mutex_lock(&innobase_share_mutex);
|
||||
uint length=(uint) strlen(table_name);
|
||||
if (!(share=(INNOBASE_SHARE*) hash_search(&innobase_open_tables,
|
||||
(mysql_byte*) table_name,
|
||||
@ -5967,7 +5981,7 @@ static INNOBASE_SHARE *get_share(const char *table_name)
|
||||
strmov(share->table_name,table_name);
|
||||
if (my_hash_insert(&innobase_open_tables, (mysql_byte*) share))
|
||||
{
|
||||
pthread_mutex_unlock(&innobase_mutex);
|
||||
pthread_mutex_unlock(&innobase_share_mutex);
|
||||
my_free((gptr) share,0);
|
||||
return 0;
|
||||
}
|
||||
@ -5976,13 +5990,13 @@ static INNOBASE_SHARE *get_share(const char *table_name)
|
||||
}
|
||||
}
|
||||
share->use_count++;
|
||||
pthread_mutex_unlock(&innobase_mutex);
|
||||
pthread_mutex_unlock(&innobase_share_mutex);
|
||||
return share;
|
||||
}
|
||||
|
||||
static void free_share(INNOBASE_SHARE *share)
|
||||
{
|
||||
pthread_mutex_lock(&innobase_mutex);
|
||||
pthread_mutex_lock(&innobase_share_mutex);
|
||||
if (!--share->use_count)
|
||||
{
|
||||
hash_delete(&innobase_open_tables, (mysql_byte*) share);
|
||||
@ -5990,7 +6004,7 @@ static void free_share(INNOBASE_SHARE *share)
|
||||
pthread_mutex_destroy(&share->mutex);
|
||||
my_free((gptr) share, MYF(0));
|
||||
}
|
||||
pthread_mutex_unlock(&innobase_mutex);
|
||||
pthread_mutex_unlock(&innobase_share_mutex);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
@ -6454,15 +6468,38 @@ innobase_xa_prepare(
|
||||
FALSE - the current SQL statement ended */
|
||||
{
|
||||
int error = 0;
|
||||
trx_t* trx;
|
||||
trx_t* trx = check_trx_exists(thd);
|
||||
|
||||
if (thd->lex->sql_command != SQLCOM_XA_PREPARE) {
|
||||
|
||||
/* For ibbackup to work the order of transactions in binlog
|
||||
and InnoDB must be the same. Consider the situation
|
||||
|
||||
thread1> prepare; write to binlog; ...
|
||||
<context switch>
|
||||
thread2> prepare; write to binlog; commit
|
||||
thread1> ... commit
|
||||
|
||||
To ensure this will not happen we're taking the mutex on
|
||||
prepare, and releasing it on commit.
|
||||
|
||||
Note: only do it for normal commits, done via ha_commit_trans.
|
||||
If 2pc protocol is executed by external transaction
|
||||
coordinator, it will be just a regular MySQL client
|
||||
executing XA PREPARE and XA COMMIT commands.
|
||||
In this case we cannot know how many minutes or hours
|
||||
will be between XA PREPARE and XA COMMIT, and we don't want
|
||||
to block for undefined period of time.
|
||||
*/
|
||||
pthread_mutex_lock(&prepare_commit_mutex);
|
||||
trx->active_trans = 2;
|
||||
}
|
||||
|
||||
if (!thd->variables.innodb_support_xa) {
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
trx = check_trx_exists(thd);
|
||||
|
||||
trx->xid=thd->transaction.xid;
|
||||
|
||||
/* Release a possible FIFO ticket and search latch. Since we will
|
||||
|
@ -526,7 +526,6 @@ void trans_register_ha(THD *thd, bool all, handlerton *ht_arg)
|
||||
|
||||
/*
|
||||
RETURN
|
||||
-1 - cannot prepare
|
||||
0 - ok
|
||||
1 - error, transaction was rolled back
|
||||
*/
|
||||
@ -539,8 +538,6 @@ int ha_prepare(THD *thd)
|
||||
#ifdef USING_TRANSACTIONS
|
||||
if (trans->nht)
|
||||
{
|
||||
if (trans->no_2pc)
|
||||
DBUG_RETURN(-1);
|
||||
for (; *ht; ht++)
|
||||
{
|
||||
int err;
|
||||
|
@ -2050,7 +2050,7 @@ const String *Item_param::query_val_str(String* str) const
|
||||
buf= str->c_ptr_quick();
|
||||
ptr= buf;
|
||||
*ptr++= '\'';
|
||||
ptr+= escape_string_for_mysql(str_value.charset(), ptr,
|
||||
ptr+= escape_string_for_mysql(str_value.charset(), ptr, 0,
|
||||
str_value.ptr(), str_value.length());
|
||||
*ptr++= '\'';
|
||||
str->length(ptr - buf);
|
||||
|
@ -1720,7 +1720,7 @@ void Item_func_coalesce::fix_length_and_dec()
|
||||
decimals= 0;
|
||||
break;
|
||||
case ROW_RESULT:
|
||||
defaullt:
|
||||
default:
|
||||
DBUG_ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
@ -2012,6 +2012,7 @@ int Format_description_log_event::exec_event(struct st_relay_log_info* rli)
|
||||
delete rli->relay_log.description_event_for_exec;
|
||||
rli->relay_log.description_event_for_exec= this;
|
||||
|
||||
#ifdef USING_TRANSACTIONS
|
||||
/*
|
||||
As a transaction NEVER spans on 2 or more binlogs:
|
||||
if we have an active transaction at this point, the master died
|
||||
@ -2033,6 +2034,7 @@ int Format_description_log_event::exec_event(struct st_relay_log_info* rli)
|
||||
"to its binary log.");
|
||||
end_trans(thd, ROLLBACK);
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
If this event comes from ourselves, there is no cleaning task to perform,
|
||||
we don't call Start_log_event_v3::exec_event() (this was just to update the
|
||||
|
@ -865,7 +865,7 @@ static bool insert_params_from_vars_with_log(Prepared_statement *stmt,
|
||||
*ptr++= '\'';
|
||||
ptr+=
|
||||
escape_string_for_mysql(&my_charset_utf8_general_ci,
|
||||
ptr, entry->name.str, entry->name.length);
|
||||
ptr, 0, entry->name.str, entry->name.length);
|
||||
*ptr++= '\'';
|
||||
str.length(ptr - buf);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user