mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
Merge sinisa@bk-internal.mysql.com:/home/bk/mysql-4.0
into sinisa.nasamreza.org:/mnt/work/mysql-4.0 sql/sql_acl.cc: Auto merged sql/sql_parse.cc: Auto merged sql/sql_select.cc: Auto merged sql/sql_yacc.yy: Auto merged
This commit is contained in:
@@ -44,6 +44,7 @@ jorge@linux.jorge.mysql.com
|
|||||||
kaj@work.mysql.com
|
kaj@work.mysql.com
|
||||||
lenz@kallisto.mysql.com
|
lenz@kallisto.mysql.com
|
||||||
lenz@mysql.com
|
lenz@mysql.com
|
||||||
|
miguel@hegel.(none)
|
||||||
miguel@hegel.br
|
miguel@hegel.br
|
||||||
miguel@hegel.local
|
miguel@hegel.local
|
||||||
miguel@light.
|
miguel@light.
|
||||||
@@ -84,6 +85,7 @@ sasha@mysql.sashanet.com
|
|||||||
serg@build.mysql2.com
|
serg@build.mysql2.com
|
||||||
serg@serg.mylan
|
serg@serg.mylan
|
||||||
serg@serg.mysql.com
|
serg@serg.mysql.com
|
||||||
|
serg@sergbook.mylan
|
||||||
serg@sergbook.mysql.com
|
serg@sergbook.mysql.com
|
||||||
sinisa@rhols221.adsl.netsonic.fi
|
sinisa@rhols221.adsl.netsonic.fi
|
||||||
tfr@beta.frontier86.ee
|
tfr@beta.frontier86.ee
|
||||||
|
@@ -711,7 +711,7 @@ AC_DEFUN(MYSQL_FIND_OPENSSL, [
|
|||||||
done
|
done
|
||||||
|
|
||||||
for d in /usr/ssl/lib /usr/local/ssl/lib /usr/lib/openssl \
|
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
|
if test -f $d/libssl.a ; then
|
||||||
OPENSSL_LIB=$d
|
OPENSSL_LIB=$d
|
||||||
fi
|
fi
|
||||||
@@ -721,7 +721,7 @@ AC_DEFUN(MYSQL_FIND_OPENSSL, [
|
|||||||
echo "Could not find an installation of OpenSSL"
|
echo "Could not find an installation of OpenSSL"
|
||||||
if test -n "$OPENSSL_LIB" ; then
|
if test -n "$OPENSSL_LIB" ; then
|
||||||
if test "$IS_LINUX" = "true"; 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
|
||||||
fi
|
fi
|
||||||
exit 1
|
exit 1
|
||||||
|
@@ -396,8 +396,8 @@ static int check_header(IO_CACHE* file)
|
|||||||
if (buf[4] == START_EVENT)
|
if (buf[4] == START_EVENT)
|
||||||
{
|
{
|
||||||
uint event_len;
|
uint event_len;
|
||||||
event_len = uint4korr(buf + 4);
|
event_len = uint4korr(buf + EVENT_LEN_OFFSET);
|
||||||
old_format = (event_len < LOG_EVENT_HEADER_LEN + START_HEADER_LEN);
|
old_format = (event_len < (LOG_EVENT_HEADER_LEN + START_HEADER_LEN));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
my_b_seek(file, pos);
|
my_b_seek(file, pos);
|
||||||
|
@@ -757,7 +757,7 @@ AC_CHECK_LIB(crypt, crypt)
|
|||||||
AC_CHECK_FUNC(crypt, AC_DEFINE(HAVE_CRYPT))
|
AC_CHECK_FUNC(crypt, AC_DEFINE(HAVE_CRYPT))
|
||||||
|
|
||||||
# For sem_xxx functions on Solaris 2.6
|
# 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
|
# For compress in zlib
|
||||||
MYSQL_CHECK_ZLIB_WITH_COMPRESS($with_named_zlib)
|
MYSQL_CHECK_ZLIB_WITH_COMPRESS($with_named_zlib)
|
||||||
|
@@ -494,6 +494,46 @@ dict_index_get_nth_col_pos(
|
|||||||
return(ULINT_UNDEFINED);
|
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
|
Looks for a matching field in an index. The column and the prefix len have
|
||||||
to be the same. */
|
to be the same. */
|
||||||
|
@@ -569,6 +569,16 @@ dict_index_get_nth_col_pos(
|
|||||||
dict_index_t* index, /* in: index */
|
dict_index_t* index, /* in: index */
|
||||||
ulint n); /* in: column number */
|
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
|
Looks for a matching field in an index. The column and the prefix len has
|
||||||
to be the same. */
|
to be the same. */
|
||||||
|
|
||||||
|
@@ -446,7 +446,6 @@ page_copy_rec_list_end_no_locks(
|
|||||||
page_cur_move_to_next(&cur1);
|
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);
|
ut_a(mach_read_from_2(new_page + UNIV_PAGE_SIZE - 10) == PAGE_INFIMUM);
|
||||||
|
|
||||||
page_cur_set_before_first(new_page, &cur2);
|
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);
|
sup = page_get_supremum_rec(page);
|
||||||
|
|
||||||
while (sup != page_cur_get_rec(&cur1)) {
|
while (sup != page_cur_get_rec(&cur1)) {
|
||||||
ut_a(
|
if (!page_cur_rec_insert(&cur2,
|
||||||
page_cur_rec_insert(&cur2, page_cur_get_rec(&cur1), mtr));
|
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(&cur1);
|
||||||
page_cur_move_to_next(&cur2);
|
page_cur_move_to_next(&cur2);
|
||||||
}
|
}
|
||||||
|
@@ -791,27 +791,30 @@ row_ins_foreign_check_on_constraint(
|
|||||||
mem_heap_free(tmp_heap);
|
mem_heap_free(tmp_heap);
|
||||||
|
|
||||||
clust_rec = btr_pcur_get_rec(cascade->pcur);
|
clust_rec = btr_pcur_get_rec(cascade->pcur);
|
||||||
}
|
|
||||||
|
|
||||||
if (!page_rec_is_user_rec(clust_rec)) {
|
if (!page_rec_is_user_rec(clust_rec)
|
||||||
fprintf(stderr,
|
|| 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: error in cascade of a foreign key op\n"
|
||||||
"InnoDB: index %s table %s\n", index->name,
|
"InnoDB: index %s table %s\n", index->name,
|
||||||
index->table->name);
|
index->table->name);
|
||||||
|
|
||||||
rec_sprintf(err_buf, 900, rec);
|
rec_sprintf(err_buf, 900, rec);
|
||||||
fprintf(stderr, "InnoDB: record %s\n", err_buf);
|
fprintf(stderr, "InnoDB: record %s\n", err_buf);
|
||||||
|
|
||||||
rec_sprintf(err_buf, 900, clust_rec);
|
rec_sprintf(err_buf, 900, clust_rec);
|
||||||
fprintf(stderr, "InnoDB: clustered record %s\n", err_buf);
|
fprintf(stderr, "InnoDB: clustered record %s\n",
|
||||||
|
err_buf);
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"InnoDB: Make a detailed bug report and send it\n");
|
"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 */
|
/* 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));
|
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) {
|
if (!node->read_view) {
|
||||||
/* Try to place a lock on the index record */
|
/* 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,
|
row_sel_fetch_columns(index, clust_rec,
|
||||||
UT_LIST_GET_FIRST(plan->columns));
|
UT_LIST_GET_FIRST(plan->columns));
|
||||||
|
func_exit:
|
||||||
*out_rec = clust_rec;
|
*out_rec = clust_rec;
|
||||||
|
|
||||||
return(DB_SUCCESS);
|
return(DB_SUCCESS);
|
||||||
@@ -1253,6 +1276,8 @@ rec_loop:
|
|||||||
|
|
||||||
/* PHASE 3: Get previous version in a consistent read */
|
/* PHASE 3: Get previous version in a consistent read */
|
||||||
|
|
||||||
|
cons_read_requires_clust_rec = FALSE;
|
||||||
|
|
||||||
if (consistent_read) {
|
if (consistent_read) {
|
||||||
/* This is a non-locking consistent read: if necessary, fetch
|
/* This is a non-locking consistent read: if necessary, fetch
|
||||||
a previous version of the record */
|
a previous version of the record */
|
||||||
@@ -2269,7 +2294,10 @@ row_sel_get_clust_rec_for_mysql(
|
|||||||
/* out: DB_SUCCESS or error code */
|
/* out: DB_SUCCESS or error code */
|
||||||
row_prebuilt_t* prebuilt,/* in: prebuilt struct in the handle */
|
row_prebuilt_t* prebuilt,/* in: prebuilt struct in the handle */
|
||||||
dict_index_t* sec_index,/* in: secondary index where rec resides */
|
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 */
|
que_thr_t* thr, /* in: query thread */
|
||||||
rec_t** out_rec,/* out: clustered record or an old version of
|
rec_t** out_rec,/* out: clustered record or an old version of
|
||||||
it, NULL if the old version did not exist
|
it, NULL if the old version did not exist
|
||||||
@@ -2285,7 +2313,7 @@ row_sel_get_clust_rec_for_mysql(
|
|||||||
ulint err;
|
ulint err;
|
||||||
trx_t* trx;
|
trx_t* trx;
|
||||||
char err_buf[1000];
|
char err_buf[1000];
|
||||||
|
|
||||||
*out_rec = NULL;
|
*out_rec = NULL;
|
||||||
|
|
||||||
row_build_row_ref_in_tuple(prebuilt->clust_ref, sec_index, rec);
|
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);
|
clust_rec = btr_pcur_get_rec(prebuilt->clust_pcur);
|
||||||
|
|
||||||
if (!page_rec_is_user_rec(clust_rec)) {
|
/* Note: only if the search ends up on a non-infimum record is the
|
||||||
ut_print_timestamp(stderr);
|
low_match value the real match to the search tuple */
|
||||||
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);
|
if (!page_rec_is_user_rec(clust_rec)
|
||||||
fprintf(stderr, "InnoDB: sec index record %s\n", err_buf);
|
|| 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);
|
if (!rec_get_deleted_flag(rec)
|
||||||
fprintf(stderr, "InnoDB: clust index record %s\n", err_buf);
|
|| prebuilt->select_lock_type != LOCK_NONE) {
|
||||||
|
|
||||||
trx = thr_get_trx(thr);
|
ut_print_timestamp(stderr);
|
||||||
trx_print(err_buf, trx);
|
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);
|
||||||
|
|
||||||
fprintf(stderr,
|
rec_sprintf(err_buf, 900, rec);
|
||||||
"%s\nInnoDB: Make a detailed bug report and send it\n",
|
fprintf(stderr,
|
||||||
err_buf);
|
"InnoDB: sec index record %s\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;
|
clust_rec = NULL;
|
||||||
|
|
||||||
@@ -2989,8 +3038,6 @@ rec_loop:
|
|||||||
/*-------------------------------------------------------------*/
|
/*-------------------------------------------------------------*/
|
||||||
/* PHASE 4: Look for matching records in a loop */
|
/* PHASE 4: Look for matching records in a loop */
|
||||||
|
|
||||||
cons_read_requires_clust_rec = FALSE;
|
|
||||||
|
|
||||||
rec = btr_pcur_get_rec(pcur);
|
rec = btr_pcur_get_rec(pcur);
|
||||||
/*
|
/*
|
||||||
printf("Using index %s cnt %lu ", index->name, cnt);
|
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
|
/* We are ready to look at a possible new index entry in the result
|
||||||
set: the cursor is now placed on a user record */
|
set: the cursor is now placed on a user record */
|
||||||
|
|
||||||
|
cons_read_requires_clust_rec = FALSE;
|
||||||
|
|
||||||
if (prebuilt->select_lock_type != LOCK_NONE) {
|
if (prebuilt->select_lock_type != LOCK_NONE) {
|
||||||
/* Try to place a lock on the index record; note that delete
|
/* Try to place a lock on the index record; note that delete
|
||||||
marked records are a special case in a unique search. If there
|
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
|
/* This is a non-locking consistent read: if necessary, fetch
|
||||||
a previous version of the record */
|
a previous version of the record */
|
||||||
|
|
||||||
cons_read_requires_clust_rec = FALSE;
|
|
||||||
|
|
||||||
if (trx->isolation_level == TRX_ISO_READ_UNCOMMITTED) {
|
if (trx->isolation_level == TRX_ISO_READ_UNCOMMITTED) {
|
||||||
|
|
||||||
/* Do nothing: we let a non-locking SELECT read the
|
/* 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) {
|
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
|
not a consistent read which might see an earlier version
|
||||||
of a non-clustered index record */
|
of a non-clustered index record */
|
||||||
|
|
||||||
@@ -3324,7 +3371,7 @@ got_row:
|
|||||||
goto normal_return;
|
goto normal_return;
|
||||||
|
|
||||||
next_rec:
|
next_rec:
|
||||||
/*-------------------------------------------------------------*/
|
/*-------------------------------------------------------------*/
|
||||||
/* PHASE 5: Move the cursor to the next index record */
|
/* PHASE 5: Move the cursor to the next index record */
|
||||||
|
|
||||||
if (mtr_has_extra_clust_latch) {
|
if (mtr_has_extra_clust_latch) {
|
||||||
|
@@ -59,7 +59,6 @@ row_vers_impl_x_locked_off_kernel(
|
|||||||
ibool rec_del;
|
ibool rec_del;
|
||||||
ulint err;
|
ulint err;
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
char err_buf[1000];
|
|
||||||
|
|
||||||
ut_ad(mutex_own(&kernel_mutex));
|
ut_ad(mutex_own(&kernel_mutex));
|
||||||
ut_ad(!rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED));
|
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_rec = row_get_clust_rec(BTR_SEARCH_LEAF, rec, index,
|
||||||
&clust_index, &mtr);
|
&clust_index, &mtr);
|
||||||
if (!clust_rec) {
|
if (!clust_rec) {
|
||||||
rec_sprintf(err_buf, 900, rec);
|
/* 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. */
|
||||||
|
|
||||||
ut_print_timestamp(stderr);
|
mutex_enter(&kernel_mutex);
|
||||||
fprintf(stderr,
|
mtr_commit(&mtr);
|
||||||
" 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 */
|
|
||||||
|
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
@@ -40,14 +40,17 @@
|
|||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#ifdef HAVE_SELECT_H
|
#ifdef HAVE_SELECT_H
|
||||||
# include <select.h>
|
#include <select.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_SYS_SELECT_H
|
#ifdef HAVE_SYS_SELECT_H
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_POLL
|
||||||
|
#include <sys/poll.h>
|
||||||
#endif
|
#endif
|
||||||
|
#endif /* !defined(MSDOS) && !defined(__WIN__) */
|
||||||
#ifdef HAVE_SYS_UN_H
|
#ifdef HAVE_SYS_UN_H
|
||||||
# include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#endif
|
#endif
|
||||||
#if defined(THREAD) && !defined(__WIN__)
|
#if defined(THREAD) && !defined(__WIN__)
|
||||||
#include <my_pthread.h> /* because of signal() */
|
#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* user,
|
||||||
const char* passwd);
|
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
|
a timeout value, in seconds, that we should wait until we
|
||||||
derermine we can't connect to a particular host. If timeout is 0,
|
derermine we can't connect to a particular host. If timeout is 0,
|
||||||
my_connect() will behave exactly like connect().
|
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>
|
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)
|
uint timeout)
|
||||||
{
|
{
|
||||||
#if defined(__WIN__) || defined(OS2) || defined(__NETWARE__)
|
#if defined(__WIN__) || defined(OS2) || defined(__NETWARE__)
|
||||||
return connect(s, (struct sockaddr*) name, namelen);
|
return connect(fd, (struct sockaddr*) name, namelen);
|
||||||
#else
|
#else
|
||||||
int flags, res, s_err;
|
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
|
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)
|
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
|
#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
|
#endif
|
||||||
|
|
||||||
res = connect(s, (struct sockaddr*) name, namelen);
|
res= connect(fd, (struct sockaddr*) name, namelen);
|
||||||
s_err = errno; /* Save the error... */
|
s_err= errno; /* Save the error... */
|
||||||
fcntl(s, F_SETFL, flags);
|
fcntl(fd, F_SETFL, flags);
|
||||||
if ((res != 0) && (s_err != EINPROGRESS))
|
if ((res != 0) && (s_err != EINPROGRESS))
|
||||||
{
|
{
|
||||||
errno = s_err; /* Restore it */
|
errno= s_err; /* Restore it */
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
if (res == 0) /* Connected quickly! */
|
if (res == 0) /* Connected quickly! */
|
||||||
return(0);
|
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
|
Our connection is "in progress." We can use the select() call to wait
|
||||||
the select() call to wait up to a specified period of time
|
up to a specified period of time for the connection to suceed.
|
||||||
for the connection to suceed. If select() returns 0
|
If select() returns 0 (after waiting howevermany seconds), our socket
|
||||||
(after waiting howevermany seconds), our socket never became
|
never became writable (host is probably unreachable.) Otherwise, if
|
||||||
writable (host is probably unreachable.) Otherwise, if
|
|
||||||
select() returns 1, then one of two conditions exist:
|
select() returns 1, then one of two conditions exist:
|
||||||
|
|
||||||
1. An error occured. We use getsockopt() to check for this.
|
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_ZERO(&sfds);
|
||||||
FD_SET(s, &sfds);
|
FD_SET(fd, &sfds);
|
||||||
/*
|
/*
|
||||||
select could be interrupted by a signal, and if it is,
|
select could be interrupted by a signal, and if it is,
|
||||||
the timeout should be adjusted and the select restarted
|
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_sec = (long) timeout;
|
||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
#if defined(HPUX10) && defined(THREAD)
|
#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;
|
break;
|
||||||
#else
|
#else
|
||||||
if ((res = select(s+1, NULL, &sfds, NULL, &tv)) > 0)
|
if ((res = select(fd+1, NULL, &sfds, NULL, &tv)) > 0)
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
if (res == 0) /* timeout */
|
if (res == 0) /* timeout */
|
||||||
@@ -247,7 +287,7 @@ int my_connect(my_socket s, const struct sockaddr *name, uint namelen,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
s_err=0;
|
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);
|
return(-1);
|
||||||
|
|
||||||
if (s_err)
|
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(-1); /* but return an error... */
|
||||||
}
|
}
|
||||||
return (0); /* ok */
|
return (0); /* ok */
|
||||||
|
#endif /* HAVE_POLL */
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif /* defined(__WIN__) || defined(OS2) || defined(__NETWARE__) */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Create a named pipe connection
|
Create a named pipe connection
|
||||||
|
@@ -569,7 +569,9 @@ error () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
error_is () {
|
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() {
|
prefix_to_8() {
|
||||||
|
@@ -234,3 +234,16 @@ INSERT INTO t1 VALUES (1, 'a545f661efdd1fb66fdee3aab79945bf');
|
|||||||
SELECT 1 FROM t1 WHERE tmp=AES_DECRYPT(tmp,"password");
|
SELECT 1 FROM t1 WHERE tmp=AES_DECRYPT(tmp,"password");
|
||||||
1
|
1
|
||||||
DROP TABLE t1;
|
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);
|
select week(20001231,2),week(20001231,3);
|
||||||
week(20001231,2) week(20001231,3)
|
week(20001231,2) week(20001231,3)
|
||||||
1 52
|
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');
|
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')
|
date_format('1998-12-31','%x-%v') date_format('1999-01-01','%x-%v')
|
||||||
1998-53 1998-53
|
1998-53 1998-53
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
drop table if exists t1;
|
||||||
delete from mysql.user where user='mysqltest_1';
|
delete from mysql.user where user='mysqltest_1';
|
||||||
delete from mysql.db where user='mysqltest_1';
|
delete from mysql.db where user='mysqltest_1';
|
||||||
flush privileges;
|
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;
|
revoke all privileges on mysqltest.* from mysqltest_1@localhost;
|
||||||
delete from mysql.user where user='mysqltest_1';
|
delete from mysql.user where user='mysqltest_1';
|
||||||
flush privileges;
|
flush privileges;
|
||||||
grant usage on test.* to user@localhost with grant option;
|
grant usage on test.* to mysqltest_1@localhost with grant option;
|
||||||
show grants for user@localhost;
|
show grants for mysqltest_1@localhost;
|
||||||
Grants for user@localhost
|
Grants for mysqltest_1@localhost
|
||||||
GRANT USAGE ON *.* TO 'user'@'localhost'
|
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
|
||||||
GRANT USAGE ON `test`.* TO 'user'@'localhost' WITH GRANT OPTION
|
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
|
1 1007 101
|
||||||
optimize table t1;
|
optimize table t1;
|
||||||
Table Op Msg_type Msg_text
|
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;
|
show keys from t1;
|
||||||
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
|
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
|
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);
|
insert into t1 values (1), (2);
|
||||||
optimize table t1;
|
optimize table t1;
|
||||||
Table Op Msg_type Msg_text
|
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;
|
delete from t1 where a = 1;
|
||||||
select * from t1;
|
select * from t1;
|
||||||
a
|
a
|
||||||
@@ -712,7 +712,7 @@ world 2
|
|||||||
hello 1
|
hello 1
|
||||||
optimize table t1;
|
optimize table t1;
|
||||||
Table Op Msg_type Msg_text
|
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;
|
show keys from t1;
|
||||||
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
|
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
|
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;
|
update t1 set c=a;
|
||||||
explain select * from t1 where c between 1 and 10000;
|
explain select * from t1 where c between 1 and 10000;
|
||||||
table type possible_keys key key_len ref rows Extra
|
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;
|
drop table t1,t2;
|
||||||
create table t1 (id int primary key auto_increment, fk int, index index_fk (fk)) type=innodb;
|
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);
|
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
|
slave-bin.002 122 Query 1 228 use test; drop table t1
|
||||||
show slave status;
|
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
|
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;
|
show binlog events in 'slave-bin.005' from 4;
|
||||||
Error when executing command SHOW BINLOG EVENTS: Could not find target log
|
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;
|
slave start;
|
||||||
show slave status;
|
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
|
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;
|
slave stop;
|
||||||
change master to master_log_pos=173;
|
change master to master_log_pos=173;
|
||||||
slave start;
|
slave start;
|
||||||
|
@@ -5,7 +5,7 @@ Could not initialize master info structure, check permisions on master.info
|
|||||||
slave start;
|
slave start;
|
||||||
Could not initialize master info structure, check permisions on master.info
|
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';
|
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;
|
reset slave;
|
||||||
change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root';
|
change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root';
|
||||||
reset master;
|
reset master;
|
||||||
|
@@ -26,3 +26,13 @@ ORDER BY link;
|
|||||||
key_link_id link
|
key_link_id link
|
||||||
NULL NULL
|
NULL NULL
|
||||||
drop table t1,t2;
|
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');
|
INSERT INTO t1 VALUES (1, 'a545f661efdd1fb66fdee3aab79945bf');
|
||||||
SELECT 1 FROM t1 WHERE tmp=AES_DECRYPT(tmp,"password");
|
SELECT 1 FROM t1 WHERE tmp=AES_DECRYPT(tmp,"password");
|
||||||
DROP TABLE t1;
|
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(19981231,2), week(19981231,3), week(20000101,2), week(20000101,3);
|
||||||
select week(20001231,2),week(20001231,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('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');
|
select date_format('1999-12-31','%x-%v'),date_format('2000-01-01','%x-%v');
|
||||||
|
|
||||||
|
@@ -1,3 +1,7 @@
|
|||||||
|
--disable_warnings
|
||||||
|
drop table if exists t1;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
#
|
#
|
||||||
# Test that SSL options works properly
|
# 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;
|
revoke all privileges on mysqltest.* from mysqltest_1@localhost;
|
||||||
delete from mysql.user where user='mysqltest_1';
|
delete from mysql.user where user='mysqltest_1';
|
||||||
flush privileges;
|
flush privileges;
|
||||||
grant usage on test.* to user@localhost with grant option;
|
grant usage on test.* to mysqltest_1@localhost with grant option;
|
||||||
show grants for user@localhost;
|
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;
|
system chmod 000 var/slave-data/master.info;
|
||||||
connection slave;
|
connection slave;
|
||||||
drop table if exists t1, t2, t3, t4;
|
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
|
--error 1201
|
||||||
slave start;
|
slave start;
|
||||||
system chmod 600 var/slave-data/master.info;
|
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
|
--error 1201
|
||||||
slave start;
|
slave start;
|
||||||
--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
|
--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
|
# CHANGE MASTER will fail because it first parses master.info before changing it
|
||||||
!eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root';
|
# (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;
|
reset slave;
|
||||||
--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
|
--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';
|
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
|
#same value on the master
|
||||||
connection master;
|
connection master;
|
||||||
save_master_pos;
|
|
||||||
set insert_id=1234;
|
set insert_id=1234;
|
||||||
insert into t2 values(NULL);
|
insert into t2 values(NULL);
|
||||||
connection slave;
|
connection slave;
|
||||||
sync_with_master;
|
|
||||||
|
|
||||||
wait_for_slave_to_stop;
|
wait_for_slave_to_stop;
|
||||||
|
|
||||||
#restart slave skipping one event
|
#restart slave skipping one event
|
||||||
|
@@ -29,3 +29,18 @@ GROUP BY t1.id
|
|||||||
ORDER BY link;
|
ORDER BY link;
|
||||||
|
|
||||||
drop table t1,t2;
|
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 */
|
#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 */
|
Fixes a directroy name so that can be used by open()
|
||||||
/* Uses cleanup_dirname and changes ~/.. to home_dir/.. */
|
|
||||||
/* Returns length of new directory */
|
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/..
|
||||||
|
|
||||||
|
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 unpack_dirname(my_string to, const char *from)
|
||||||
|
|
||||||
/* to may be == from */
|
|
||||||
{
|
{
|
||||||
uint length,h_length;
|
uint length,h_length;
|
||||||
char buff[FN_REFLEN+1+4],*suffix,*tilde_expansion;
|
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 $<
|
$(CXXCOMPILE) $(LM_CFLAGS) -c $<
|
||||||
|
|
||||||
lex_hash.h: lex.h gen_lex_hash.cc sql_yacc.h
|
lex_hash.h: lex.h gen_lex_hash.cc sql_yacc.h
|
||||||
$(MAKE) gen_lex_hash
|
$(MAKE) gen_lex_hash$(EXEEXT)
|
||||||
./gen_lex_hash > $@
|
./gen_lex_hash$(EXEEXT) > $@
|
||||||
|
|
||||||
# Hack to ensure that lex_hash.h is built early
|
# Hack to ensure that lex_hash.h is built early
|
||||||
sql_lex.o: lex_hash.h
|
sql_lex.o: lex_hash.h
|
||||||
|
@@ -1863,7 +1863,11 @@ build_template(
|
|||||||
|
|
||||||
if (prebuilt->read_just_key) {
|
if (prebuilt->read_just_key) {
|
||||||
/* MySQL has instructed us that it is enough to
|
/* 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;
|
fetch_all_in_key = TRUE;
|
||||||
} else {
|
} else {
|
||||||
@@ -1924,9 +1928,8 @@ build_template(
|
|||||||
field = table->field[i];
|
field = table->field[i];
|
||||||
|
|
||||||
if (templ_type == ROW_MYSQL_REC_FIELDS
|
if (templ_type == ROW_MYSQL_REC_FIELDS
|
||||||
&& !(fetch_all_in_key &&
|
&& !(fetch_all_in_key
|
||||||
ULINT_UNDEFINED != dict_index_get_nth_col_pos(
|
&& dict_index_contains_col_or_prefix(index, i))
|
||||||
index, i))
|
|
||||||
&& thd->query_id != field->query_id
|
&& thd->query_id != field->query_id
|
||||||
&& thd->query_id != (field->query_id ^ MAX_ULONG_BIT)
|
&& thd->query_id != (field->query_id ^ MAX_ULONG_BIT)
|
||||||
&& thd->query_id !=
|
&& thd->query_id !=
|
||||||
@@ -4127,6 +4130,12 @@ ha_innobase::analyze(
|
|||||||
return(0);
|
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
|
Tries to check that an InnoDB table is not corrupted. If corruption is
|
||||||
noticed, prints to stderr information about it. In case of corruption
|
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 position(const byte *record);
|
||||||
void info(uint);
|
void info(uint);
|
||||||
int analyze(THD* thd,HA_CHECK_OPT* check_opt);
|
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 extra(enum ha_extra_function operation);
|
||||||
int reset(void);
|
int reset(void);
|
||||||
int external_lock(THD *thd, int lock_type);
|
int external_lock(THD *thd, int lock_type);
|
||||||
|
@@ -1539,37 +1539,46 @@ void Item_func_elt::update_used_tables()
|
|||||||
double Item_func_elt::val()
|
double Item_func_elt::val()
|
||||||
{
|
{
|
||||||
uint tmp;
|
uint tmp;
|
||||||
|
null_value=1;
|
||||||
if ((tmp=(uint) item->val_int()) == 0 || tmp > arg_count)
|
if ((tmp=(uint) item->val_int()) == 0 || tmp > arg_count)
|
||||||
{
|
|
||||||
null_value=1;
|
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
|
||||||
|
double result= args[tmp-1]->val();
|
||||||
|
if (args[tmp-1]->is_null())
|
||||||
|
return 0.0;
|
||||||
|
|
||||||
null_value=0;
|
null_value=0;
|
||||||
return args[tmp-1]->val();
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
longlong Item_func_elt::val_int()
|
longlong Item_func_elt::val_int()
|
||||||
{
|
{
|
||||||
uint tmp;
|
uint tmp;
|
||||||
|
null_value=1;
|
||||||
if ((tmp=(uint) item->val_int()) == 0 || tmp > arg_count)
|
if ((tmp=(uint) item->val_int()) == 0 || tmp > arg_count)
|
||||||
{
|
|
||||||
null_value=1;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
int result= args[tmp-1]->val_int();
|
||||||
|
if (args[tmp-1]->is_null())
|
||||||
|
return 0;
|
||||||
|
|
||||||
null_value=0;
|
null_value=0;
|
||||||
return args[tmp-1]->val_int();
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
String *Item_func_elt::val_str(String *str)
|
String *Item_func_elt::val_str(String *str)
|
||||||
{
|
{
|
||||||
uint tmp;
|
uint tmp;
|
||||||
|
null_value=1;
|
||||||
if ((tmp=(uint) item->val_int()) == 0 || tmp > arg_count)
|
if ((tmp=(uint) item->val_int()) == 0 || tmp > arg_count)
|
||||||
{
|
|
||||||
null_value=1;
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
String *result= args[tmp-1]->val_str(str);
|
||||||
|
if (args[tmp-1]->is_null())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
null_value=0;
|
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,
|
static inline char* slave_load_file_stem(char*buf, uint file_id,
|
||||||
int event_server_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 = strend(buf);
|
||||||
buf = int10_to_str(::server_id, buf, 10);
|
buf = int10_to_str(::server_id, buf, 10);
|
||||||
*buf++ = '-';
|
*buf++ = '-';
|
||||||
@@ -168,19 +168,22 @@ static void cleanup_load_tmpdir()
|
|||||||
uint i;
|
uint i;
|
||||||
if (!(dirp=my_dir(slave_load_tmpdir,MYF(MY_WME))))
|
if (!(dirp=my_dir(slave_load_tmpdir,MYF(MY_WME))))
|
||||||
return;
|
return;
|
||||||
|
char fname[FN_REFLEN];
|
||||||
for (i=0 ; i < (uint)dirp->number_off_files; i++)
|
for (i=0 ; i < (uint)dirp->number_off_files; i++)
|
||||||
{
|
{
|
||||||
file=dirp->dir_entry+i;
|
file=dirp->dir_entry+i;
|
||||||
if (is_prefix(file->name,"SQL_LOAD-"))
|
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);
|
my_dirend(dirp);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
Log_event::Log_event(const char* buf, bool old_format)
|
Log_event::Log_event(const char* buf, bool old_format)
|
||||||
:temp_buf(0), cached_event_len(0), cache_stmt(0)
|
: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)
|
int Rotate_log_event::write_data(IO_CACHE* file)
|
||||||
{
|
{
|
||||||
char buf[ROTATE_HEADER_LEN];
|
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) ||
|
return (my_b_safe_write(file, (byte*)buf, ROTATE_HEADER_LEN) ||
|
||||||
my_b_safe_write(file, (byte*)new_log_ident, (uint) ident_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);
|
opt_binlog_index_name,LOG_BIN);
|
||||||
using_update_log=1;
|
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)
|
if (opt_bootstrap)
|
||||||
{
|
{
|
||||||
@@ -3179,7 +3185,8 @@ enum options {
|
|||||||
OPT_BDB_CACHE_SIZE,
|
OPT_BDB_CACHE_SIZE,
|
||||||
OPT_BDB_LOG_BUFFER_SIZE,
|
OPT_BDB_LOG_BUFFER_SIZE,
|
||||||
OPT_BDB_MAX_LOCK,
|
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*) &global_system_variables.net_wait_timeout,
|
||||||
(gptr*) &max_system_variables.net_wait_timeout, 0, GET_ULONG,
|
(gptr*) &max_system_variables.net_wait_timeout, 0, GET_ULONG,
|
||||||
REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
|
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}
|
{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 */
|
/* a remove operation */
|
||||||
if (!(service = OpenService(scm,szInternName, SERVICE_ALL_ACCESS )))
|
if (!(service = OpenService(scm,szInternName, SERVICE_ALL_ACCESS )))
|
||||||
printf("The service doesn't exists!\n");
|
printf("The service doesn't exist!\n");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SERVICE_STATUS ss;
|
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_seed1 sys_rand_seed1("rand_seed1");
|
||||||
static sys_var_rand_seed2 sys_rand_seed2("rand_seed2");
|
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
|
List of all variables for initialisation and storage in hash
|
||||||
@@ -316,6 +318,7 @@ sys_var *sys_variables[]=
|
|||||||
&sys_bulk_insert_buff_size,
|
&sys_bulk_insert_buff_size,
|
||||||
&sys_concurrent_insert,
|
&sys_concurrent_insert,
|
||||||
&sys_connect_timeout,
|
&sys_connect_timeout,
|
||||||
|
&sys_default_week_format,
|
||||||
&sys_convert_charset,
|
&sys_convert_charset,
|
||||||
&sys_delay_key_write,
|
&sys_delay_key_write,
|
||||||
&sys_delayed_insert_limit,
|
&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_connect_timeout.name, (char*) &sys_connect_timeout, SHOW_SYS},
|
||||||
{sys_convert_charset.name, (char*) &sys_convert_charset, SHOW_SYS},
|
{sys_convert_charset.name, (char*) &sys_convert_charset, SHOW_SYS},
|
||||||
{"datadir", mysql_real_data_home, SHOW_CHAR},
|
{"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_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_limit.name, (char*) &sys_delayed_insert_limit,SHOW_SYS},
|
||||||
{sys_delayed_insert_timeout.name, (char*) &sys_delayed_insert_timeout, SHOW_SYS},
|
{sys_delayed_insert_timeout.name, (char*) &sys_delayed_insert_timeout, SHOW_SYS},
|
||||||
|
33
sql/slave.cc
33
sql/slave.cc
@@ -134,7 +134,7 @@ int init_slave()
|
|||||||
goto err;
|
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))
|
!master_host))
|
||||||
{
|
{
|
||||||
sql_print_error("Failed to initialize the master info structure");
|
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])
|
if (mi->host[0])
|
||||||
{
|
{
|
||||||
|
DBUG_PRINT("info",("host is set: '%s'", mi->host));
|
||||||
String *packet= &thd->packet;
|
String *packet= &thd->packet;
|
||||||
packet->length(0);
|
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);
|
pthread_mutex_lock(&data_lock);
|
||||||
/*
|
/*
|
||||||
This function will abort when it notices that
|
This function will abort when it notices that some CHANGE MASTER or
|
||||||
some CHANGE MASTER or RESET MASTER has changed
|
RESET MASTER has changed the master info.
|
||||||
the master info. To catch this, these commands
|
To catch this, these commands modify abort_pos_wait ; We just monitor
|
||||||
modify abort_pos_wait ; we just monitor abort_pos_wait
|
abort_pos_wait and see if it has changed.
|
||||||
and see if it has changed.
|
Why do we have this mechanism instead of simply monitoring slave_running
|
||||||
Why do we have this mechanism instead of simply monitoring slave_running in
|
in the loop (we do this too), as CHANGE MASTER/RESET SLAVE require that
|
||||||
the loop (we do this too), as CHANGE MASTER/RESET SLAVE require that the
|
the SQL thread be stopped?
|
||||||
SQL thread be stopped? This is in case
|
This is becasue if someones does:
|
||||||
STOP SLAVE;CHANGE MASTER/RESET SLAVE; START SLAVE;
|
STOP SLAVE;CHANGE MASTER/RESET SLAVE; START SLAVE;
|
||||||
happens very quickly between the moment pthread_cond_wait() wakes up and
|
the change may happen very quickly and we may not notice that
|
||||||
the while() is evaluated: in that case slave_running is again 1 when the
|
slave_running briefly switches between 1/0/1.
|
||||||
while() is evaluated.
|
|
||||||
*/
|
*/
|
||||||
init_abort_pos_wait= abort_pos_wait;
|
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
|
error= -2; //means improper arguments
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
//p points to '.'
|
/* p points to '.' */
|
||||||
log_name_extension= strtoul(++p, &p_end, 10);
|
log_name_extension= strtoul(++p, &p_end, 10);
|
||||||
/*
|
/*
|
||||||
p_end points to the first invalid character.
|
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;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
//"compare and wait" main loop
|
/* The "compare and wait" main loop */
|
||||||
while (!thd->killed &&
|
while (!thd->killed &&
|
||||||
init_abort_pos_wait == abort_pos_wait &&
|
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)
|
slave_running)
|
||||||
{
|
{
|
||||||
bool pos_reached;
|
bool pos_reached;
|
||||||
|
361
sql/sql_acl.cc
361
sql/sql_acl.cc
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2000 MySQL AB
|
/* Copyright (C) 2000-2003 MySQL AB
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -193,7 +193,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
|
|||||||
host.db= get_field(&mem, table,1);
|
host.db= get_field(&mem, table,1);
|
||||||
host.access= get_access(table,2);
|
host.access= get_access(table,2);
|
||||||
host.access= fix_rights_for_db(host.access);
|
host.access= fix_rights_for_db(host.access);
|
||||||
host.sort= get_sort(2,host.host.hostname,host.db);
|
host.sort= get_sort(2,host.host.hostname,host.db);
|
||||||
#ifndef TO_BE_REMOVED
|
#ifndef TO_BE_REMOVED
|
||||||
if (table->fields == 8)
|
if (table->fields == 8)
|
||||||
{ // Without grant
|
{ // Without grant
|
||||||
@@ -213,8 +213,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
|
|||||||
if (table->field[2]->field_length == 8 &&
|
if (table->field[2]->field_length == 8 &&
|
||||||
protocol_version == PROTOCOL_VERSION)
|
protocol_version == PROTOCOL_VERSION)
|
||||||
{
|
{
|
||||||
sql_print_error(
|
sql_print_error("Old 'user' table. (Check README or the Reference manual). Continuing --old-protocol"); /* purecov: tested */
|
||||||
"Old 'user' table. (Check README or the Reference manual). Continuing --old-protocol"); /* purecov: tested */
|
|
||||||
protocol_version=9; /* purecov: tested */
|
protocol_version=9; /* purecov: tested */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,7 +246,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
|
|||||||
user.sort=get_sort(2,user.host.hostname,user.user);
|
user.sort=get_sort(2,user.host.hostname,user.user);
|
||||||
user.hostname_length= (user.host.hostname ?
|
user.hostname_length= (user.host.hostname ?
|
||||||
(uint) strlen(user.host.hostname) : 0);
|
(uint) strlen(user.host.hostname) : 0);
|
||||||
if (table->fields >= 31) /* Starting from 4.0.2 we have more fields */
|
if (table->fields >= 31) /* Starting from 4.0.2 we have more fields */
|
||||||
{
|
{
|
||||||
char *ssl_type=get_field(&mem, table, 24);
|
char *ssl_type=get_field(&mem, table, 24);
|
||||||
if (!ssl_type)
|
if (!ssl_type)
|
||||||
@@ -259,7 +258,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
|
|||||||
else /* !strcmp(ssl_type, "SPECIFIED") */
|
else /* !strcmp(ssl_type, "SPECIFIED") */
|
||||||
user.ssl_type=SSL_TYPE_SPECIFIED;
|
user.ssl_type=SSL_TYPE_SPECIFIED;
|
||||||
|
|
||||||
user.ssl_cipher= get_field(&mem, table, 25);
|
user.ssl_cipher= get_field(&mem, table, 25);
|
||||||
user.x509_issuer= get_field(&mem, table, 26);
|
user.x509_issuer= get_field(&mem, table, 26);
|
||||||
user.x509_subject= get_field(&mem, table, 27);
|
user.x509_subject= get_field(&mem, table, 27);
|
||||||
|
|
||||||
@@ -368,7 +367,14 @@ void acl_free(bool end)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reload acl list if possible */
|
|
||||||
|
/*
|
||||||
|
Forget current privileges and read new privileges from the privilege tables
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
acl_reload()
|
||||||
|
thd Thread handle
|
||||||
|
*/
|
||||||
|
|
||||||
void acl_reload(THD *thd)
|
void acl_reload(THD *thd)
|
||||||
{
|
{
|
||||||
@@ -493,8 +499,8 @@ static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b)
|
|||||||
|
|
||||||
ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
|
ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
|
||||||
const char *password,const char *message,
|
const char *password,const char *message,
|
||||||
char **priv_user, char *priv_host,
|
char **priv_user, char *priv_host,
|
||||||
bool old_ver, USER_RESOURCES *mqh)
|
bool old_ver, USER_RESOURCES *mqh)
|
||||||
{
|
{
|
||||||
ulong user_access=NO_ACCESS;
|
ulong user_access=NO_ACCESS;
|
||||||
*priv_user=(char*) user;
|
*priv_user=(char*) user;
|
||||||
@@ -526,15 +532,15 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
|
|||||||
{
|
{
|
||||||
#ifdef HAVE_OPENSSL
|
#ifdef HAVE_OPENSSL
|
||||||
Vio *vio=thd->net.vio;
|
Vio *vio=thd->net.vio;
|
||||||
/*
|
/*
|
||||||
In this point we know that user is allowed to connect
|
In this point we know that user is allowed to connect
|
||||||
from given host by given username/password pair. Now
|
from given host by given username/password pair. Now
|
||||||
we check if SSL is required, if user is using SSL and
|
we check if SSL is required, if user is using SSL and
|
||||||
if X509 certificate attributes are OK
|
if X509 certificate attributes are OK
|
||||||
*/
|
*/
|
||||||
switch (acl_user->ssl_type) {
|
switch (acl_user->ssl_type) {
|
||||||
case SSL_TYPE_NOT_SPECIFIED: // Impossible
|
case SSL_TYPE_NOT_SPECIFIED: // Impossible
|
||||||
case SSL_TYPE_NONE: /* SSL is not required to connect */
|
case SSL_TYPE_NONE: /* SSL is not required to connect */
|
||||||
user_access=acl_user->access;
|
user_access=acl_user->access;
|
||||||
break;
|
break;
|
||||||
case SSL_TYPE_ANY: /* Any kind of SSL is good enough */
|
case SSL_TYPE_ANY: /* Any kind of SSL is good enough */
|
||||||
@@ -544,7 +550,7 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
|
|||||||
case SSL_TYPE_X509: /* Client should have any valid certificate. */
|
case SSL_TYPE_X509: /* Client should have any valid certificate. */
|
||||||
/*
|
/*
|
||||||
We need to check for absence of SSL because without SSL
|
We need to check for absence of SSL because without SSL
|
||||||
we should reject connection.
|
we should reject connection.
|
||||||
*/
|
*/
|
||||||
if (vio_type(vio) == VIO_TYPE_SSL && SSL_get_peer_certificate(vio->ssl_))
|
if (vio_type(vio) == VIO_TYPE_SSL && SSL_get_peer_certificate(vio->ssl_))
|
||||||
user_access=acl_user->access;
|
user_access=acl_user->access;
|
||||||
@@ -653,12 +659,12 @@ static byte* check_get_key(ACL_USER *buff,uint *length,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void acl_update_user(const char *user, const char *host,
|
static void acl_update_user(const char *user, const char *host,
|
||||||
const char *password,
|
const char *password,
|
||||||
enum SSL_type ssl_type,
|
enum SSL_type ssl_type,
|
||||||
const char *ssl_cipher,
|
const char *ssl_cipher,
|
||||||
const char *x509_issuer,
|
const char *x509_issuer,
|
||||||
const char *x509_subject,
|
const char *x509_subject,
|
||||||
USER_RESOURCES *mqh,
|
USER_RESOURCES *mqh,
|
||||||
ulong privileges)
|
ulong privileges)
|
||||||
{
|
{
|
||||||
for (uint i=0 ; i < acl_users.elements ; i++)
|
for (uint i=0 ; i < acl_users.elements ; i++)
|
||||||
@@ -707,7 +713,7 @@ static void acl_update_user(const char *user, const char *host,
|
|||||||
|
|
||||||
|
|
||||||
static void acl_insert_user(const char *user, const char *host,
|
static void acl_insert_user(const char *user, const char *host,
|
||||||
const char *password,
|
const char *password,
|
||||||
enum SSL_type ssl_type,
|
enum SSL_type ssl_type,
|
||||||
const char *ssl_cipher,
|
const char *ssl_cipher,
|
||||||
const char *x509_issuer,
|
const char *x509_issuer,
|
||||||
@@ -805,9 +811,10 @@ static void acl_insert_db(const char *user, const char *host, const char *db,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
** Get privilege for a host, user and db combination
|
/*
|
||||||
*****************************************************************************/
|
Get privilege for a host, user and db combination
|
||||||
|
*/
|
||||||
|
|
||||||
ulong acl_get(const char *host, const char *ip, const char *bin_ip,
|
ulong acl_get(const char *host, const char *ip, const char *bin_ip,
|
||||||
const char *user, const char *db)
|
const char *user, const char *db)
|
||||||
@@ -929,11 +936,14 @@ int wild_case_compare(const char *str,const char *wildstr)
|
|||||||
DBUG_RETURN (*str != '\0');
|
DBUG_RETURN (*str != '\0');
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
** check if there are any possible matching entries for this host
|
/*
|
||||||
** All host names without wild cards are stored in a hash table,
|
Check if there are any possible matching entries for this host
|
||||||
** entries with wildcards are stored in a dynamic array
|
|
||||||
*****************************************************************************/
|
NOTES
|
||||||
|
All host names without wild cards are stored in a hash table,
|
||||||
|
entries with wildcards are stored in a dynamic array
|
||||||
|
*/
|
||||||
|
|
||||||
static void init_check_host(void)
|
static void init_check_host(void)
|
||||||
{
|
{
|
||||||
@@ -1006,10 +1016,6 @@ bool acl_check_host(const char *host, const char *ip)
|
|||||||
return 1; // Host is not allowed
|
return 1; // Host is not allowed
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
Change password for the user if it's not an anonymous user
|
|
||||||
Note: This should write the error directly to the client!
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Check if the user is allowed to change password
|
Check if the user is allowed to change password
|
||||||
@@ -1021,8 +1027,8 @@ bool acl_check_host(const char *host, const char *ip)
|
|||||||
user user name
|
user user name
|
||||||
|
|
||||||
RETURN VALUE
|
RETURN VALUE
|
||||||
0 OK
|
0 OK
|
||||||
1 ERROR ; In this case the error is sent to the client.
|
1 ERROR ; In this case the error is sent to the client.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool check_change_password(THD *thd, const char *host, const char *user)
|
bool check_change_password(THD *thd, const char *host, const char *user)
|
||||||
@@ -1061,7 +1067,7 @@ bool check_change_password(THD *thd, const char *host, const char *user)
|
|||||||
RETURN VALUES
|
RETURN VALUES
|
||||||
0 ok
|
0 ok
|
||||||
1 ERROR; In this case the error is sent to the client.
|
1 ERROR; In this case the error is sent to the client.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool change_password(THD *thd, const char *host, const char *user,
|
bool change_password(THD *thd, const char *host, const char *user,
|
||||||
char *new_password)
|
char *new_password)
|
||||||
@@ -1127,7 +1133,7 @@ find_acl_user(const char *host, const char *user)
|
|||||||
{
|
{
|
||||||
ACL_USER *acl_user=dynamic_element(&acl_users,i,ACL_USER*);
|
ACL_USER *acl_user=dynamic_element(&acl_users,i,ACL_USER*);
|
||||||
DBUG_PRINT("info",("strcmp('%s','%s'), compare_hostname('%s','%s'),",
|
DBUG_PRINT("info",("strcmp('%s','%s'), compare_hostname('%s','%s'),",
|
||||||
user,acl_user->user,(host),(acl_user->host)));
|
user,acl_user->user,(host),(acl_user->host)));
|
||||||
if (!acl_user->user && !user[0] ||
|
if (!acl_user->user && !user[0] ||
|
||||||
acl_user->user && !strcmp(user,acl_user->user))
|
acl_user->user && !strcmp(user,acl_user->user))
|
||||||
{
|
{
|
||||||
@@ -1140,15 +1146,18 @@ find_acl_user(const char *host, const char *user)
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
Handle comparing of hostname
|
|
||||||
A hostname may be of type:
|
|
||||||
hostname (May include wildcards); monty.pp.sci.fi
|
|
||||||
ip (May include wildcards); 192.168.0.0
|
|
||||||
ip/netmask 192.168.0.0/255.255.255.0
|
|
||||||
|
|
||||||
A net mask of 0.0.0.0 is not allowed.
|
/*
|
||||||
*****************************************************************************/
|
Comparing of hostnames
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
A hostname may be of type:
|
||||||
|
hostname (May include wildcards); monty.pp.sci.fi
|
||||||
|
ip (May include wildcards); 192.168.0.0
|
||||||
|
ip/netmask 192.168.0.0/255.255.255.0
|
||||||
|
|
||||||
|
A net mask of 0.0.0.0 is not allowed.
|
||||||
|
*/
|
||||||
|
|
||||||
static const char *calc_ip(const char *ip, long *val, char end)
|
static const char *calc_ip(const char *ip, long *val, char end)
|
||||||
{
|
{
|
||||||
@@ -1195,9 +1204,9 @@ static bool compare_hostname(const acl_host_and_ip *host, const char *hostname,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/*
|
||||||
Code to update grants in the user and database privilege tables
|
Update grants in the user and database privilege tables
|
||||||
****************************************************************************/
|
*/
|
||||||
|
|
||||||
static bool update_user_table(THD *thd, const char *host, const char *user,
|
static bool update_user_table(THD *thd, const char *host, const char *user,
|
||||||
const char *new_password)
|
const char *new_password)
|
||||||
@@ -1263,7 +1272,7 @@ static bool test_if_create_new_users(THD *thd)
|
|||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
** Handle GRANT commands
|
Handle GRANT commands
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
|
static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
|
||||||
@@ -1285,8 +1294,8 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
|
|||||||
if (combo.password.length != HASH_PASSWORD_LENGTH)
|
if (combo.password.length != HASH_PASSWORD_LENGTH)
|
||||||
{
|
{
|
||||||
my_printf_error(ER_PASSWORD_NO_MATCH,
|
my_printf_error(ER_PASSWORD_NO_MATCH,
|
||||||
"Password hash should be a %d-digit hexadecimal number",
|
"Password hash should be a %d-digit hexadecimal number",
|
||||||
MYF(0),HASH_PASSWORD_LENGTH);
|
MYF(0),HASH_PASSWORD_LENGTH);
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
password=combo.password.str;
|
password=combo.password.str;
|
||||||
@@ -1459,7 +1468,7 @@ static int replace_db_table(TABLE *table, const char *db,
|
|||||||
char what= (revoke_grant) ? 'N' : 'Y';
|
char what= (revoke_grant) ? 'N' : 'Y';
|
||||||
DBUG_ENTER("replace_db_table");
|
DBUG_ENTER("replace_db_table");
|
||||||
|
|
||||||
// is there such a user in user table in memory ????
|
/* Check if there is such a user in user table in memory? */
|
||||||
if (!initialized || !find_acl_user(combo.host.str,combo.user.str))
|
if (!initialized || !find_acl_user(combo.host.str,combo.user.str))
|
||||||
{
|
{
|
||||||
my_error(ER_PASSWORD_NO_MATCH,MYF(0));
|
my_error(ER_PASSWORD_NO_MATCH,MYF(0));
|
||||||
@@ -1471,7 +1480,7 @@ static int replace_db_table(TABLE *table, const char *db,
|
|||||||
table->field[2]->store(combo.user.str,combo.user.length);
|
table->field[2]->store(combo.user.str,combo.user.length);
|
||||||
table->file->index_init(0);
|
table->file->index_init(0);
|
||||||
if (table->file->index_read(table->record[0],(byte*) table->field[0]->ptr,0,
|
if (table->file->index_read(table->record[0],(byte*) table->field[0]->ptr,0,
|
||||||
HA_READ_KEY_EXACT))
|
HA_READ_KEY_EXACT))
|
||||||
{
|
{
|
||||||
if (what == 'N')
|
if (what == 'N')
|
||||||
{ // no row, no revoke
|
{ // no row, no revoke
|
||||||
@@ -1502,7 +1511,7 @@ static int replace_db_table(TABLE *table, const char *db,
|
|||||||
|
|
||||||
if (old_row_exists)
|
if (old_row_exists)
|
||||||
{
|
{
|
||||||
// update old existing row
|
/* update old existing row */
|
||||||
if (rights)
|
if (rights)
|
||||||
{
|
{
|
||||||
if ((error=table->file->update_row(table->record[1],table->record[0])))
|
if ((error=table->file->update_row(table->record[1],table->record[0])))
|
||||||
@@ -1529,11 +1538,11 @@ static int replace_db_table(TABLE *table, const char *db,
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
/* This could only happen if the grant tables got corrupted */
|
/* This could only happen if the grant tables got corrupted */
|
||||||
table_error:
|
table_error:
|
||||||
table->file->print_error(error,MYF(0)); /* purecov: deadcode */
|
table->file->print_error(error,MYF(0)); /* purecov: deadcode */
|
||||||
table->file->index_end();
|
table->file->index_end();
|
||||||
|
|
||||||
abort:
|
abort:
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1649,7 +1658,7 @@ public:
|
|||||||
if (!(mem_check = new GRANT_COLUMN(*res,
|
if (!(mem_check = new GRANT_COLUMN(*res,
|
||||||
fix_rights_for_column(priv))))
|
fix_rights_for_column(priv))))
|
||||||
{
|
{
|
||||||
// Don't use this entry
|
/* Don't use this entry */
|
||||||
privs = cols = 0; /* purecov: deadcode */
|
privs = cols = 0; /* purecov: deadcode */
|
||||||
return; /* purecov: deadcode */
|
return; /* purecov: deadcode */
|
||||||
}
|
}
|
||||||
@@ -1827,7 +1836,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
|
|||||||
key_length, HA_READ_KEY_EXACT))
|
key_length, HA_READ_KEY_EXACT))
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
// Scan trough all rows with the same host,db,user and table
|
/* Scan through all rows with the same host,db,user and table */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
ulong privileges = (ulong) table->field[6]->val_int();
|
ulong privileges = (ulong) table->field[6]->val_int();
|
||||||
@@ -1877,7 +1886,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
|
|||||||
!key_cmp(table,key,0,key_length));
|
!key_cmp(table,key,0,key_length));
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
table->file->index_end();
|
table->file->index_end();
|
||||||
DBUG_RETURN(result);
|
DBUG_RETURN(result);
|
||||||
}
|
}
|
||||||
@@ -1947,7 +1956,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
|
|||||||
|
|
||||||
if (revoke_grant)
|
if (revoke_grant)
|
||||||
{
|
{
|
||||||
// column rights are already fixed in mysql_table_grant !
|
/* column rights are already fixed in mysql_table_grant */
|
||||||
store_table_rights=j & ~store_table_rights;
|
store_table_rights=j & ~store_table_rights;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1983,7 +1992,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
|
|||||||
if (rights | col_rights)
|
if (rights | col_rights)
|
||||||
{
|
{
|
||||||
grant_table->privs= rights;
|
grant_table->privs= rights;
|
||||||
grant_table->cols= col_rights;
|
grant_table->cols= col_rights;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1991,19 +2000,36 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
|
|||||||
}
|
}
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
/* This should never happen */
|
/* This should never happen */
|
||||||
table_error:
|
table_error:
|
||||||
table->file->print_error(error,MYF(0)); /* purecov: deadcode */
|
table->file->print_error(error,MYF(0)); /* purecov: deadcode */
|
||||||
DBUG_RETURN(-1); /* purecov: deadcode */
|
DBUG_RETURN(-1); /* purecov: deadcode */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Store table level and column level grants in the privilege tables
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
mysql_table_grant()
|
||||||
|
thd Thread handle
|
||||||
|
table_list List of tables to give grant
|
||||||
|
user_list List of users to give grant
|
||||||
|
columns List of columns to give grant
|
||||||
|
rights Table level grant
|
||||||
|
revoke_grant Set to 1 if this is a REVOKE command
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 ok
|
||||||
|
1 error
|
||||||
|
*/
|
||||||
|
|
||||||
int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
|
int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
|
||||||
List <LEX_USER> &user_list,
|
List <LEX_USER> &user_list,
|
||||||
List <LEX_COLUMN> &columns, ulong rights,
|
List <LEX_COLUMN> &columns, ulong rights,
|
||||||
bool revoke_grant)
|
bool revoke_grant)
|
||||||
{
|
{
|
||||||
ulong column_priv = 0;
|
ulong column_priv= 0;
|
||||||
List_iterator <LEX_USER> str_list (user_list);
|
List_iterator <LEX_USER> str_list (user_list);
|
||||||
LEX_USER *Str;
|
LEX_USER *Str;
|
||||||
TABLE_LIST tables[3];
|
TABLE_LIST tables[3];
|
||||||
@@ -2024,21 +2050,21 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
|
|||||||
if (columns.elements && !revoke_grant)
|
if (columns.elements && !revoke_grant)
|
||||||
{
|
{
|
||||||
TABLE *table;
|
TABLE *table;
|
||||||
class LEX_COLUMN *check;
|
class LEX_COLUMN *column;
|
||||||
List_iterator <LEX_COLUMN> iter(columns);
|
List_iterator <LEX_COLUMN> column_iter(columns);
|
||||||
|
|
||||||
if (!(table=open_ltable(thd,table_list,TL_READ)))
|
if (!(table=open_ltable(thd,table_list,TL_READ)))
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
while ((check = iter++))
|
while ((column = column_iter++))
|
||||||
{
|
{
|
||||||
if (!find_field_in_table(thd,table,check->column.ptr(),
|
if (!find_field_in_table(thd,table,column->column.ptr(),
|
||||||
check->column.length(),0,0))
|
column->column.length(),0,0))
|
||||||
{
|
{
|
||||||
my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),MYF(0),
|
my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),MYF(0),
|
||||||
check->column.c_ptr(), table_list->alias);
|
column->column.c_ptr(), table_list->alias);
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
column_priv |= check->rights | (rights & COL_ACLS);
|
column_priv|= column->rights;
|
||||||
}
|
}
|
||||||
close_thread_tables(thd);
|
close_thread_tables(thd);
|
||||||
}
|
}
|
||||||
@@ -2148,21 +2174,21 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
|
|||||||
/* If revoke_grant, calculate the new column privilege for tables_priv */
|
/* If revoke_grant, calculate the new column privilege for tables_priv */
|
||||||
if (revoke_grant)
|
if (revoke_grant)
|
||||||
{
|
{
|
||||||
class LEX_COLUMN *check;
|
class LEX_COLUMN *column;
|
||||||
List_iterator <LEX_COLUMN> iter(columns);
|
List_iterator <LEX_COLUMN> column_iter(columns);
|
||||||
GRANT_COLUMN *grant_column;
|
GRANT_COLUMN *grant_column;
|
||||||
|
|
||||||
/* Fix old grants */
|
/* Fix old grants */
|
||||||
while ((check = iter++))
|
while ((column = column_iter++))
|
||||||
{
|
{
|
||||||
grant_column = column_hash_search(grant_table,
|
grant_column = column_hash_search(grant_table,
|
||||||
check->column.ptr(),
|
column->column.ptr(),
|
||||||
check->column.length());
|
column->column.length());
|
||||||
if (grant_column)
|
if (grant_column)
|
||||||
grant_column->rights&= ~(check->rights | rights);
|
grant_column->rights&= ~(column->rights | rights);
|
||||||
}
|
}
|
||||||
/* scan trough all columns to get new column grant */
|
/* scan trough all columns to get new column grant */
|
||||||
column_priv=0;
|
column_priv= 0;
|
||||||
for (uint idx=0 ; idx < grant_table->hash_columns.records ; idx++)
|
for (uint idx=0 ; idx < grant_table->hash_columns.records ; idx++)
|
||||||
{
|
{
|
||||||
grant_column= (GRANT_COLUMN*) hash_element(&grant_table->hash_columns,
|
grant_column= (GRANT_COLUMN*) hash_element(&grant_table->hash_columns,
|
||||||
@@ -2259,7 +2285,7 @@ int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list,
|
|||||||
if (!revoke_grant)
|
if (!revoke_grant)
|
||||||
create_new_users= test_if_create_new_users(thd);
|
create_new_users= test_if_create_new_users(thd);
|
||||||
|
|
||||||
// go through users in user_list
|
/* go through users in user_list */
|
||||||
pthread_mutex_lock(&LOCK_grant);
|
pthread_mutex_lock(&LOCK_grant);
|
||||||
VOID(pthread_mutex_lock(&acl_cache->lock));
|
VOID(pthread_mutex_lock(&acl_cache->lock));
|
||||||
grant_version++;
|
grant_version++;
|
||||||
@@ -2280,7 +2306,7 @@ int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ((replace_user_table(thd,
|
if ((replace_user_table(thd,
|
||||||
tables[0].table,
|
tables[0].table,
|
||||||
*Str,
|
*Str,
|
||||||
(!db ? rights : 0), revoke_grant,
|
(!db ? rights : 0), revoke_grant,
|
||||||
create_new_users)))
|
create_new_users)))
|
||||||
@@ -2410,7 +2436,16 @@ end:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Reload grant array if possible */
|
/*
|
||||||
|
Reload grant array if possible
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
grant_reload()
|
||||||
|
thd Thread handler
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
Locked tables are checked by acl_init and doesn't have to be checked here
|
||||||
|
*/
|
||||||
|
|
||||||
void grant_reload(THD *thd)
|
void grant_reload(THD *thd)
|
||||||
{
|
{
|
||||||
@@ -2419,8 +2454,6 @@ void grant_reload(THD *thd)
|
|||||||
MEM_ROOT old_mem;
|
MEM_ROOT old_mem;
|
||||||
DBUG_ENTER("grant_reload");
|
DBUG_ENTER("grant_reload");
|
||||||
|
|
||||||
// Locked tables are checked by acl_init and doesn't have to be checked here
|
|
||||||
|
|
||||||
pthread_mutex_lock(&LOCK_grant);
|
pthread_mutex_lock(&LOCK_grant);
|
||||||
grant_version++;
|
grant_version++;
|
||||||
old_hash_tables=hash_tables;
|
old_hash_tables=hash_tables;
|
||||||
@@ -2496,13 +2529,13 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
|
|||||||
pthread_mutex_unlock(&LOCK_grant);
|
pthread_mutex_unlock(&LOCK_grant);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
pthread_mutex_unlock(&LOCK_grant);
|
pthread_mutex_unlock(&LOCK_grant);
|
||||||
if (!no_errors) // Not a silent skip of table
|
if (!no_errors) // Not a silent skip of table
|
||||||
{
|
{
|
||||||
const char *command="";
|
const char *command="";
|
||||||
if (want_access & SELECT_ACL)
|
if (want_access & SELECT_ACL)
|
||||||
command ="select";
|
command ="select";
|
||||||
else if (want_access & INSERT_ACL)
|
else if (want_access & INSERT_ACL)
|
||||||
command = "insert";
|
command = "insert";
|
||||||
else if (want_access & UPDATE_ACL)
|
else if (want_access & UPDATE_ACL)
|
||||||
@@ -2543,7 +2576,7 @@ bool check_grant_column(THD *thd,TABLE *table, const char *name,
|
|||||||
|
|
||||||
pthread_mutex_lock(&LOCK_grant);
|
pthread_mutex_lock(&LOCK_grant);
|
||||||
|
|
||||||
// reload table if someone has modified any grants
|
/* reload table if someone has modified any grants */
|
||||||
|
|
||||||
if (table->grant.version != grant_version)
|
if (table->grant.version != grant_version)
|
||||||
{
|
{
|
||||||
@@ -2603,7 +2636,7 @@ bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table)
|
|||||||
|
|
||||||
pthread_mutex_lock(&LOCK_grant);
|
pthread_mutex_lock(&LOCK_grant);
|
||||||
|
|
||||||
// reload table if someone has modified any grants
|
/* reload table if someone has modified any grants */
|
||||||
|
|
||||||
if (table->grant.version != grant_version)
|
if (table->grant.version != grant_version)
|
||||||
{
|
{
|
||||||
@@ -2613,7 +2646,7 @@ bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table)
|
|||||||
table->real_name,0); /* purecov: inspected */
|
table->real_name,0); /* purecov: inspected */
|
||||||
table->grant.version=grant_version; /* purecov: inspected */
|
table->grant.version=grant_version; /* purecov: inspected */
|
||||||
}
|
}
|
||||||
// The following should always be true
|
/* The following should always be true */
|
||||||
if (!(grant_table=table->grant.grant_table))
|
if (!(grant_table=table->grant.grant_table))
|
||||||
goto err; /* purecov: inspected */
|
goto err; /* purecov: inspected */
|
||||||
|
|
||||||
@@ -2628,7 +2661,7 @@ bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* We must use my_printf_error() here! */
|
/* We must use my_printf_error() here! */
|
||||||
err:
|
err:
|
||||||
pthread_mutex_unlock(&LOCK_grant);
|
pthread_mutex_unlock(&LOCK_grant);
|
||||||
|
|
||||||
const char *command="";
|
const char *command="";
|
||||||
@@ -2648,11 +2681,11 @@ bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/*
|
||||||
Check if a user has the right to access a database
|
Check if a user has the right to access a database
|
||||||
Access is accepted if he has a grant for any table in the database
|
Access is accepted if he has a grant for any table in the database
|
||||||
Return 1 if access is denied
|
Return 1 if access is denied
|
||||||
****************************************************************************/
|
*/
|
||||||
|
|
||||||
bool check_grant_db(THD *thd,const char *db)
|
bool check_grant_db(THD *thd,const char *db)
|
||||||
{
|
{
|
||||||
@@ -2692,7 +2725,7 @@ ulong get_table_grant(THD *thd, TABLE_LIST *table)
|
|||||||
|
|
||||||
pthread_mutex_lock(&LOCK_grant);
|
pthread_mutex_lock(&LOCK_grant);
|
||||||
grant_table = table_hash_search(thd->host,thd->ip,db,user,
|
grant_table = table_hash_search(thd->host,thd->ip,db,user,
|
||||||
table->real_name,0);
|
table->real_name, 0);
|
||||||
table->grant.grant_table=grant_table; // Remember for column test
|
table->grant.grant_table=grant_table; // Remember for column test
|
||||||
table->grant.version=grant_version;
|
table->grant.version=grant_version;
|
||||||
if (grant_table)
|
if (grant_table)
|
||||||
@@ -2710,7 +2743,7 @@ ulong get_column_grant(THD *thd, TABLE_LIST *table, Field *field)
|
|||||||
ulong priv;
|
ulong priv;
|
||||||
|
|
||||||
pthread_mutex_lock(&LOCK_grant);
|
pthread_mutex_lock(&LOCK_grant);
|
||||||
// reload table if someone has modified any grants
|
/* reload table if someone has modified any grants */
|
||||||
if (table->grant.version != grant_version)
|
if (table->grant.version != grant_version)
|
||||||
{
|
{
|
||||||
table->grant.grant_table=
|
table->grant.grant_table=
|
||||||
@@ -2735,11 +2768,20 @@ ulong get_column_grant(THD *thd, TABLE_LIST *table, Field *field)
|
|||||||
return priv;
|
return priv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Help function for mysql_show_grants */
|
||||||
|
|
||||||
/*****************************************************************************
|
static void add_user_option(String *grant, ulong value, const char *name)
|
||||||
SHOW GRANTS : send to client grant-like strings depicting user@host
|
{
|
||||||
privileges
|
if (value)
|
||||||
*****************************************************************************/
|
{
|
||||||
|
char buff[22], *p; // just as in int2str
|
||||||
|
grant->append(' ');
|
||||||
|
grant->append(name, strlen(name));
|
||||||
|
grant->append(' ');
|
||||||
|
p=int10_to_str(value, buff, 10);
|
||||||
|
grant->append(buff,p-buff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const char *command_array[]=
|
static const char *command_array[]=
|
||||||
{
|
{
|
||||||
@@ -2748,13 +2790,21 @@ static const char *command_array[]=
|
|||||||
"SUPER", "CREATE TEMPORARY TABLES", "LOCK TABLES", "EXECUTE",
|
"SUPER", "CREATE TEMPORARY TABLES", "LOCK TABLES", "EXECUTE",
|
||||||
"REPLICATION SLAVE", "REPLICATION CLIENT",
|
"REPLICATION SLAVE", "REPLICATION CLIENT",
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint command_lengths[]=
|
static uint command_lengths[]=
|
||||||
{
|
{
|
||||||
6,6,6,6,6,4,6,8,7,4,5,10,5,5,14,5,23,11,7,17,18
|
6,6,6,6,6,4,6,8,7,4,5,10,5,5,14,5,23,11,7,17,18
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
/*
|
||||||
|
SHOW GRANTS; Send grants for a user to the client
|
||||||
|
|
||||||
|
IMPLEMENTATION
|
||||||
|
Send to client grant-like strings depicting user@host privileges
|
||||||
|
*/
|
||||||
|
|
||||||
|
int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
||||||
{
|
{
|
||||||
ulong want_access;
|
ulong want_access;
|
||||||
uint counter,index;
|
uint counter,index;
|
||||||
@@ -2793,7 +2843,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
!my_strcasecmp(lex_user->host.str,host))
|
!my_strcasecmp(lex_user->host.str,host))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (counter == acl_users.elements)
|
if (counter == acl_users.elements)
|
||||||
{
|
{
|
||||||
my_printf_error(ER_NONEXISTING_GRANT,ER(ER_NONEXISTING_GRANT),
|
my_printf_error(ER_NONEXISTING_GRANT,ER(ER_NONEXISTING_GRANT),
|
||||||
MYF(0),lex_user->user.str,lex_user->host.str);
|
MYF(0),lex_user->user.str,lex_user->host.str);
|
||||||
@@ -2824,13 +2874,13 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
global.append("ALL PRIVILEGES",14);
|
global.append("ALL PRIVILEGES",14);
|
||||||
else if (!(want_access & ~GRANT_ACL))
|
else if (!(want_access & ~GRANT_ACL))
|
||||||
global.append("USAGE",5);
|
global.append("USAGE",5);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool found=0;
|
bool found=0;
|
||||||
ulong j,test_access= want_access & ~GRANT_ACL;
|
ulong j,test_access= want_access & ~GRANT_ACL;
|
||||||
for (counter=0, j = SELECT_ACL;j <= GLOBAL_ACLS;counter++,j <<= 1)
|
for (counter=0, j = SELECT_ACL;j <= GLOBAL_ACLS;counter++,j <<= 1)
|
||||||
{
|
{
|
||||||
if (test_access & j)
|
if (test_access & j)
|
||||||
{
|
{
|
||||||
if (found)
|
if (found)
|
||||||
global.append(", ",2);
|
global.append(", ",2);
|
||||||
@@ -2840,7 +2890,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
global.append (" ON *.* TO '",12);
|
global.append (" ON *.* TO '",12);
|
||||||
global.append(lex_user->user.str,lex_user->user.length);
|
global.append(lex_user->user.str,lex_user->user.length);
|
||||||
global.append ("'@'",3);
|
global.append ("'@'",3);
|
||||||
global.append(lex_user->host.str,lex_user->host.length);
|
global.append(lex_user->host.str,lex_user->host.length);
|
||||||
global.append ('\'');
|
global.append ('\'');
|
||||||
@@ -2863,25 +2913,25 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
global.append(" REQUIRE ",9);
|
global.append(" REQUIRE ",9);
|
||||||
if (acl_user->x509_issuer)
|
if (acl_user->x509_issuer)
|
||||||
{
|
{
|
||||||
ssl_options++;
|
ssl_options++;
|
||||||
global.append("ISSUER \'",8);
|
global.append("ISSUER \'",8);
|
||||||
global.append(acl_user->x509_issuer,strlen(acl_user->x509_issuer));
|
global.append(acl_user->x509_issuer,strlen(acl_user->x509_issuer));
|
||||||
global.append('\'');
|
global.append('\'');
|
||||||
}
|
}
|
||||||
if (acl_user->x509_subject)
|
if (acl_user->x509_subject)
|
||||||
{
|
{
|
||||||
if (ssl_options++)
|
if (ssl_options++)
|
||||||
global.append(' ');
|
global.append(' ');
|
||||||
global.append("SUBJECT \'",9);
|
global.append("SUBJECT \'",9);
|
||||||
global.append(acl_user->x509_subject,strlen(acl_user->x509_subject));
|
global.append(acl_user->x509_subject,strlen(acl_user->x509_subject));
|
||||||
global.append('\'');
|
global.append('\'');
|
||||||
}
|
}
|
||||||
if (acl_user->ssl_cipher)
|
if (acl_user->ssl_cipher)
|
||||||
{
|
{
|
||||||
if (ssl_options++)
|
if (ssl_options++)
|
||||||
global.append(' ');
|
global.append(' ');
|
||||||
global.append("CIPHER '",8);
|
global.append("CIPHER '",8);
|
||||||
global.append(acl_user->ssl_cipher,strlen(acl_user->ssl_cipher));
|
global.append(acl_user->ssl_cipher,strlen(acl_user->ssl_cipher));
|
||||||
global.append('\'');
|
global.append('\'');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2889,30 +2939,15 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
(acl_user->user_resource.questions | acl_user->user_resource.updates |
|
(acl_user->user_resource.questions | acl_user->user_resource.updates |
|
||||||
acl_user->user_resource.connections))
|
acl_user->user_resource.connections))
|
||||||
{
|
{
|
||||||
global.append(" WITH",5);
|
global.append(" WITH",5);
|
||||||
if (want_access & GRANT_ACL)
|
if (want_access & GRANT_ACL)
|
||||||
global.append(" GRANT OPTION",13);
|
global.append(" GRANT OPTION",13);
|
||||||
if (acl_user->user_resource.questions)
|
add_user_option(&global, acl_user->user_resource.questions,
|
||||||
{
|
"MAX_QUERIES_PER_HOUR");
|
||||||
char buff[22], *p; // just as in int2str
|
add_user_option(&global, acl_user->user_resource.updates,
|
||||||
global.append(" MAX_QUERIES_PER_HOUR ",22);
|
"MAX_UPDATES_PER_HOUR");
|
||||||
p=int10_to_str(acl_user->user_resource.questions,buff,10);
|
add_user_option(&global, acl_user->user_resource.connections,
|
||||||
global.append(buff,p-buff);
|
"MAX_CONNECTIONS_PER_HOUR");
|
||||||
}
|
|
||||||
if (acl_user->user_resource.updates)
|
|
||||||
{
|
|
||||||
char buff[22], *p; // just as in int2str
|
|
||||||
global.append(" MAX_UPDATES_PER_HOUR ",22);
|
|
||||||
p=int10_to_str(acl_user->user_resource.updates,buff,10);
|
|
||||||
global.append(buff,p-buff);
|
|
||||||
}
|
|
||||||
if (acl_user->user_resource.connections)
|
|
||||||
{
|
|
||||||
char buff[22], *p; // just as in int2str
|
|
||||||
global.append(" MAX_CONNECTIONS_PER_HOUR ",26);
|
|
||||||
p=int10_to_str(acl_user->user_resource.connections,buff,10);
|
|
||||||
global.append(buff,p-buff);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
thd->packet.length(0);
|
thd->packet.length(0);
|
||||||
net_store_data(&thd->packet,global.ptr(),global.length());
|
net_store_data(&thd->packet,global.ptr(),global.length());
|
||||||
@@ -2938,7 +2973,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
!my_strcasecmp(lex_user->host.str,host))
|
!my_strcasecmp(lex_user->host.str,host))
|
||||||
{
|
{
|
||||||
want_access=acl_db->access;
|
want_access=acl_db->access;
|
||||||
if (want_access)
|
if (want_access)
|
||||||
{
|
{
|
||||||
String db(buff,sizeof(buff));
|
String db(buff,sizeof(buff));
|
||||||
db.length(0);
|
db.length(0);
|
||||||
@@ -2947,7 +2982,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
if (test_all_bits(want_access,(DB_ACLS & ~GRANT_ACL)))
|
if (test_all_bits(want_access,(DB_ACLS & ~GRANT_ACL)))
|
||||||
db.append("ALL PRIVILEGES",14);
|
db.append("ALL PRIVILEGES",14);
|
||||||
else if (!(want_access & ~GRANT_ACL))
|
else if (!(want_access & ~GRANT_ACL))
|
||||||
db.append("USAGE",5);
|
db.append("USAGE",5);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int found=0, cnt;
|
int found=0, cnt;
|
||||||
@@ -2963,13 +2998,13 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
db.append (" ON `",5);
|
db.append(" ON `",5);
|
||||||
db.append(acl_db->db);
|
db.append(acl_db->db);
|
||||||
db.append ("`.* TO '",8);
|
db.append("`.* TO '",8);
|
||||||
db.append(lex_user->user.str,lex_user->user.length);
|
db.append(lex_user->user.str,lex_user->user.length);
|
||||||
db.append ("'@'",3);
|
db.append("'@'",3);
|
||||||
db.append(lex_user->host.str, lex_user->host.length);
|
db.append(lex_user->host.str, lex_user->host.length);
|
||||||
db.append ('\'');
|
db.append('\'');
|
||||||
if (want_access & GRANT_ACL)
|
if (want_access & GRANT_ACL)
|
||||||
db.append(" WITH GRANT OPTION",18);
|
db.append(" WITH GRANT OPTION",18);
|
||||||
thd->packet.length(0);
|
thd->packet.length(0);
|
||||||
@@ -2988,7 +3023,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
for (index=0 ; index < hash_tables.records ; index++)
|
for (index=0 ; index < hash_tables.records ; index++)
|
||||||
{
|
{
|
||||||
const char *user,*host;
|
const char *user,*host;
|
||||||
GRANT_TABLE *grant_table= (GRANT_TABLE*) hash_element(&hash_tables,index);
|
GRANT_TABLE *grant_table= (GRANT_TABLE*) hash_element(&hash_tables,index);
|
||||||
|
|
||||||
if (!(user=grant_table->user))
|
if (!(user=grant_table->user))
|
||||||
user="";
|
user="";
|
||||||
@@ -2998,44 +3033,54 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
if (!strcmp(lex_user->user.str,user) &&
|
if (!strcmp(lex_user->user.str,user) &&
|
||||||
!my_strcasecmp(lex_user->host.str,host))
|
!my_strcasecmp(lex_user->host.str,host))
|
||||||
{
|
{
|
||||||
want_access=grant_table->privs;
|
ulong table_access= grant_table->privs;
|
||||||
if ((want_access | grant_table->cols) != 0)
|
if ((table_access | grant_table->cols) != 0)
|
||||||
{
|
{
|
||||||
String global(buff,sizeof(buff));
|
String global(buff,sizeof(buff));
|
||||||
global.length(0);
|
global.length(0);
|
||||||
global.append("GRANT ",6);
|
global.append("GRANT ",6);
|
||||||
|
|
||||||
if (test_all_bits(grant_table->privs,(TABLE_ACLS & ~GRANT_ACL)))
|
if (test_all_bits(table_access, (TABLE_ACLS & ~GRANT_ACL)))
|
||||||
global.append("ALL PRIVILEGES",14);
|
global.append("ALL PRIVILEGES",14);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int found=0;
|
int found= 0;
|
||||||
ulong j,test_access= (want_access | grant_table->cols) & ~GRANT_ACL;
|
ulong j,test_access= (table_access | grant_table->cols) & ~GRANT_ACL;
|
||||||
|
|
||||||
for (counter=0, j = SELECT_ACL;j <= TABLE_ACLS; counter++,j <<= 1)
|
for (counter= 0, j= SELECT_ACL; j <= TABLE_ACLS; counter++, j<<= 1)
|
||||||
{
|
{
|
||||||
if (test_access & j)
|
if (test_access & j)
|
||||||
{
|
{
|
||||||
if (found)
|
if (found)
|
||||||
global.append(", ",2);
|
global.append(", ",2);
|
||||||
found = 1;
|
found= 1;
|
||||||
global.append(command_array[counter],command_lengths[counter]);
|
global.append(command_array[counter],command_lengths[counter]);
|
||||||
|
|
||||||
if (grant_table->cols)
|
if (grant_table->cols)
|
||||||
{
|
{
|
||||||
uint found_col=0;
|
uint found_col= 0;
|
||||||
for (uint col_index=0 ;
|
for (uint col_index=0 ;
|
||||||
col_index < grant_table->hash_columns.records ;
|
col_index < grant_table->hash_columns.records ;
|
||||||
col_index++)
|
col_index++)
|
||||||
{
|
{
|
||||||
GRANT_COLUMN *grant_column = (GRANT_COLUMN*)
|
GRANT_COLUMN *grant_column = (GRANT_COLUMN*)
|
||||||
hash_element(&grant_table->hash_columns,col_index);
|
hash_element(&grant_table->hash_columns,col_index);
|
||||||
if (grant_column->rights & j)
|
if (grant_column->rights & j)
|
||||||
{
|
{
|
||||||
if (!found_col)
|
if (!found_col)
|
||||||
{
|
{
|
||||||
|
found_col= 1;
|
||||||
|
/*
|
||||||
|
If we have a duplicated table level privilege, we
|
||||||
|
must write the access privilege name again.
|
||||||
|
*/
|
||||||
|
if (table_access & j)
|
||||||
|
{
|
||||||
|
global.append(", ", 2);
|
||||||
|
global.append(command_array[counter],
|
||||||
|
command_lengths[counter]);
|
||||||
|
}
|
||||||
global.append(" (",2);
|
global.append(" (",2);
|
||||||
found_col=1;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
global.append(", ",2);
|
global.append(", ",2);
|
||||||
@@ -3054,12 +3099,12 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
global.append("`.`",3);
|
global.append("`.`",3);
|
||||||
global.append(grant_table->tname);
|
global.append(grant_table->tname);
|
||||||
global.append("` TO '",6);
|
global.append("` TO '",6);
|
||||||
global.append(lex_user->user.str,lex_user->user.length);
|
global.append(lex_user->user.str,lex_user->user.length);
|
||||||
global.append("'@'",3);
|
global.append("'@'",3);
|
||||||
global.append(lex_user->host.str,lex_user->host.length);
|
global.append(lex_user->host.str,lex_user->host.length);
|
||||||
global.append('\'');
|
global.append('\'');
|
||||||
if (want_access & GRANT_ACL)
|
if (table_access & GRANT_ACL)
|
||||||
global.append(" WITH GRANT OPTION",18);
|
global.append(" WITH GRANT OPTION",18);
|
||||||
thd->packet.length(0);
|
thd->packet.length(0);
|
||||||
net_store_data(&thd->packet,global.ptr(),global.length());
|
net_store_data(&thd->packet,global.ptr(),global.length());
|
||||||
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),
|
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),
|
||||||
@@ -3072,7 +3117,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
VOID(pthread_mutex_unlock(&acl_cache->lock));
|
VOID(pthread_mutex_unlock(&acl_cache->lock));
|
||||||
pthread_mutex_unlock(&LOCK_grant);
|
pthread_mutex_unlock(&LOCK_grant);
|
||||||
|
|
||||||
|
@@ -76,8 +76,8 @@
|
|||||||
#define get_rights_for_db(A) (((A) & 63) | (((A) & DB_CHUNK1) >> 4) | (((A) & DB_CHUNK2) >> 6))
|
#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 fix_rights_for_table(A) (((A) & 63) | (((A) & ~63) << 4))
|
||||||
#define get_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 fix_rights_for_column(A) (((A) & 7) | (((A) & ~7) << 8))
|
||||||
#define get_rights_for_column(A) (((A) & COL_ACLS) | ((A & ~COL_ACLS) >> 7))
|
#define get_rights_for_column(A) (((A) & 7) | ((A) >> 8))
|
||||||
|
|
||||||
/* prototypes */
|
/* prototypes */
|
||||||
|
|
||||||
|
@@ -309,6 +309,7 @@ struct system_variables
|
|||||||
ulong tmp_table_size;
|
ulong tmp_table_size;
|
||||||
ulong tx_isolation;
|
ulong tx_isolation;
|
||||||
ulong table_type;
|
ulong table_type;
|
||||||
|
ulong default_week_format;
|
||||||
|
|
||||||
my_bool log_warnings;
|
my_bool log_warnings;
|
||||||
my_bool low_priority_updates;
|
my_bool low_priority_updates;
|
||||||
|
@@ -584,6 +584,11 @@ check_connections(THD *thd)
|
|||||||
if (thd->client_capabilities & CLIENT_SSL)
|
if (thd->client_capabilities & CLIENT_SSL)
|
||||||
{
|
{
|
||||||
/* Do the SSL layering. */
|
/* 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..."));
|
DBUG_PRINT("info", ("IO layer change in progress..."));
|
||||||
if (sslaccept(ssl_acceptor_fd, net->vio, thd->variables.net_wait_timeout))
|
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,
|
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];
|
char header[LOG_EVENT_HEADER_LEN], buf[ROTATE_HEADER_LEN];
|
||||||
memset(header, 0, 4); // when does not matter
|
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);
|
int4store(header + LOG_POS_OFFSET, 0);
|
||||||
|
|
||||||
packet->append(header, sizeof(header));
|
packet->append(header, sizeof(header));
|
||||||
/* We need to split the next statement because of problem with cxx */
|
int8store(buf+R_POS_OFFSET,position);
|
||||||
int4store(buf,4); // tell slave to skip magic number
|
|
||||||
int4store(buf+4,0);
|
|
||||||
packet->append(buf, ROTATE_HEADER_LEN);
|
packet->append(buf, ROTATE_HEADER_LEN);
|
||||||
packet->append(p,ident_len);
|
packet->append(p,ident_len);
|
||||||
if (my_net_write(net, (char*)packet->ptr(), packet->length()))
|
if (my_net_write(net, (char*)packet->ptr(), packet->length()))
|
||||||
@@ -382,17 +380,30 @@ impossible position";
|
|||||||
*/
|
*/
|
||||||
packet->set("\0", 1);
|
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
|
my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
|
||||||
if (fake_rotate_event(net, packet, log_file_name, &errmsg))
|
goto err;
|
||||||
{
|
|
||||||
my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
packet->set("\0", 1);
|
|
||||||
}
|
}
|
||||||
|
packet->set("\0", 1);
|
||||||
|
|
||||||
while (!net->error && net->vio != 0 && !thd->killed)
|
while (!net->error && net->vio != 0 && !thd->killed)
|
||||||
{
|
{
|
||||||
@@ -585,10 +596,12 @@ Increase max_allowed_packet on master";
|
|||||||
end_io_cache(&log);
|
end_io_cache(&log);
|
||||||
(void) my_close(file, MYF(MY_WME));
|
(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 ||
|
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;
|
my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
|
||||||
goto err;
|
goto err;
|
||||||
@@ -828,7 +841,7 @@ int change_master(THD* thd, MASTER_INFO* mi)
|
|||||||
// TODO: see if needs re-write
|
// TODO: see if needs re-write
|
||||||
if (init_master_info(mi, master_info_file, relay_log_info_file, 0))
|
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);
|
unlock_slave_threads(mi);
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
@@ -453,6 +453,9 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
|
|||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
thd->proc_info="preparing";
|
thd->proc_info="preparing";
|
||||||
|
|
||||||
|
select_distinct= select_distinct && (join.const_tables != join.tables);
|
||||||
|
|
||||||
if (result->initialize_tables(&join))
|
if (result->initialize_tables(&join))
|
||||||
goto err;
|
goto err;
|
||||||
if (join.const_table_map != join.found_const_table_map &&
|
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;
|
key_field->field->table->reginfo.not_exists_optimize=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define FT_KEYPART (MAX_REF_PARTS+10)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_ft_keys(DYNAMIC_ARRAY *keyuse_array,
|
add_ft_keys(DYNAMIC_ARRAY *keyuse_array,
|
||||||
JOIN_TAB *stat,COND *cond,table_map usable_tables)
|
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)
|
if ((!cond_func || cond_func->key == NO_SUCH_KEY) ||
|
||||||
return;
|
(!(usable_tables & cond_func->table->map)))
|
||||||
|
|
||||||
if (!(usable_tables & cond_func->table->map))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
KEYUSE keyuse;
|
KEYUSE keyuse;
|
||||||
|
|
||||||
keyuse.table= cond_func->table;
|
keyuse.table= cond_func->table;
|
||||||
keyuse.val = cond_func;
|
keyuse.val = cond_func;
|
||||||
keyuse.key = cond_func->key;
|
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();
|
keyuse.used_tables=cond_func->key_item()->used_tables();
|
||||||
VOID(insert_dynamic(keyuse_array,(gptr) &keyuse));
|
VOID(insert_dynamic(keyuse_array,(gptr) &keyuse));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sort_keyuse(KEYUSE *a,KEYUSE *b)
|
sort_keyuse(KEYUSE *a,KEYUSE *b)
|
||||||
{
|
{
|
||||||
|
@@ -2016,7 +2016,11 @@ simple_expr:
|
|||||||
| USER '(' ')'
|
| USER '(' ')'
|
||||||
{ $$= new Item_func_user(); current_thd->safe_to_cache_query=0; }
|
{ $$= new Item_func_user(); current_thd->safe_to_cache_query=0; }
|
||||||
| WEEK_SYM '(' expr ')'
|
| 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 ')'
|
| WEEK_SYM '(' expr ',' expr ')'
|
||||||
{ $$= new Item_func_week($3,$5); }
|
{ $$= new Item_func_week($3,$5); }
|
||||||
| YEAR_SYM '(' expr ')'
|
| YEAR_SYM '(' expr ')'
|
||||||
|
Reference in New Issue
Block a user