Commit 4e26801e authored by serg@serg.mysql.com's avatar serg@serg.mysql.com

Merge

parents e9cc0d26 988a98c3
...@@ -181,3 +181,5 @@ mysql-test/mysql-test-run ...@@ -181,3 +181,5 @@ mysql-test/mysql-test-run
BitKeeper/tmp/gone BitKeeper/tmp/gone
mysqld.S mysqld.S
mysqld.sym mysqld.sym
.snprj/*
sql-bench/output/*
This diff is collapsed.
...@@ -436,10 +436,16 @@ AM_CONDITIONAL(ASSEMBLER, test ASSEMBLER_x86 = "" -o ASSEMBLER_x86 = "") ...@@ -436,10 +436,16 @@ AM_CONDITIONAL(ASSEMBLER, test ASSEMBLER_x86 = "" -o ASSEMBLER_x86 = "")
AC_MSG_CHECKING(whether to use RAID) AC_MSG_CHECKING(whether to use RAID)
AC_ARG_WITH(raid, AC_ARG_WITH(raid,
[ --with-raid Enable RAID Support], [ --with-raid Enable RAID Support],
[ AC_DEFINE(USE_RAID) [ USE_RAID=$withval ],
AC_MSG_RESULT(yes) ], [ USE_RAID=no ]
[ AC_MSG_RESULT(no) ]
) )
if test "$USE_RAID" = "yes"
then
AC_MSG_RESULT([yes])
AC_DEFINE([USE_RAID])
else
AC_MSG_RESULT([no])
fi
# Use this to set the place used for unix socket used to local communication. # Use this to set the place used for unix socket used to local communication.
AC_ARG_WITH(unix-socket-path, AC_ARG_WITH(unix-socket-path,
......
id code name
1 1 Tim
2 1 Monty
3 2 David
4 2 Erik
5 3 Sasha
6 3 Jeremy
7 4 Matt
id code name
2 1 Monty
3 2 David
4 2 Erik
5 3 Sasha
6 3 Jeremy
7 4 Matt
8 1 Sinisa
id code name
3 2 David
4 2 Erik
5 3 Sasha
6 3 Jeremy
7 4 Matt
8 1 Sinisa
12 1 Ralph
drop table if exists t1;
create table t1 (id int unsigned not null auto_increment, code tinyint unsigned not null, name char(20) not null, primary key (id), key (code), unique (name)) type=bdb;
insert into t1 (code, name) values (1, 'Tim'), (1, 'Monty'), (2, 'David'), (2, 'Erik'), (3, 'Sasha'), (3, 'Jeremy'), (4, 'Matt');
select id, code, name from t1 order by id;
update ignore t1 set id = 8, name = 'Sinisa' where id < 3;
select id, code, name from t1 order by id;
update ignore t1 set id = id + 10, name = 'Ralph' where id < 4;
select id, code, name from t1 order by id;
drop table t1;
...@@ -472,7 +472,7 @@ int main(int argc,char **argv) ...@@ -472,7 +472,7 @@ int main(int argc,char **argv)
int error; int error;
MY_INIT(argv[0]); MY_INIT(argv[0]);
start_value=5206280L; best_t1=590774L; best_t2=5977654L; best_type=1; /* mode=6229 add=2 func_type: 0 */ start_value=5307411L; best_t1=4597287L; best_t2=3375760L; best_type=1; /* mode=4783 add=5 func_type: 0 */
if (get_options(argc,(char **) argv)) if (get_options(argc,(char **) argv))
exit(1); exit(1);
......
...@@ -889,13 +889,15 @@ int ha_berkeley::key_cmp(uint keynr, const byte * old_row, ...@@ -889,13 +889,15 @@ int ha_berkeley::key_cmp(uint keynr, const byte * old_row,
/* /*
Update a row from one value to another. Update a row from one value to another.
Clobbers key_buff2
*/ */
int ha_berkeley::update_primary_key(DB_TXN *trans, bool primary_key_changed, int ha_berkeley::update_primary_key(DB_TXN *trans, bool primary_key_changed,
const byte * old_row, const byte * old_row, DBT *old_key,
const byte * new_row, DBT *prim_key) const byte * new_row, DBT *new_key,
ulong thd_options, bool local_using_ignore)
{ {
DBT row, old_key; DBT row;
int error; int error;
DBUG_ENTER("update_primary_key"); DBUG_ENTER("update_primary_key");
...@@ -903,37 +905,83 @@ int ha_berkeley::update_primary_key(DB_TXN *trans, bool primary_key_changed, ...@@ -903,37 +905,83 @@ int ha_berkeley::update_primary_key(DB_TXN *trans, bool primary_key_changed,
{ {
// Primary key changed or we are updating a key that can have duplicates. // Primary key changed or we are updating a key that can have duplicates.
// Delete the old row and add a new one // Delete the old row and add a new one
create_key(&old_key, primary_key, key_buff2, old_row); if (!(error=remove_key(trans, primary_key, old_row, (DBT *) 0, old_key)))
if ((error=remove_key(trans, primary_key, old_row, (DBT *) 0, &old_key)))
DBUG_RETURN(error); // This should always succeed
if ((error=pack_row(&row, new_row, 0)))
{
// Out of memory (this shouldn't happen!)
(void) file->put(file, trans, &old_key, &row,
key_type[primary_key]);
DBUG_RETURN(error);
}
// Write new key
if ((error=file->put(file, trans, prim_key, &row, key_type[primary_key])))
{ {
// Probably a duplicated key; Return the error and let the caller if (!(error=pack_row(&row, new_row, 0)))
// abort. {
last_dup_key=primary_key; if ((error=file->put(file, trans, new_key, &row,
DBUG_RETURN(error); key_type[primary_key])))
{
// Probably a duplicated key; restore old key and row if needed
last_dup_key=primary_key;
if (local_using_ignore &&
!(thd_options & OPTION_INTERNAL_SUBTRANSACTIONS))
{
int new_error;
if ((new_error=pack_row(&row, old_row, 0)) ||
(new_error=file->put(file, trans, old_key, &row,
key_type[primary_key])))
error=new_error; // fatal error
}
}
}
} }
} }
else else
{ {
// Primary key didn't change; just update the row data // Primary key didn't change; just update the row data
if ((error=pack_row(&row, new_row, 0))) if (!(error=pack_row(&row, new_row, 0)))
DBUG_RETURN(error); error=file->put(file, trans, new_key, &row, 0);
error=file->put(file, trans, prim_key, &row, 0);
if (error)
DBUG_RETURN(error); // Fatal error
} }
DBUG_RETURN(0); DBUG_RETURN(error);
} }
/*
Restore changed keys, when a non-fatal error aborts the insert/update
of one row.
Clobbers keybuff2
*/
int ha_berkeley::restore_keys(DB_TXN *trans, key_map changed_keys,
uint primary_key,
const byte *old_row, DBT *old_key,
const byte *new_row, DBT *new_key,
ulong thd_options)
{
int error;
DBT tmp_key;
DBUG_ENTER("restore_keys");
/* Restore the old primary key, and the old row, but don't ignore
duplicate key failure */
if ((error=update_primary_key(trans, TRUE, new_row, new_key,
old_row, old_key, thd_options, FALSE)))
goto err;
/* Remove the new key, and put back the old key
changed_keys is a map of all non-primary keys that need to be
rolled back. The last key set in changed_keys is the one that
triggered the duplicate key error (it wasn't inserted), so for
that one just put back the old value. */
for (uint keynr=0; changed_keys; keynr++, changed_keys >>= 1)
{
if (changed_keys & 1)
{
if (changed_keys != 1 &&
(error = remove_key(trans, keynr, new_row, (DBT*) 0, new_key)))
break;
if ((error = key_file[keynr]->put(key_file[keynr], trans,
create_key(&tmp_key, keynr, key_buff2,
old_row),
old_key, key_type[keynr])))
break;
}
}
err:
dbug_assert(error != DB_KEYEXIST);
DBUG_RETURN(error);
}
int ha_berkeley::update_row(const byte * old_row, byte * new_row) int ha_berkeley::update_row(const byte * old_row, byte * new_row)
...@@ -941,6 +989,7 @@ int ha_berkeley::update_row(const byte * old_row, byte * new_row) ...@@ -941,6 +989,7 @@ int ha_berkeley::update_row(const byte * old_row, byte * new_row)
DBT prim_key, key, old_prim_key; DBT prim_key, key, old_prim_key;
int error; int error;
DB_TXN *sub_trans; DB_TXN *sub_trans;
ulong thd_options = table->in_use->options;
bool primary_key_changed; bool primary_key_changed;
DBUG_ENTER("update_row"); DBUG_ENTER("update_row");
...@@ -966,15 +1015,22 @@ int ha_berkeley::update_row(const byte * old_row, byte * new_row) ...@@ -966,15 +1015,22 @@ int ha_berkeley::update_row(const byte * old_row, byte * new_row)
old_prim_key=prim_key; old_prim_key=prim_key;
} }
sub_trans = transaction;
LINT_INIT(error); LINT_INIT(error);
for (uint retry=0 ; retry < berkeley_trans_retry ; retry++) for (uint retry=0 ; retry < berkeley_trans_retry ; retry++)
{ {
if ((error=txn_begin(db_env, transaction, &sub_trans, 0))) key_map changed_keys = 0;
break; if (using_ignore && (thd_options & OPTION_INTERNAL_SUBTRANSACTIONS))
DBUG_PRINT("trans",("starting subtransaction")); {
if ((error=txn_begin(db_env, transaction, &sub_trans, 0)))
break;
DBUG_PRINT("trans",("starting subtransaction"));
}
/* Start by updating the primary key */ /* Start by updating the primary key */
if (!(error=update_primary_key(sub_trans, primary_key_changed, if (!(error=update_primary_key(sub_trans, primary_key_changed,
old_row, new_row, &prim_key))) old_row, &old_prim_key,
new_row, &prim_key,
thd_options, using_ignore)))
{ {
// Update all other keys // Update all other keys
for (uint keynr=0 ; keynr < table->keys ; keynr++) for (uint keynr=0 ; keynr < table->keys ; keynr++)
...@@ -984,10 +1040,23 @@ int ha_berkeley::update_row(const byte * old_row, byte * new_row) ...@@ -984,10 +1040,23 @@ int ha_berkeley::update_row(const byte * old_row, byte * new_row)
if (key_cmp(keynr, old_row, new_row) || primary_key_changed) if (key_cmp(keynr, old_row, new_row) || primary_key_changed)
{ {
if ((error=remove_key(sub_trans, keynr, old_row, (DBT*) 0, if ((error=remove_key(sub_trans, keynr, old_row, (DBT*) 0,
&old_prim_key)) || &old_prim_key)))
(error=key_file[keynr]->put(key_file[keynr], sub_trans, {
if (using_ignore &&
(thd_options & OPTION_INTERNAL_SUBTRANSACTIONS))
{
int new_error;
DBUG_PRINT("trans",("aborting subtransaction"));
new_error=txn_abort(sub_trans);
if (new_error)
error = new_error;
}
DBUG_RETURN(error); // Fatal error
}
changed_keys |= (key_map)1 << keynr;
if ((error=key_file[keynr]->put(key_file[keynr], sub_trans,
create_key(&key, keynr, key_buff2, create_key(&key, keynr, key_buff2,
new_row), new_row),
&prim_key, key_type[keynr]))) &prim_key, key_type[keynr])))
{ {
last_dup_key=keynr; last_dup_key=keynr;
...@@ -996,22 +1065,50 @@ int ha_berkeley::update_row(const byte * old_row, byte * new_row) ...@@ -996,22 +1065,50 @@ int ha_berkeley::update_row(const byte * old_row, byte * new_row)
} }
} }
} }
if (!error) if (error)
{
DBUG_PRINT("trans",("committing subtransaction"));
error=txn_commit(sub_trans, 0);
}
else
{ {
/* Remove inserted row */ /* Remove inserted row */
DBUG_PRINT("error",("Got error %d",error));
if (using_ignore)
{
int new_error = 0;
if (thd_options & OPTION_INTERNAL_SUBTRANSACTIONS)
{
DBUG_PRINT("trans",("aborting subtransaction"));
new_error=txn_abort(sub_trans);
}
else if (changed_keys)
new_error=restore_keys(transaction, changed_keys, primary_key,
old_row, &old_prim_key, new_row, &prim_key,
thd_options);
if (new_error)
{
error=new_error; // This shouldn't happen
break;
}
}
#ifdef BROKEN_CODE_HERE
int new_error; int new_error;
DBUG_PRINT("error",("Got error %d",error)); DBUG_PRINT("error",("Got error %d",error));
DBUG_PRINT("trans",("aborting subtransaction")); if (using_ignore && (thd_options & OPTION_INTERNAL_SUBTRANSACTIONS))
if ((new_error=txn_abort(sub_trans))) {
DBUG_PRINT("trans",("aborting subtransaction"));
new_error=txn_abort(sub_trans);
}
else if (changed_keys)
new_error=restore_keys(changed_keys, primary_key,
old_row, old_prim_key, new_row, prim_key);
if (new_error)
{ {
error=new_error; // This shouldn't happen error=new_error; // This shouldn't happen
break; break;
} }
#endif
}
else if (using_ignore && (thd_options & OPTION_INTERNAL_SUBTRANSACTIONS))
{
DBUG_PRINT("trans",("committing subtransaction"));
error=txn_commit(sub_trans, 0);
} }
if (error != DB_LOCK_DEADLOCK) if (error != DB_LOCK_DEADLOCK)
break; break;
...@@ -1065,7 +1162,7 @@ int ha_berkeley::remove_key(DB_TXN *sub_trans, uint keynr, const byte *record, ...@@ -1065,7 +1162,7 @@ int ha_berkeley::remove_key(DB_TXN *sub_trans, uint keynr, const byte *record,
create_key(&key, keynr, key_buff2, record)), create_key(&key, keynr, key_buff2, record)),
(keynr == primary_key ? (keynr == primary_key ?
packed_record : prim_key), packed_record : prim_key),
DB_GET_BOTH))) DB_GET_BOTH | DB_RMW)))
{ // This shouldn't happen { // This shouldn't happen
error=tmp_cursor->c_del(tmp_cursor,0); error=tmp_cursor->c_del(tmp_cursor,0);
} }
...@@ -1401,9 +1498,7 @@ void ha_berkeley::position(const byte *record) ...@@ -1401,9 +1498,7 @@ void ha_berkeley::position(const byte *record)
{ {
DBT key; DBT key;
if (hidden_primary_key) if (hidden_primary_key)
{
memcpy_fixed(ref, (char*) current_ident, BDB_HIDDEN_PRIMARY_KEY_LENGTH); memcpy_fixed(ref, (char*) current_ident, BDB_HIDDEN_PRIMARY_KEY_LENGTH);
}
else else
create_key(&key, primary_key, ref, record); create_key(&key, primary_key, ref, record);
} }
...@@ -1438,6 +1533,7 @@ int ha_berkeley::extra(enum ha_extra_function operation) ...@@ -1438,6 +1533,7 @@ int ha_berkeley::extra(enum ha_extra_function operation)
case HA_EXTRA_RESET: case HA_EXTRA_RESET:
case HA_EXTRA_RESET_STATE: case HA_EXTRA_RESET_STATE:
key_read=0; key_read=0;
using_ignore=0;
break; break;
case HA_EXTRA_KEYREAD: case HA_EXTRA_KEYREAD:
key_read=1; // Query satisfied with key key_read=1; // Query satisfied with key
...@@ -1445,6 +1541,12 @@ int ha_berkeley::extra(enum ha_extra_function operation) ...@@ -1445,6 +1541,12 @@ int ha_berkeley::extra(enum ha_extra_function operation)
case HA_EXTRA_NO_KEYREAD: case HA_EXTRA_NO_KEYREAD:
key_read=0; key_read=0;
break; break;
case HA_EXTRA_IGNORE_DUP_KEY:
using_ignore=1;
break;
case HA_EXTRA_NO_IGNORE_DUP_KEY:
using_ignore=0;
break;
default: default:
break; break;
} }
...@@ -1548,6 +1650,8 @@ THR_LOCK_DATA **ha_berkeley::store_lock(THD *thd, THR_LOCK_DATA **to, ...@@ -1548,6 +1650,8 @@ THR_LOCK_DATA **ha_berkeley::store_lock(THD *thd, THR_LOCK_DATA **to,
!thd->in_lock_tables) !thd->in_lock_tables)
lock_type = TL_WRITE_ALLOW_WRITE; lock_type = TL_WRITE_ALLOW_WRITE;
lock.type=lock_type; lock.type=lock_type;
lock_on_read= ((table->reginfo.lock_type > TL_WRITE_ALLOW_READ) ? DB_RMW :
0);
} }
*to++= &lock; *to++= &lock;
return to; return to;
...@@ -1658,7 +1762,7 @@ int ha_berkeley::delete_table(const char *name) ...@@ -1658,7 +1762,7 @@ int ha_berkeley::delete_table(const char *name)
double ha_berkeley::scan_time() double ha_berkeley::scan_time()
{ {
return records/3; return records/3;
} }
ha_rows ha_berkeley::records_in_range(int keynr, ha_rows ha_berkeley::records_in_range(int keynr,
const byte *start_key,uint start_key_len, const byte *start_key,uint start_key_len,
...@@ -1811,7 +1915,7 @@ int ha_berkeley::analyze(THD* thd, HA_CHECK_OPT* check_opt) ...@@ -1811,7 +1915,7 @@ int ha_berkeley::analyze(THD* thd, HA_CHECK_OPT* check_opt)
stat=0; stat=0;
} }
if (file->stat(file, (void*) &stat, 0, 0)) if (file->stat(file, (void*) &stat, 0, 0))
goto err; goto err;
} }
pthread_mutex_lock(&share->mutex); pthread_mutex_lock(&share->mutex);
share->rows=stat->bt_ndata; share->rows=stat->bt_ndata;
......
...@@ -70,10 +70,15 @@ class ha_berkeley: public handler ...@@ -70,10 +70,15 @@ class ha_berkeley: public handler
DBT *packed_record, DBT *prim_key); DBT *packed_record, DBT *prim_key);
int remove_keys(DB_TXN *trans,const byte *record, DBT *new_record, int remove_keys(DB_TXN *trans,const byte *record, DBT *new_record,
DBT *prim_key, key_map keys, int result); DBT *prim_key, key_map keys, int result);
int restore_keys(DB_TXN *trans, key_map changed_keys, uint primary_key,
const byte *old_row, DBT *old_key,
const byte *new_row, DBT *new_key,
ulong thd_options);
int key_cmp(uint keynr, const byte * old_row, const byte * new_row); int key_cmp(uint keynr, const byte * old_row, const byte * new_row);
int update_primary_key(DB_TXN *trans, bool primary_key_changed, int update_primary_key(DB_TXN *trans, bool primary_key_changed,
const byte * old_row, const byte * new_row, const byte * old_row, DBT *old_key,
DBT *prim_key); const byte * new_row, DBT *prim_key,
ulong thd_options, bool local_using_ignore);
int read_row(int error, char *buf, uint keynr, DBT *row, DBT *key, bool); int read_row(int error, char *buf, uint keynr, DBT *row, DBT *key, bool);
DBT *get_pos(DBT *to, byte *pos); DBT *get_pos(DBT *to, byte *pos);
......
...@@ -520,7 +520,7 @@ extern ulong keybuff_size,sortbuff_size,max_item_sort_length,table_cache_size, ...@@ -520,7 +520,7 @@ extern ulong keybuff_size,sortbuff_size,max_item_sort_length,table_cache_size,
binlog_cache_size, max_binlog_cache_size; binlog_cache_size, max_binlog_cache_size;
extern ulong specialflag, current_pid; extern ulong specialflag, current_pid;
extern bool low_priority_updates; extern bool low_priority_updates;
extern bool opt_sql_bin_update; extern bool opt_sql_bin_update, opt_safe_show_db;
extern char language[LIBLEN],reg_ext[FN_EXTLEN],blob_newline; extern char language[LIBLEN],reg_ext[FN_EXTLEN],blob_newline;
extern const char **errmesg; /* Error messages */ extern const char **errmesg; /* Error messages */
extern byte last_ref[MAX_REFLENGTH]; /* Index ref of keys */ extern byte last_ref[MAX_REFLENGTH]; /* Index ref of keys */
......
...@@ -146,6 +146,33 @@ static uint handler_count; ...@@ -146,6 +146,33 @@ static uint handler_count;
static bool opt_console=0; static bool opt_console=0;
#endif #endif
#ifdef HAVE_BERKELEY_DB
SHOW_COMP_OPTION have_berkeley_db=SHOW_OPTION_YES;
#else
SHOW_COMP_OPTION have_berkeley_db=SHOW_OPTION_NO;
#endif
#ifdef HAVE_GEMENI_DB
SHOW_COMP_OPTION have_gemeni=SHOW_OPTION_YES;
#else
SHOW_COMP_OPTION have_gemeni=SHOW_OPTION_NO;
#endif
#ifdef HAVE_INNOBASE_DB
SHOW_COMP_OPTION have_innobase=SHOW_OPTION_YES;
#else
SHOW_COMP_OPTION have_innobase=SHOW_OPTION_NO;
#endif
#ifdef USE_RAID
SHOW_COMP_OPTION have_raid=SHOW_OPTION_YES;
#else
SHOW_COMP_OPTION have_raid=SHOW_OPTION_NO;
#endif
#ifdef HAVE_OPENSSL
SHOW_COMP_OPTION have_ssl=SHOW_OPTION_YES;
#else
SHOW_COMP_OPTION have_ssl=SHOW_OPTION_NO;
#endif
static bool opt_skip_slave_start = 0; // if set, slave is not autostarted static bool opt_skip_slave_start = 0; // if set, slave is not autostarted
static ulong opt_specialflag=SPECIAL_ENGLISH; static ulong opt_specialflag=SPECIAL_ENGLISH;
static my_socket unix_sock= INVALID_SOCKET,ip_sock= INVALID_SOCKET; static my_socket unix_sock= INVALID_SOCKET,ip_sock= INVALID_SOCKET;
...@@ -155,9 +182,10 @@ static my_string opt_logname=0,opt_update_logname=0, ...@@ -155,9 +182,10 @@ static my_string opt_logname=0,opt_update_logname=0,
static char mysql_home[FN_REFLEN],pidfile_name[FN_REFLEN]; static char mysql_home[FN_REFLEN],pidfile_name[FN_REFLEN];
static pthread_t select_thread; static pthread_t select_thread;
static bool opt_log,opt_update_log,opt_bin_log,opt_slow_log,opt_noacl, static bool opt_log,opt_update_log,opt_bin_log,opt_slow_log,opt_noacl,
opt_disable_networking=0, opt_bootstrap=0,opt_skip_show_db=0, opt_disable_networking=0, opt_bootstrap=0,opt_skip_show_db=0,
opt_ansi_mode=0,opt_myisam_log=0, opt_large_files=sizeof(my_off_t) > 4; opt_ansi_mode=0,opt_myisam_log=0,
bool opt_sql_bin_update = 0, opt_log_slave_updates = 0; opt_large_files=sizeof(my_off_t) > 4;
bool opt_sql_bin_update = 0, opt_log_slave_updates = 0, opt_safe_show_db=0;
FILE *bootstrap_file=0; FILE *bootstrap_file=0;
int segfaulted = 0; // ensure we do not enter SIGSEGV handler twice int segfaulted = 0; // ensure we do not enter SIGSEGV handler twice
extern MASTER_INFO glob_mi; extern MASTER_INFO glob_mi;
...@@ -2322,7 +2350,7 @@ enum options { ...@@ -2322,7 +2350,7 @@ enum options {
OPT_INNOBASE_DATA_HOME_DIR,OPT_INNOBASE_DATA_FILE_PATH, OPT_INNOBASE_DATA_HOME_DIR,OPT_INNOBASE_DATA_FILE_PATH,
OPT_INNOBASE_LOG_GROUP_HOME_DIR, OPT_INNOBASE_LOG_GROUP_HOME_DIR,
OPT_INNOBASE_LOG_ARCH_DIR, OPT_INNOBASE_LOG_ARCHIVE, OPT_INNOBASE_LOG_ARCH_DIR, OPT_INNOBASE_LOG_ARCHIVE,
OPT_INNOBASE_FLUSH_LOG_AT_TRX_COMMIT OPT_INNOBASE_FLUSH_LOG_AT_TRX_COMMIT, OPT_SAFE_SHOW_DB
}; };
static struct option long_options[] = { static struct option long_options[] = {
...@@ -2424,6 +2452,7 @@ static struct option long_options[] = { ...@@ -2424,6 +2452,7 @@ static struct option long_options[] = {
{"replicate-rewrite-db", required_argument, 0, {"replicate-rewrite-db", required_argument, 0,
(int) OPT_REPLICATE_REWRITE_DB}, (int) OPT_REPLICATE_REWRITE_DB},
{"safe-mode", no_argument, 0, (int) OPT_SAFE}, {"safe-mode", no_argument, 0, (int) OPT_SAFE},
{"safe-show-database", no_argument, 0, (int) OPT_SAFE_SHOW_DB},
{"socket", required_argument, 0, (int) OPT_SOCKET}, {"socket", required_argument, 0, (int) OPT_SOCKET},
{"server-id", required_argument, 0, (int) OPT_SERVER_ID}, {"server-id", required_argument, 0, (int) OPT_SERVER_ID},
{"set-variable", required_argument, 0, 'O'}, {"set-variable", required_argument, 0, 'O'},
...@@ -2593,6 +2622,11 @@ struct show_var_st init_vars[]= { ...@@ -2593,6 +2622,11 @@ struct show_var_st init_vars[]= {
{"delayed_queue_size", (char*) &delayed_queue_size, SHOW_LONG}, {"delayed_queue_size", (char*) &delayed_queue_size, SHOW_LONG},
{"flush", (char*) &myisam_flush, SHOW_MY_BOOL}, {"flush", (char*) &myisam_flush, SHOW_MY_BOOL},
{"flush_time", (char*) &flush_time, SHOW_LONG}, {"flush_time", (char*) &flush_time, SHOW_LONG},
{"have_bdb", (char*) &have_berkeley_db, SHOW_HAVE},
{"have_gemeni", (char*) &have_gemeni, SHOW_HAVE},
{"have_innobase", (char*) &have_innobase, SHOW_HAVE},
{"have_raid", (char*) &have_raid, SHOW_HAVE},
{"have_ssl", (char*) &have_ssl, SHOW_HAVE},
{"init_file", (char*) &opt_init_file, SHOW_CHAR_PTR}, {"init_file", (char*) &opt_init_file, SHOW_CHAR_PTR},
{"interactive_timeout", (char*) &net_interactive_timeout, SHOW_LONG}, {"interactive_timeout", (char*) &net_interactive_timeout, SHOW_LONG},
{"join_buffer_size", (char*) &join_buff_size, SHOW_LONG}, {"join_buffer_size", (char*) &join_buff_size, SHOW_LONG},
...@@ -2631,6 +2665,7 @@ struct show_var_st init_vars[]= { ...@@ -2631,6 +2665,7 @@ struct show_var_st init_vars[]= {
{"protocol_version", (char*) &protocol_version, SHOW_INT}, {"protocol_version", (char*) &protocol_version, SHOW_INT},
{"record_buffer", (char*) &my_default_record_cache_size,SHOW_LONG}, {"record_buffer", (char*) &my_default_record_cache_size,SHOW_LONG},
{"query_buffer_size", (char*) &query_buff_size, SHOW_LONG}, {"query_buffer_size", (char*) &query_buff_size, SHOW_LONG},
{"safe_show_database", (char*) &opt_safe_show_db, SHOW_BOOL},
{"server_id", (char*) &server_id, SHOW_LONG}, {"server_id", (char*) &server_id, SHOW_LONG},
{"skip_locking", (char*) &my_disable_locking, SHOW_MY_BOOL}, {"skip_locking", (char*) &my_disable_locking, SHOW_MY_BOOL},
{"skip_networking", (char*) &opt_disable_networking, SHOW_BOOL}, {"skip_networking", (char*) &opt_disable_networking, SHOW_BOOL},
...@@ -3347,11 +3382,13 @@ static void get_options(int argc,char **argv) ...@@ -3347,11 +3382,13 @@ static void get_options(int argc,char **argv)
break; break;
case OPT_BDB_SKIP: case OPT_BDB_SKIP:
berkeley_skip=1; berkeley_skip=1;
have_berkeley_db=SHOW_OPTION_DISABLED;
break; break;
#endif #endif
#ifdef HAVE_INNOBASE_DB #ifdef HAVE_INNOBASE_DB
case OPT_INNOBASE_SKIP: case OPT_INNOBASE_SKIP:
innobase_skip=1; innobase_skip=1;
have_innobase_db=SHOW_HAVE_DISABLED;
break; break;
case OPT_INNOBASE_DATA_HOME_DIR: case OPT_INNOBASE_DATA_HOME_DIR:
innobase_data_home_dir=optarg; innobase_data_home_dir=optarg;
...@@ -3410,6 +3447,9 @@ static void get_options(int argc,char **argv) ...@@ -3410,6 +3447,9 @@ static void get_options(int argc,char **argv)
case OPT_MASTER_CONNECT_RETRY: case OPT_MASTER_CONNECT_RETRY:
master_connect_retry= atoi(optarg); master_connect_retry= atoi(optarg);
break; break;
case (int) OPT_SAFE_SHOW_DB:
opt_safe_show_db=1;
break;
default: default:
fprintf(stderr,"%s: Unrecognized option: %c\n",my_progname,c); fprintf(stderr,"%s: Unrecognized option: %c\n",my_progname,c);
......
...@@ -75,10 +75,17 @@ mysqld_show_dbs(THD *thd,const char *wild) ...@@ -75,10 +75,17 @@ mysqld_show_dbs(THD *thd,const char *wild)
List_iterator<char> it(files); List_iterator<char> it(files);
while ((file_name=it++)) while ((file_name=it++))
{ {
thd->packet.length(0); if (!opt_safe_show_db || thd->master_access ||
net_store_data(&thd->packet,file_name); acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr,
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length())) thd->priv_user, file_name) ||
DBUG_RETURN(-1); (grant_option && !check_grant_db(thd, file_name)))
{
thd->packet.length(0);
net_store_data(&thd->packet,file_name);
if (my_net_write(&thd->net, (char*) thd->packet.ptr(),
thd->packet.length()))
DBUG_RETURN(-1);
}
} }
send_eof(&thd->net); send_eof(&thd->net);
DBUG_RETURN(0); DBUG_RETURN(0);
...@@ -1086,6 +1093,14 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables) ...@@ -1086,6 +1093,14 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables)
case SHOW_INT: case SHOW_INT:
net_store_data(&packet2,(uint32) *(int*) variables[i].value); net_store_data(&packet2,(uint32) *(int*) variables[i].value);
break; break;
case SHOW_HAVE:
{
SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) variables[i].value;
net_store_data(&packet2, (tmp == SHOW_OPTION_NO ? "NO" :
tmp == SHOW_OPTION_YES ? "YES" :
"DISABLED"));
break;
}
case SHOW_CHAR: case SHOW_CHAR:
net_store_data(&packet2,variables[i].value); net_store_data(&packet2,variables[i].value);
break; break;
......
...@@ -1658,7 +1658,8 @@ copy_data_between_tables(TABLE *from,TABLE *to, ...@@ -1658,7 +1658,8 @@ copy_data_between_tables(TABLE *from,TABLE *to,
}; };
init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1,1); init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1,1);
if (handle_duplicates == DUP_IGNORE) if (handle_duplicates == DUP_IGNORE ||
handle_duplicates == DUP_REPLACE)
to->file->extra(HA_EXTRA_IGNORE_DUP_KEY); to->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
next_field=to->next_number_field; next_field=to->next_number_field;
while (!(error=info.read_record(&info))) while (!(error=info.read_record(&info)))
...@@ -1675,7 +1676,8 @@ copy_data_between_tables(TABLE *from,TABLE *to, ...@@ -1675,7 +1676,8 @@ copy_data_between_tables(TABLE *from,TABLE *to,
copy_ptr->do_copy(copy_ptr); copy_ptr->do_copy(copy_ptr);
if ((error=to->file->write_row((byte*) to->record[0]))) if ((error=to->file->write_row((byte*) to->record[0])))
{ {
if (handle_duplicates != DUP_IGNORE || if ((handle_duplicates != DUP_IGNORE &&
handle_duplicates != DUP_REPLACE) ||
(error != HA_ERR_FOUND_DUPP_KEY && (error != HA_ERR_FOUND_DUPP_KEY &&
error != HA_ERR_FOUND_DUPP_UNIQUE)) error != HA_ERR_FOUND_DUPP_UNIQUE))
{ {
......
...@@ -125,7 +125,9 @@ typedef struct { ...@@ -125,7 +125,9 @@ typedef struct {
enum SHOW_TYPE { SHOW_LONG,SHOW_CHAR,SHOW_INT,SHOW_CHAR_PTR,SHOW_BOOL, enum SHOW_TYPE { SHOW_LONG,SHOW_CHAR,SHOW_INT,SHOW_CHAR_PTR,SHOW_BOOL,
SHOW_MY_BOOL,SHOW_OPENTABLES,SHOW_STARTTIME,SHOW_QUESTION, SHOW_MY_BOOL,SHOW_OPENTABLES,SHOW_STARTTIME,SHOW_QUESTION,
SHOW_LONG_CONST, SHOW_INT_CONST}; SHOW_LONG_CONST, SHOW_INT_CONST, SHOW_HAVE};
enum SHOW_COMP_OPTION { SHOW_OPTION_YES, SHOW_OPTION_NO, SHOW_OPTION_DISABLED};
struct show_var_st { struct show_var_st {
const char *name; const char *name;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment