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

Merge sinisa@bk-internal.mysql.com:/home/bk/mysql-4.0

into sinisa.nasamreza.org:/mnt/work/mysql-4.0
parents 1d93c8f5 0ede29ff
......@@ -44,6 +44,7 @@ jorge@linux.jorge.mysql.com
kaj@work.mysql.com
lenz@kallisto.mysql.com
lenz@mysql.com
miguel@hegel.(none)
miguel@hegel.br
miguel@hegel.local
miguel@light.
......@@ -84,6 +85,7 @@ sasha@mysql.sashanet.com
serg@build.mysql2.com
serg@serg.mylan
serg@serg.mysql.com
serg@sergbook.mylan
serg@sergbook.mysql.com
sinisa@rhols221.adsl.netsonic.fi
tfr@beta.frontier86.ee
......
......@@ -711,7 +711,7 @@ AC_DEFUN(MYSQL_FIND_OPENSSL, [
done
for d in /usr/ssl/lib /usr/local/ssl/lib /usr/lib/openssl \
/usr/lib /opt/ssl/lib /opt/openssl/lib /usr/local/lib/ ; do
/usr/lib /usr/lib64 /opt/ssl/lib /opt/openssl/lib /usr/local/lib/ ; do
if test -f $d/libssl.a ; then
OPENSSL_LIB=$d
fi
......@@ -721,7 +721,7 @@ AC_DEFUN(MYSQL_FIND_OPENSSL, [
echo "Could not find an installation of OpenSSL"
if test -n "$OPENSSL_LIB" ; then
if test "$IS_LINUX" = "true"; then
echo "Looks like you've forgotted to install OpenSSL development RPM"
echo "Looks like you've forgotten to install OpenSSL development RPM"
fi
fi
exit 1
......
......@@ -396,8 +396,8 @@ static int check_header(IO_CACHE* file)
if (buf[4] == START_EVENT)
{
uint event_len;
event_len = uint4korr(buf + 4);
old_format = (event_len < LOG_EVENT_HEADER_LEN + START_HEADER_LEN);
event_len = uint4korr(buf + EVENT_LEN_OFFSET);
old_format = (event_len < (LOG_EVENT_HEADER_LEN + START_HEADER_LEN));
}
}
my_b_seek(file, pos);
......
......@@ -757,7 +757,7 @@ AC_CHECK_LIB(crypt, crypt)
AC_CHECK_FUNC(crypt, AC_DEFINE(HAVE_CRYPT))
# For sem_xxx functions on Solaris 2.6
AC_CHECK_FUNC(sem_init, , AC_CHECK_LIB(posix4))
AC_CHECK_FUNC(sem_init, , AC_CHECK_LIB(posix4, sem_init))
# For compress in zlib
MYSQL_CHECK_ZLIB_WITH_COMPRESS($with_named_zlib)
......
......@@ -494,6 +494,46 @@ dict_index_get_nth_col_pos(
return(ULINT_UNDEFINED);
}
/************************************************************************
Returns TRUE if the index contains a column or a prefix of that column. */
ibool
dict_index_contains_col_or_prefix(
/*==============================*/
/* out: TRUE if contains the column or its
prefix */
dict_index_t* index, /* in: index */
ulint n) /* in: column number */
{
dict_field_t* field;
dict_col_t* col;
ulint pos;
ulint n_fields;
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
if (index->type & DICT_CLUSTERED) {
return(TRUE);
}
col = dict_table_get_nth_col(index->table, n);
n_fields = dict_index_get_n_fields(index);
for (pos = 0; pos < n_fields; pos++) {
field = dict_index_get_nth_field(index, pos);
if (col == field->col) {
return(TRUE);
}
}
return(FALSE);
}
/************************************************************************
Looks for a matching field in an index. The column and the prefix len have
to be the same. */
......
......@@ -569,6 +569,16 @@ dict_index_get_nth_col_pos(
dict_index_t* index, /* in: index */
ulint n); /* in: column number */
/************************************************************************
Returns TRUE if the index contains a column or a prefix of that column. */
ibool
dict_index_contains_col_or_prefix(
/*==============================*/
/* out: TRUE if contains the column or its
prefix */
dict_index_t* index, /* in: index */
ulint n); /* in: column number */
/************************************************************************
Looks for a matching field in an index. The column and the prefix len has
to be the same. */
......
......@@ -446,7 +446,6 @@ page_copy_rec_list_end_no_locks(
page_cur_move_to_next(&cur1);
}
/* Track a memory corruption bug in Windows */
ut_a(mach_read_from_2(new_page + UNIV_PAGE_SIZE - 10) == PAGE_INFIMUM);
page_cur_set_before_first(new_page, &cur2);
......@@ -456,11 +455,23 @@ page_copy_rec_list_end_no_locks(
sup = page_get_supremum_rec(page);
while (sup != page_cur_get_rec(&cur1)) {
ut_a(
page_cur_rec_insert(&cur2, page_cur_get_rec(&cur1), mtr));
if (!page_cur_rec_insert(&cur2,
page_cur_get_rec(&cur1), mtr)) {
/* Track an assertion failure reported on the mailing
list on June 18th, 2003 */
buf_page_print(new_page);
buf_page_print(page);
ut_print_timestamp(stderr);
fprintf(stderr,
"InnoDB: rec offset %lu, cur1 offset %lu, cur2 offset %lu\n",
(ulint)(rec - page),
(ulint)(page_cur_get_rec(&cur1) - page),
(ulint)(page_cur_get_rec(&cur2) - new_page));
ut_a(0);
}
ut_a(mach_read_from_2(new_page + UNIV_PAGE_SIZE - 10)
== PAGE_INFIMUM);
page_cur_move_to_next(&cur1);
page_cur_move_to_next(&cur2);
}
......
......@@ -791,27 +791,30 @@ row_ins_foreign_check_on_constraint(
mem_heap_free(tmp_heap);
clust_rec = btr_pcur_get_rec(cascade->pcur);
}
if (!page_rec_is_user_rec(clust_rec)) {
fprintf(stderr,
if (!page_rec_is_user_rec(clust_rec)
|| btr_pcur_get_low_match(cascade->pcur)
< dict_index_get_n_unique(clust_index)) {
fprintf(stderr,
"InnoDB: error in cascade of a foreign key op\n"
"InnoDB: index %s table %s\n", index->name,
index->table->name);
rec_sprintf(err_buf, 900, rec);
fprintf(stderr, "InnoDB: record %s\n", err_buf);
rec_sprintf(err_buf, 900, rec);
fprintf(stderr, "InnoDB: record %s\n", err_buf);
rec_sprintf(err_buf, 900, clust_rec);
fprintf(stderr, "InnoDB: clustered record %s\n", err_buf);
fprintf(stderr,
rec_sprintf(err_buf, 900, clust_rec);
fprintf(stderr, "InnoDB: clustered record %s\n",
err_buf);
fprintf(stderr,
"InnoDB: Make a detailed bug report and send it\n");
fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n");
fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n");
err = DB_SUCCESS;
err = DB_SUCCESS;
goto nonstandard_exit_func;
goto nonstandard_exit_func;
}
}
/* Set an X-lock on the row to delete or update in the child table */
......
......@@ -609,7 +609,29 @@ row_sel_get_clust_rec(
clust_rec = btr_pcur_get_rec(&(plan->clust_pcur));
ut_ad(page_rec_is_user_rec(clust_rec));
/* Note: only if the search ends up on a non-infimum record is the
low_match value the real match to the search tuple */
if (!page_rec_is_user_rec(clust_rec)
|| btr_pcur_get_low_match(&(plan->clust_pcur))
< dict_index_get_n_unique(index)) {
ut_a(rec_get_deleted_flag(rec));
ut_a(node->read_view);
/* In a rare case it is possible that no clust rec is found
for a delete-marked secondary index record: if in row0umod.c
in row_undo_mod_remove_clust_low() we have already removed
the clust rec, while purge is still cleaning and removing
secondary index records associated with earlier versions of
the clustered index record. In that case we know that the
clustered index record did not exist in the read view of
trx. */
clust_rec = NULL;
goto func_exit;
}
if (!node->read_view) {
/* Try to place a lock on the index record */
......@@ -672,6 +694,7 @@ row_sel_get_clust_rec(
row_sel_fetch_columns(index, clust_rec,
UT_LIST_GET_FIRST(plan->columns));
func_exit:
*out_rec = clust_rec;
return(DB_SUCCESS);
......@@ -1253,6 +1276,8 @@ rec_loop:
/* PHASE 3: Get previous version in a consistent read */
cons_read_requires_clust_rec = FALSE;
if (consistent_read) {
/* This is a non-locking consistent read: if necessary, fetch
a previous version of the record */
......@@ -2269,7 +2294,10 @@ row_sel_get_clust_rec_for_mysql(
/* out: DB_SUCCESS or error code */
row_prebuilt_t* prebuilt,/* in: prebuilt struct in the handle */
dict_index_t* sec_index,/* in: secondary index where rec resides */
rec_t* rec, /* in: record in a non-clustered index */
rec_t* rec, /* in: record in a non-clustered index; if
this is a locking read, then rec is not
allowed to be delete-marked, and that would
not make sense either */
que_thr_t* thr, /* in: query thread */
rec_t** out_rec,/* out: clustered record or an old version of
it, NULL if the old version did not exist
......@@ -2285,7 +2313,7 @@ row_sel_get_clust_rec_for_mysql(
ulint err;
trx_t* trx;
char err_buf[1000];
*out_rec = NULL;
row_build_row_ref_in_tuple(prebuilt->clust_ref, sec_index, rec);
......@@ -2298,26 +2326,47 @@ row_sel_get_clust_rec_for_mysql(
clust_rec = btr_pcur_get_rec(prebuilt->clust_pcur);
if (!page_rec_is_user_rec(clust_rec)) {
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: error clustered record for sec rec not found\n"
"InnoDB: index %s table %s\n", sec_index->name,
sec_index->table->name);
/* Note: only if the search ends up on a non-infimum record is the
low_match value the real match to the search tuple */
rec_sprintf(err_buf, 900, rec);
fprintf(stderr, "InnoDB: sec index record %s\n", err_buf);
if (!page_rec_is_user_rec(clust_rec)
|| btr_pcur_get_low_match(prebuilt->clust_pcur)
< dict_index_get_n_unique(clust_index)) {
/* In a rare case it is possible that no clust rec is found
for a delete-marked secondary index record: if in row0umod.c
in row_undo_mod_remove_clust_low() we have already removed
the clust rec, while purge is still cleaning and removing
secondary index records associated with earlier versions of
the clustered index record. In that case we know that the
clustered index record did not exist in the read view of
trx. */
rec_sprintf(err_buf, 900, clust_rec);
fprintf(stderr, "InnoDB: clust index record %s\n", err_buf);
if (!rec_get_deleted_flag(rec)
|| prebuilt->select_lock_type != LOCK_NONE) {
trx = thr_get_trx(thr);
trx_print(err_buf, trx);
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: error clustered record for sec rec not found\n"
"InnoDB: index %s table %s\n", sec_index->name,
sec_index->table->name);
rec_sprintf(err_buf, 900, rec);
fprintf(stderr,
"InnoDB: sec index record %s\n", err_buf);
fprintf(stderr,
"%s\nInnoDB: Make a detailed bug report and send it\n",
err_buf);
fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n");
rec_sprintf(err_buf, 900, clust_rec);
fprintf(stderr,
"InnoDB: clust index record %s\n", err_buf);
trx = thr_get_trx(thr);
trx_print(err_buf, trx);
fprintf(stderr,
"%s\nInnoDB: Make a detailed bug report and send it\n",
err_buf);
fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n");
}
clust_rec = NULL;
......@@ -2989,8 +3038,6 @@ rec_loop:
/*-------------------------------------------------------------*/
/* PHASE 4: Look for matching records in a loop */
cons_read_requires_clust_rec = FALSE;
rec = btr_pcur_get_rec(pcur);
/*
printf("Using index %s cnt %lu ", index->name, cnt);
......@@ -3145,6 +3192,8 @@ rec_loop:
/* We are ready to look at a possible new index entry in the result
set: the cursor is now placed on a user record */
cons_read_requires_clust_rec = FALSE;
if (prebuilt->select_lock_type != LOCK_NONE) {
/* Try to place a lock on the index record; note that delete
marked records are a special case in a unique search. If there
......@@ -3170,8 +3219,6 @@ rec_loop:
/* This is a non-locking consistent read: if necessary, fetch
a previous version of the record */
cons_read_requires_clust_rec = FALSE;
if (trx->isolation_level == TRX_ISO_READ_UNCOMMITTED) {
/* Do nothing: we let a non-locking SELECT read the
......@@ -3215,7 +3262,7 @@ rec_loop:
if (rec_get_deleted_flag(rec) && !cons_read_requires_clust_rec) {
/* The record is delete marked: we can skip it if this is
/* The record is delete-marked: we can skip it if this is
not a consistent read which might see an earlier version
of a non-clustered index record */
......@@ -3324,7 +3371,7 @@ got_row:
goto normal_return;
next_rec:
/*-------------------------------------------------------------*/
/*-------------------------------------------------------------*/
/* PHASE 5: Move the cursor to the next index record */
if (mtr_has_extra_clust_latch) {
......
......@@ -59,7 +59,6 @@ row_vers_impl_x_locked_off_kernel(
ibool rec_del;
ulint err;
mtr_t mtr;
char err_buf[1000];
ut_ad(mutex_own(&kernel_mutex));
ut_ad(!rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED));
......@@ -77,22 +76,20 @@ row_vers_impl_x_locked_off_kernel(
clust_rec = row_get_clust_rec(BTR_SEARCH_LEAF, rec, index,
&clust_index, &mtr);
if (!clust_rec) {
rec_sprintf(err_buf, 900, rec);
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Error: cannot find the clustered index record\n"
"InnoDB: for a secondary index record in table %s index %s.\n"
"InnoDB: Secondary index record %s.\n"
"InnoDB: The table is probably corrupt. Please run CHECK TABLE on it.\n"
"InnoDB: You can try to repair the table by dump + drop + reimport.\n"
"InnoDB: Send a detailed bug report to mysql@lists.mysql.com.\n",
index->table_name, index->name, err_buf);
mutex_enter(&kernel_mutex);
mtr_commit(&mtr);
/* We assume there is no lock on the record, though this
is not certain because the table is apparently corrupt */
/* In a rare case it is possible that no clust rec is found
for a secondary index record: if in row0umod.c
row_undo_mod_remove_clust_low() we have already removed the
clust rec, while purge is still cleaning and removing
secondary index records associated with earlier versions of
the clustered index record. In that case there cannot be
any implicit lock on the secondary index record, because
an active transaction which has modified the secondary index
record has also modified the clustered index record. And in
a rollback we always undo the modifications to secondary index
records before the clustered index record. */
mutex_enter(&kernel_mutex);
mtr_commit(&mtr);
return(NULL);
}
......
......@@ -40,14 +40,17 @@
#include <arpa/inet.h>
#include <netdb.h>
#ifdef HAVE_SELECT_H
# include <select.h>
#include <select.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#ifdef HAVE_POLL
#include <sys/poll.h>
#endif
#endif /* !defined(MSDOS) && !defined(__WIN__) */
#ifdef HAVE_SYS_UN_H
# include <sys/un.h>
#include <sys/un.h>
#endif
#if defined(THREAD) && !defined(__WIN__)
#include <my_pthread.h> /* because of signal() */
......@@ -148,9 +151,12 @@ static MYSQL* spawn_init(MYSQL* parent, const char* host,
const char* user,
const char* passwd);
#if !(defined(__WIN__) || defined(OS2) || defined(__NETWARE__))
static int wait_for_data(my_socket fd, uint timeout);
#endif
/****************************************************************************
A modified version of connect(). connect2() allows you to specify
A modified version of connect(). my_connect() allows you to specify
a timeout value, in seconds, that we should wait until we
derermine we can't connect to a particular host. If timeout is 0,
my_connect() will behave exactly like connect().
......@@ -158,17 +164,13 @@ static MYSQL* spawn_init(MYSQL* parent, const char* host,
Base version coded by Steve Bernacki, Jr. <steve@navinet.net>
*****************************************************************************/
int my_connect(my_socket s, const struct sockaddr *name, uint namelen,
int my_connect(my_socket fd, const struct sockaddr *name, uint namelen,
uint timeout)
{
#if defined(__WIN__) || defined(OS2) || defined(__NETWARE__)
return connect(s, (struct sockaddr*) name, namelen);
return connect(fd, (struct sockaddr*) name, namelen);
#else
int flags, res, s_err;
SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint);
fd_set sfds;
struct timeval tv;
time_t start_time, now_time;
/*
If they passed us a timeout of zero, we should behave
......@@ -176,30 +178,68 @@ int my_connect(my_socket s, const struct sockaddr *name, uint namelen,
*/
if (timeout == 0)
return connect(s, (struct sockaddr*) name, namelen);
return connect(fd, (struct sockaddr*) name, namelen);
flags = fcntl(s, F_GETFL, 0); /* Set socket to not block */
flags = fcntl(fd, F_GETFL, 0); /* Set socket to not block */
#ifdef O_NONBLOCK
fcntl(s, F_SETFL, flags | O_NONBLOCK); /* and save the flags.. */
fcntl(fd, F_SETFL, flags | O_NONBLOCK); /* and save the flags.. */
#endif
res = connect(s, (struct sockaddr*) name, namelen);
s_err = errno; /* Save the error... */
fcntl(s, F_SETFL, flags);
res= connect(fd, (struct sockaddr*) name, namelen);
s_err= errno; /* Save the error... */
fcntl(fd, F_SETFL, flags);
if ((res != 0) && (s_err != EINPROGRESS))
{
errno = s_err; /* Restore it */
errno= s_err; /* Restore it */
return(-1);
}
if (res == 0) /* Connected quickly! */
return(0);
return wait_for_data(fd, timeout);
#endif
}
/*
Wait up to timeout seconds for a connection to be established.
We prefer to do this with poll() as there is no limitations with this.
If not, we will use select()
*/
#if !(defined(__WIN__) || defined(OS2) || defined(__NETWARE__))
static int wait_for_data(my_socket fd, uint timeout)
{
#ifdef HAVE_POLL
struct pollfd ufds;
int res;
ufds.fd= fd;
ufds.events= POLLIN | POLLPRI;
if (!(res= poll(&ufds, 1, (int) timeout*1000)))
{
errno= EINTR;
return -1;
}
if (res < 0 || !(ufds.revents & (POLLIN | POLLPRI)))
return -1;
return 0;
#else
SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint);
fd_set sfds;
struct timeval tv;
time_t start_time, now_time;
int res, s_err;
if (fd >= FD_SETSIZE) /* Check if wrong error */
return 0; /* Can't use timeout */
/*
Otherwise, our connection is "in progress." We can use
the select() call to wait up to a specified period of time
for the connection to suceed. If select() returns 0
(after waiting howevermany seconds), our socket never became
writable (host is probably unreachable.) Otherwise, if
Our connection is "in progress." We can use the select() call to wait
up to a specified period of time for the connection to suceed.
If select() returns 0 (after waiting howevermany seconds), our socket
never became writable (host is probably unreachable.) Otherwise, if
select() returns 1, then one of two conditions exist:
1. An error occured. We use getsockopt() to check for this.
......@@ -212,7 +252,7 @@ int my_connect(my_socket s, const struct sockaddr *name, uint namelen,
*/
FD_ZERO(&sfds);
FD_SET(s, &sfds);
FD_SET(fd, &sfds);
/*
select could be interrupted by a signal, and if it is,
the timeout should be adjusted and the select restarted
......@@ -226,10 +266,10 @@ int my_connect(my_socket s, const struct sockaddr *name, uint namelen,
tv.tv_sec = (long) timeout;
tv.tv_usec = 0;
#if defined(HPUX10) && defined(THREAD)
if ((res = select(s+1, NULL, (int*) &sfds, NULL, &tv)) > 0)
if ((res = select(fd+1, NULL, (int*) &sfds, NULL, &tv)) > 0)
break;
#else
if ((res = select(s+1, NULL, &sfds, NULL, &tv)) > 0)
if ((res = select(fd+1, NULL, &sfds, NULL, &tv)) > 0)
break;
#endif
if (res == 0) /* timeout */
......@@ -247,7 +287,7 @@ int my_connect(my_socket s, const struct sockaddr *name, uint namelen,
*/
s_err=0;
if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0)
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0)
return(-1);
if (s_err)
......@@ -256,9 +296,9 @@ int my_connect(my_socket s, const struct sockaddr *name, uint namelen,
return(-1); /* but return an error... */
}
return (0); /* ok */
#endif
#endif /* HAVE_POLL */
}
#endif /* defined(__WIN__) || defined(OS2) || defined(__NETWARE__) */
/*
Create a named pipe connection
......
......@@ -569,7 +569,9 @@ error () {
}
error_is () {
$CAT < $TIMEFILE | $SED -e 's/.* At line \(.*\)\: \(.*\)/ \>\> Error at line \1: \2<\</' | $HEAD -1
$ECHO "Errors are (from $TIMEFILE) :"
$CAT < $TIMEFILE
$ECHO "(the last line(s) may be the ones that caused the die() in mysqltest)"
}
prefix_to_8() {
......
......@@ -234,3 +234,16 @@ INSERT INTO t1 VALUES (1, 'a545f661efdd1fb66fdee3aab79945bf');
SELECT 1 FROM t1 WHERE tmp=AES_DECRYPT(tmp,"password");
1
DROP TABLE t1;
CREATE TABLE t1 (
wid int(10) unsigned NOT NULL auto_increment,
data_podp date default NULL,
status_wnio enum('nowy','podp','real','arch') NOT NULL default 'nowy',
PRIMARY KEY(wid),
);
INSERT INTO t1 VALUES (8,NULL,'real');
INSERT INTO t1 VALUES (9,NULL,'nowy');
SELECT elt(status_wnio,data_podp) FROM t1 GROUP BY wid;
elt(status_wnio,data_podp)
NULL
NULL
DROP TABLE t1;
......@@ -96,6 +96,11 @@ week(19981231,2) week(19981231,3) week(20000101,2) week(20000101,3)
select week(20001231,2),week(20001231,3);
week(20001231,2) week(20001231,3)
1 52
set default_week_format = 2;
select week(20001231),week(20001231,2),week(20001231,0);
week(20001231) week(20001231,2) week(20001231,0)
1 1 53
set default_week_format = 0;
select date_format('1998-12-31','%x-%v'),date_format('1999-01-01','%x-%v');
date_format('1998-12-31','%x-%v') date_format('1999-01-01','%x-%v')
1998-53 1998-53
......
drop table if exists t1;
delete from mysql.user where user='mysqltest_1';
delete from mysql.db where user='mysqltest_1';
flush privileges;
......@@ -64,8 +65,44 @@ GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, CREATE TE
revoke all privileges on mysqltest.* from mysqltest_1@localhost;
delete from mysql.user where user='mysqltest_1';
flush privileges;
grant usage on test.* to user@localhost with grant option;
show grants for user@localhost;
Grants for user@localhost
GRANT USAGE ON *.* TO 'user'@'localhost'
GRANT USAGE ON `test`.* TO 'user'@'localhost' WITH GRANT OPTION
grant usage on test.* to mysqltest_1@localhost with grant option;
show grants for mysqltest_1@localhost;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
GRANT USAGE ON `mysqltest`.* TO 'mysqltest_1'@'localhost' WITH GRANT OPTION
GRANT USAGE ON `test`.* TO 'mysqltest_1'@'localhost' WITH GRANT OPTION
delete from mysql.user where user='mysqltest_1';
delete from mysql.db where user='mysqltest_1';
delete from mysql.tables_priv where user='mysqltest_1';
delete from mysql.columns_priv where user='mysqltest_1';
flush privileges;
create table t1 (a int);
GRANT select,update,insert on t1 to mysqltest_1@localhost;
GRANT select (a), update (a),insert(a), references(a) on t1 to mysqltest_1@localhost;
show grants for mysqltest_1@localhost;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
GRANT SELECT, SELECT (a), INSERT, INSERT (a), UPDATE, UPDATE (a), REFERENCES (a) ON `test`.`t1` TO 'mysqltest_1'@'localhost'
select table_priv,column_priv from mysql.tables_priv where user="mysqltest_1";
table_priv column_priv
Select,Insert,Update Select,Insert,Update,References
REVOKE select (a), update on t1 from mysqltest_1@localhost;
show grants for mysqltest_1@localhost;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
GRANT SELECT, INSERT, INSERT (a), REFERENCES (a) ON `test`.`t1` TO 'mysqltest_1'@'localhost'
REVOKE insert,insert (a) on t1 from mysqltest_1@localhost;
GRANT references on t1 to mysqltest_1@localhost;
show grants for mysqltest_1@localhost;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
GRANT SELECT, REFERENCES, REFERENCES (a) ON `test`.`t1` TO 'mysqltest_1'@'localhost'
select table_priv,column_priv from mysql.tables_priv where user="mysqltest_1";
table_priv column_priv
Select,References References
delete from mysql.user where user='mysqltest_1';
delete from mysql.db where user='mysqltest_1';
delete from mysql.tables_priv where user='mysqltest_1';
delete from mysql.columns_priv where user='mysqltest_1';
flush privileges;
drop table t1;
......@@ -156,7 +156,7 @@ level id parent_id
1 1007 101
optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize error The handler for the table doesn't support optimize
test.t1 optimize status OK
show keys from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 0 PRIMARY 1 id A 87 NULL NULL BTREE
......@@ -180,7 +180,7 @@ create table t1 (a int) type=innodb;
insert into t1 values (1), (2);
optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize error The handler for the table doesn't support optimize
test.t1 optimize status OK
delete from t1 where a = 1;
select * from t1;
a
......@@ -712,7 +712,7 @@ world 2
hello 1
optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize error The handler for the table doesn't support optimize
test.t1 optimize status OK
show keys from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 0 PRIMARY 1 a A 2 NULL NULL BTREE
......@@ -1240,7 +1240,7 @@ t1 range c c 5 NULL 1 Using where
update t1 set c=a;
explain select * from t1 where c between 1 and 10000;
table type possible_keys key key_len ref rows Extra
t1 ALL c NULL NULL NULL 29537 Using where
t1 ALL c NULL NULL NULL 27682 Using where
drop table t1,t2;
create table t1 (id int primary key auto_increment, fk int, index index_fk (fk)) type=innodb;
insert into t1 (id) values (null),(null),(null),(null),(null);
......
......@@ -93,6 +93,6 @@ slave-bin.002 62 Query 1 168 use test; insert into t1 values (1)
slave-bin.002 122 Query 1 228 use test; drop table t1
show slave status;
Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
127.0.0.1 root MASTER_PORT 1 master-bin.002 276 slave-relay-bin.002 1522 master-bin.002 Yes Yes 0 0 276 1526
127.0.0.1 root MASTER_PORT 1 master-bin.002 276 slave-relay-bin.002 1563 master-bin.002 Yes Yes 0 0 276 1567
show binlog events in 'slave-bin.005' from 4;
Error when executing command SHOW BINLOG EVENTS: Could not find target log
......@@ -21,7 +21,7 @@ Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Lo
slave start;
show slave status;
Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
127.0.0.1 root MASTER_PORT 1 master-bin.001 73 slave-relay-bin.001 4 master-bin.001 No Yes 0 0 73 4
127.0.0.1 root MASTER_PORT 1 master-bin.001 73 slave-relay-bin.001 45 master-bin.001 No Yes 0 0 73 45
slave stop;
change master to master_log_pos=173;
slave start;
......
......@@ -5,7 +5,7 @@ Could not initialize master info structure, check permisions on master.info
slave start;
Could not initialize master info structure, check permisions on master.info
change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root';
Could not initialize master info
Could not initialize master info structure, check permisions on master.info
reset slave;
change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root';
reset master;
......
......@@ -26,3 +26,13 @@ ORDER BY link;
key_link_id link
NULL NULL
drop table t1,t2;
CREATE TABLE t1 (
html varchar(5) default NULL,
rin int(11) default '0',
out int(11) default '0'
) TYPE=MyISAM;
INSERT INTO t1 VALUES ('1',1,0);
SELECT DISTINCT html,SUM(out)/(SUM(rin)+1) as 'prod' FROM t1 GROUP BY rin;
html prod
1 0.00
drop table t1;
......@@ -125,3 +125,15 @@ CREATE TABLE t1 (id int(11) NOT NULL auto_increment, tmp text NOT NULL, KEY id (
INSERT INTO t1 VALUES (1, 'a545f661efdd1fb66fdee3aab79945bf');
SELECT 1 FROM t1 WHERE tmp=AES_DECRYPT(tmp,"password");
DROP TABLE t1;
CREATE TABLE t1 (
wid int(10) unsigned NOT NULL auto_increment,
data_podp date default NULL,
status_wnio enum('nowy','podp','real','arch') NOT NULL default 'nowy',
PRIMARY KEY(wid),
);
INSERT INTO t1 VALUES (8,NULL,'real');
INSERT INTO t1 VALUES (9,NULL,'nowy');
SELECT elt(status_wnio,data_podp) FROM t1 GROUP BY wid;
DROP TABLE t1;
......@@ -39,6 +39,10 @@ select yearweek("2000-01-06",1) as '2000', yearweek("2001-01-06",1) as '2001', y
select week(19981231,2), week(19981231,3), week(20000101,2), week(20000101,3);
select week(20001231,2),week(20001231,3);
set default_week_format = 2;
select week(20001231),week(20001231,2),week(20001231,0);
set default_week_format = 0;
select date_format('1998-12-31','%x-%v'),date_format('1999-01-01','%x-%v');
select date_format('1999-12-31','%x-%v'),date_format('2000-01-01','%x-%v');
......
--disable_warnings
drop table if exists t1;
--enable_warnings
#
# Test that SSL options works properly
#
......@@ -39,6 +43,32 @@ show grants for mysqltest_1@localhost;
revoke all privileges on mysqltest.* from mysqltest_1@localhost;
delete from mysql.user where user='mysqltest_1';
flush privileges;
grant usage on test.* to user@localhost with grant option;
show grants for user@localhost;
grant usage on test.* to mysqltest_1@localhost with grant option;
show grants for mysqltest_1@localhost;
delete from mysql.user where user='mysqltest_1';
delete from mysql.db where user='mysqltest_1';
delete from mysql.tables_priv where user='mysqltest_1';
delete from mysql.columns_priv where user='mysqltest_1';
flush privileges;
#
# Test what happens when you have same table and colum level grants
#
create table t1 (a int);
GRANT select,update,insert on t1 to mysqltest_1@localhost;
GRANT select (a), update (a),insert(a), references(a) on t1 to mysqltest_1@localhost;
show grants for mysqltest_1@localhost;
select table_priv,column_priv from mysql.tables_priv where user="mysqltest_1";
REVOKE select (a), update on t1 from mysqltest_1@localhost;
show grants for mysqltest_1@localhost;
REVOKE insert,insert (a) on t1 from mysqltest_1@localhost;
GRANT references on t1 to mysqltest_1@localhost;
show grants for mysqltest_1@localhost;
select table_priv,column_priv from mysql.tables_priv where user="mysqltest_1";
delete from mysql.user where user='mysqltest_1';
delete from mysql.db where user='mysqltest_1';
delete from mysql.tables_priv where user='mysqltest_1';
delete from mysql.columns_priv where user='mysqltest_1';
flush privileges;
drop table t1;
......@@ -16,14 +16,20 @@ system cat /dev/null > var/slave-data/master.info;
system chmod 000 var/slave-data/master.info;
connection slave;
drop table if exists t1, t2, t3, t4;
# START SLAVE will fail because it can't read the file (mode 000) (system error 13)
--error 1201
slave start;
system chmod 600 var/slave-data/master.info;
# It will fail again because the file is empty so the slave cannot get valuable
# info about how to connect to the master from it (failure in
# init_strvar_from_file() in init_master_info()).
--error 1201
slave start;
--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
# Will get error 13 on Unix systems becasue file is not readable
!eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root';
# CHANGE MASTER will fail because it first parses master.info before changing it
# (so when master.info is bad, people have to use RESET SLAVE first).
--error 1201
eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root';
reset slave;
--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root';
......@@ -73,12 +79,9 @@ insert into t2 values(1234);
#same value on the master
connection master;
save_master_pos;
set insert_id=1234;
insert into t2 values(NULL);
connection slave;
sync_with_master;
wait_for_slave_to_stop;
#restart slave skipping one event
......
......@@ -29,3 +29,18 @@ GROUP BY t1.id
ORDER BY link;
drop table t1,t2;
#
# test case for #674
#
CREATE TABLE t1 (
html varchar(5) default NULL,
rin int(11) default '0',
out int(11) default '0'
) TYPE=MyISAM;
INSERT INTO t1 VALUES ('1',1,0);
SELECT DISTINCT html,SUM(out)/(SUM(rin)+1) as 'prod' FROM t1 GROUP BY rin;
drop table t1;
......@@ -253,15 +253,27 @@ void symdirget(char *dir)
}
#endif /* USE_SYMDIR */
/* Unpacks dirname to name that can be used by open... */
/* Make that last char of to is '/' if from not empty and
from doesn't end in FN_DEVCHAR */
/* Uses cleanup_dirname and changes ~/.. to home_dir/.. */
/* Returns length of new directory */
uint unpack_dirname(my_string to, const char *from)
/*
Fixes a directroy name so that can be used by open()
SYNOPSIS
unpack_dirname()
to Store result here. May be = from
from 'Packed' directory name (may contain ~)
IMPLEMENTATION
Make that last char of to is '/' if from not empty and
from doesn't end in FN_DEVCHAR
Uses cleanup_dirname and changes ~/.. to home_dir/..
/* to may be == from */
Changes a UNIX filename to system filename (replaces / with \ on windows)
RETURN
Length of new directory name (= length of to)
*/
uint unpack_dirname(my_string to, const char *from)
{
uint length,h_length;
char buff[FN_REFLEN+1+4],*suffix,*tilde_expansion;
......
......@@ -114,8 +114,8 @@ sql_yacc.o: sql_yacc.cc sql_yacc.h
$(CXXCOMPILE) $(LM_CFLAGS) -c $<
lex_hash.h: lex.h gen_lex_hash.cc sql_yacc.h
$(MAKE) gen_lex_hash
./gen_lex_hash > $@
$(MAKE) gen_lex_hash$(EXEEXT)
./gen_lex_hash$(EXEEXT) > $@
# Hack to ensure that lex_hash.h is built early
sql_lex.o: lex_hash.h
......
......@@ -1863,7 +1863,11 @@ build_template(
if (prebuilt->read_just_key) {
/* MySQL has instructed us that it is enough to
fetch the columns in the key */
fetch the columns in the key; looks like MySQL
can set this flag also when there is only a
prefix of the column in the key: in that case we
retrieve the whole column from the clustered
index */
fetch_all_in_key = TRUE;
} else {
......@@ -1924,9 +1928,8 @@ build_template(
field = table->field[i];
if (templ_type == ROW_MYSQL_REC_FIELDS
&& !(fetch_all_in_key &&
ULINT_UNDEFINED != dict_index_get_nth_col_pos(
index, i))
&& !(fetch_all_in_key
&& dict_index_contains_col_or_prefix(index, i))
&& thd->query_id != field->query_id
&& thd->query_id != (field->query_id ^ MAX_ULONG_BIT)
&& thd->query_id !=
......@@ -4127,6 +4130,12 @@ ha_innobase::analyze(
return(0);
}
int ha_innobase::optimize(THD* thd, HA_CHECK_OPT* check_opt)
{
return ha_innobase::analyze(thd,check_opt);
}
/***********************************************************************
Tries to check that an InnoDB table is not corrupted. If corruption is
noticed, prints to stderr information about it. In case of corruption
......
......@@ -159,6 +159,7 @@ class ha_innobase: public handler
void position(const byte *record);
void info(uint);
int analyze(THD* thd,HA_CHECK_OPT* check_opt);
int optimize(THD* thd,HA_CHECK_OPT* check_opt);
int extra(enum ha_extra_function operation);
int reset(void);
int external_lock(THD *thd, int lock_type);
......
......@@ -1539,37 +1539,46 @@ void Item_func_elt::update_used_tables()
double Item_func_elt::val()
{
uint tmp;
null_value=1;
if ((tmp=(uint) item->val_int()) == 0 || tmp > arg_count)
{
null_value=1;
return 0.0;
}
double result= args[tmp-1]->val();
if (args[tmp-1]->is_null())
return 0.0;
null_value=0;
return args[tmp-1]->val();
return result;
}
longlong Item_func_elt::val_int()
{
uint tmp;
null_value=1;
if ((tmp=(uint) item->val_int()) == 0 || tmp > arg_count)
{
null_value=1;
return 0;
}
int result= args[tmp-1]->val_int();
if (args[tmp-1]->is_null())
return 0;
null_value=0;
return args[tmp-1]->val_int();
return result;
}
String *Item_func_elt::val_str(String *str)
{
uint tmp;
null_value=1;
if ((tmp=(uint) item->val_int()) == 0 || tmp > arg_count)
{
null_value=1;
return NULL;
}
String *result= args[tmp-1]->val_str(str);
if (args[tmp-1]->is_null())
return NULL;
null_value=0;
return args[tmp-1]->val_str(str);
return result;
}
......
......@@ -100,7 +100,7 @@ static void pretty_print_str(String* packet, char* str, int len)
static inline char* slave_load_file_stem(char*buf, uint file_id,
int event_server_id)
{
fn_format(buf,"SQL_LOAD-",slave_load_tmpdir,"",0); /* 4+32); */
fn_format(buf,"SQL_LOAD-",slave_load_tmpdir, "", MY_UNPACK_FILENAME);
buf = strend(buf);
buf = int10_to_str(::server_id, buf, 10);
*buf++ = '-';
......@@ -168,19 +168,22 @@ static void cleanup_load_tmpdir()
uint i;
if (!(dirp=my_dir(slave_load_tmpdir,MYF(MY_WME))))
return;
char fname[FN_REFLEN];
for (i=0 ; i < (uint)dirp->number_off_files; i++)
{
file=dirp->dir_entry+i;
if (is_prefix(file->name,"SQL_LOAD-"))
my_delete(file->name, MYF(0));
{
fn_format(fname,file->name,slave_load_tmpdir,"",MY_UNPACK_FILENAME);
my_delete(fname, MYF(0));
}
}
my_dirend(dirp);
}
#endif
Log_event::Log_event(const char* buf, bool old_format)
:temp_buf(0), cached_event_len(0), cache_stmt(0)
{
......@@ -813,7 +816,7 @@ Rotate_log_event::Rotate_log_event(const char* buf, int event_len,
int Rotate_log_event::write_data(IO_CACHE* file)
{
char buf[ROTATE_HEADER_LEN];
int8store(buf, pos + R_POS_OFFSET);
int8store(buf + R_POS_OFFSET, pos);
return (my_b_safe_write(file, (byte*)buf, ROTATE_HEADER_LEN) ||
my_b_safe_write(file, (byte*)new_log_ident, (uint) ident_len));
}
......
......@@ -2322,6 +2322,12 @@ The server will not act as a slave.");
opt_binlog_index_name,LOG_BIN);
using_update_log=1;
}
else if (opt_log_slave_updates)
{
sql_print_error("\
Warning: you need to use --log-bin to make --log-slave-updates work. \
Now disabling --log-slave-updates.");
}
if (opt_bootstrap)
{
......@@ -3179,7 +3185,8 @@ enum options {
OPT_BDB_CACHE_SIZE,
OPT_BDB_LOG_BUFFER_SIZE,
OPT_BDB_MAX_LOCK,
OPT_ERROR_LOG_FILE
OPT_ERROR_LOG_FILE,
OPT_DEFAULT_WEEK_FORMAT
};
......@@ -3988,6 +3995,11 @@ replicating a LOAD DATA INFILE command",
(gptr*) &global_system_variables.net_wait_timeout,
(gptr*) &max_system_variables.net_wait_timeout, 0, GET_ULONG,
REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
{ "default-week-format", OPT_DEFAULT_WEEK_FORMAT,
"The default week format used by WEEK() functions.",
(gptr*) &global_system_variables.default_week_format,
(gptr*) &max_system_variables.default_week_format,
0, GET_ULONG, REQUIRED_ARG, 0, 0, 3L, 0, 1, 0},
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
......
......@@ -462,7 +462,7 @@ BOOL NTService::SeekStatus(LPCSTR szInternName, int OperationType)
{
/* a remove operation */
if (!(service = OpenService(scm,szInternName, SERVICE_ALL_ACCESS )))
printf("The service doesn't exists!\n");
printf("The service doesn't exist!\n");
else
{
SERVICE_STATUS ss;
......
......@@ -296,6 +296,8 @@ static sys_var_slave_skip_counter sys_slave_skip_counter("sql_slave_skip_counter
static sys_var_rand_seed1 sys_rand_seed1("rand_seed1");
static sys_var_rand_seed2 sys_rand_seed2("rand_seed2");
static sys_var_thd_ulong sys_default_week_format("default_week_format",
&SV::default_week_format);
/*
List of all variables for initialisation and storage in hash
......@@ -316,6 +318,7 @@ sys_var *sys_variables[]=
&sys_bulk_insert_buff_size,
&sys_concurrent_insert,
&sys_connect_timeout,
&sys_default_week_format,
&sys_convert_charset,
&sys_delay_key_write,
&sys_delayed_insert_limit,
......@@ -421,6 +424,7 @@ struct show_var_st init_vars[]= {
{sys_connect_timeout.name, (char*) &sys_connect_timeout, SHOW_SYS},
{sys_convert_charset.name, (char*) &sys_convert_charset, SHOW_SYS},
{"datadir", mysql_real_data_home, SHOW_CHAR},
{"default_week_format", (char*) &sys_default_week_format, SHOW_SYS},
{sys_delay_key_write.name, (char*) &sys_delay_key_write, SHOW_SYS},
{sys_delayed_insert_limit.name, (char*) &sys_delayed_insert_limit,SHOW_SYS},
{sys_delayed_insert_timeout.name, (char*) &sys_delayed_insert_timeout, SHOW_SYS},
......
......@@ -134,7 +134,7 @@ int init_slave()
goto err;
}
if(init_master_info(active_mi,master_info_file,relay_log_info_file,
if (init_master_info(active_mi,master_info_file,relay_log_info_file,
!master_host))
{
sql_print_error("Failed to initialize the master info structure");
......@@ -1644,6 +1644,7 @@ int show_master_info(THD* thd, MASTER_INFO* mi)
if (mi->host[0])
{
DBUG_PRINT("info",("host is set: '%s'", mi->host));
String *packet= &thd->packet;
packet->length(0);
......@@ -1776,18 +1777,17 @@ int st_relay_log_info::wait_for_pos(THD* thd, String* log_name,
pthread_mutex_lock(&data_lock);
/*
This function will abort when it notices that
some CHANGE MASTER or RESET MASTER has changed
the master info. To catch this, these commands
modify abort_pos_wait ; we just monitor abort_pos_wait
and see if it has changed.
Why do we have this mechanism instead of simply monitoring slave_running in
the loop (we do this too), as CHANGE MASTER/RESET SLAVE require that the
SQL thread be stopped? This is in case
This function will abort when it notices that some CHANGE MASTER or
RESET MASTER has changed the master info.
To catch this, these commands modify abort_pos_wait ; We just monitor
abort_pos_wait and see if it has changed.
Why do we have this mechanism instead of simply monitoring slave_running
in the loop (we do this too), as CHANGE MASTER/RESET SLAVE require that
the SQL thread be stopped?
This is becasue if someones does:
STOP SLAVE;CHANGE MASTER/RESET SLAVE; START SLAVE;
happens very quickly between the moment pthread_cond_wait() wakes up and
the while() is evaluated: in that case slave_running is again 1 when the
while() is evaluated.
the change may happen very quickly and we may not notice that
slave_running briefly switches between 1/0/1.
*/
init_abort_pos_wait= abort_pos_wait;
......@@ -1808,7 +1808,7 @@ int st_relay_log_info::wait_for_pos(THD* thd, String* log_name,
error= -2; //means improper arguments
goto err;
}
//p points to '.'
/* p points to '.' */
log_name_extension= strtoul(++p, &p_end, 10);
/*
p_end points to the first invalid character.
......@@ -1821,14 +1821,9 @@ int st_relay_log_info::wait_for_pos(THD* thd, String* log_name,
goto err;
}
//"compare and wait" main loop
/* The "compare and wait" main loop */
while (!thd->killed &&
init_abort_pos_wait == abort_pos_wait &&
/*
formerly we tested mi->slave_running, but what we care about is
rli->slave_running (because this concerns the SQL thread, while
mi->slave_running concerns the I/O thread).
*/
slave_running)
{
bool pos_reached;
......
This diff is collapsed.
......@@ -76,8 +76,8 @@
#define get_rights_for_db(A) (((A) & 63) | (((A) & DB_CHUNK1) >> 4) | (((A) & DB_CHUNK2) >> 6))
#define fix_rights_for_table(A) (((A) & 63) | (((A) & ~63) << 4))
#define get_rights_for_table(A) (((A) & 63) | (((A) & ~63) >> 4))
#define fix_rights_for_column(A) (((A) & COL_ACLS) | ((A & ~COL_ACLS) << 7))
#define get_rights_for_column(A) (((A) & COL_ACLS) | ((A & ~COL_ACLS) >> 7))
#define fix_rights_for_column(A) (((A) & 7) | (((A) & ~7) << 8))
#define get_rights_for_column(A) (((A) & 7) | ((A) >> 8))
/* prototypes */
......
......@@ -309,6 +309,7 @@ struct system_variables
ulong tmp_table_size;
ulong tx_isolation;
ulong table_type;
ulong default_week_format;
my_bool log_warnings;
my_bool low_priority_updates;
......
......@@ -584,6 +584,11 @@ check_connections(THD *thd)
if (thd->client_capabilities & CLIENT_SSL)
{
/* Do the SSL layering. */
if (!ssl_acceptor_fd)
{
inc_host_errors(&thd->remote.sin_addr);
return(ER_HANDSHAKE_ERROR);
}
DBUG_PRINT("info", ("IO layer change in progress..."));
if (sslaccept(ssl_acceptor_fd, net->vio, thd->variables.net_wait_timeout))
{
......
......@@ -51,7 +51,7 @@ int check_binlog_magic(IO_CACHE* log, const char** errmsg)
}
static int fake_rotate_event(NET* net, String* packet, char* log_file_name,
const char**errmsg)
ulonglong position, const char**errmsg)
{
char header[LOG_EVENT_HEADER_LEN], buf[ROTATE_HEADER_LEN];
memset(header, 0, 4); // when does not matter
......@@ -68,9 +68,7 @@ static int fake_rotate_event(NET* net, String* packet, char* log_file_name,
int4store(header + LOG_POS_OFFSET, 0);
packet->append(header, sizeof(header));
/* We need to split the next statement because of problem with cxx */
int4store(buf,4); // tell slave to skip magic number
int4store(buf+4,0);
int8store(buf+R_POS_OFFSET,position);
packet->append(buf, ROTATE_HEADER_LEN);
packet->append(p,ident_len);
if (my_net_write(net, (char*)packet->ptr(), packet->length()))
......@@ -382,17 +380,30 @@ impossible position";
*/
packet->set("\0", 1);
// if we are at the start of the log
if (pos == BIN_LOG_HEADER_SIZE)
/*
Before 4.0.14 we called fake_rotate_event below only if
(pos == BIN_LOG_HEADER_SIZE), because if this is false then the slave
already knows the binlog's name.
Now we always call fake_rotate_event; if the slave already knew the log's
name (ex: CHANGE MASTER TO MASTER_LOG_FILE=...) this is useless but does not
harm much. It is nice for 3.23 (>=.58) slaves which test Rotate events
to see if the master is 4.0 (then they choose to stop because they can't
replicate 4.0); by always calling fake_rotate_event we are sure that 3.23.58
and newer will detect the problem as soon as replication starts (BUG#198).
Always calling fake_rotate_event makes sending of normal
(=from-binlog) Rotate events a priori unneeded, but it is not so simple: the
2 Rotate events are not equivalent, the normal one is before the Stop event,
the fake one is after. If we don't send the normal one, then the Stop event
will be interpreted (by existing 4.0 slaves) as "the master stopped", which
is wrong. So for safety, given that we want minimum modification of 4.0, we
send the normal and fake Rotates.
*/
if (fake_rotate_event(net, packet, log_file_name, pos, &errmsg))
{
// tell the client log name with a fake rotate_event
if (fake_rotate_event(net, packet, log_file_name, &errmsg))
{
my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
goto err;
}
packet->set("\0", 1);
my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
goto err;
}
packet->set("\0", 1);
while (!net->error && net->vio != 0 && !thd->killed)
{
......@@ -585,10 +596,12 @@ Increase max_allowed_packet on master";
end_io_cache(&log);
(void) my_close(file, MYF(MY_WME));
// fake Rotate_log event just in case it did not make it to the log
// otherwise the slave make get confused about the offset
/*
Even if the previous log contained a Rotate_log_event, we still fake
one.
*/
if ((file=open_binlog(&log, log_file_name, &errmsg)) < 0 ||
fake_rotate_event(net, packet, log_file_name, &errmsg))
fake_rotate_event(net, packet, log_file_name, BIN_LOG_HEADER_SIZE, &errmsg))
{
my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
goto err;
......@@ -828,7 +841,7 @@ int change_master(THD* thd, MASTER_INFO* mi)
// TODO: see if needs re-write
if (init_master_info(mi, master_info_file, relay_log_info_file, 0))
{
send_error(&thd->net, 0, "Could not initialize master info");
send_error(&thd->net, ER_MASTER_INFO);
unlock_slave_threads(mi);
DBUG_RETURN(1);
}
......
......@@ -453,6 +453,9 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
goto err;
thd->proc_info="preparing";
select_distinct= select_distinct && (join.const_tables != join.tables);
if (result->initialize_tables(&join))
goto err;
if (join.const_table_map != join.found_const_table_map &&
......@@ -1634,6 +1637,9 @@ add_key_part(DYNAMIC_ARRAY *keyuse_array,KEY_FIELD *key_field)
key_field->field->table->reginfo.not_exists_optimize=1;
}
#define FT_KEYPART (MAX_REF_PARTS+10)
static void
add_ft_keys(DYNAMIC_ARRAY *keyuse_array,
JOIN_TAB *stat,COND *cond,table_map usable_tables)
......@@ -1692,23 +1698,20 @@ add_ft_keys(DYNAMIC_ARRAY *keyuse_array,
}
}
if (!cond_func || cond_func->key == NO_SUCH_KEY)
return;
if (!(usable_tables & cond_func->table->map))
if ((!cond_func || cond_func->key == NO_SUCH_KEY) ||
(!(usable_tables & cond_func->table->map)))
return;
KEYUSE keyuse;
keyuse.table= cond_func->table;
keyuse.val = cond_func;
keyuse.key = cond_func->key;
#define FT_KEYPART (MAX_REF_PARTS+10)
keyuse.keypart=FT_KEYPART;
keyuse.keypart= FT_KEYPART;
keyuse.used_tables=cond_func->key_item()->used_tables();
VOID(insert_dynamic(keyuse_array,(gptr) &keyuse));
}
static int
sort_keyuse(KEYUSE *a,KEYUSE *b)
{
......
......@@ -2016,7 +2016,11 @@ simple_expr:
| USER '(' ')'
{ $$= new Item_func_user(); current_thd->safe_to_cache_query=0; }
| WEEK_SYM '(' expr ')'
{ $$= new Item_func_week($3,new Item_int((char*) "0",0,1)); }
{
LEX *lex=Lex;
$$= new Item_func_week($3,new Item_int((char*) "0",
lex->thd->variables.default_week_format,1));
}
| WEEK_SYM '(' expr ',' expr ')'
{ $$= new Item_func_week($3,$5); }
| YEAR_SYM '(' expr ')'
......
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