summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <monty@mashka.mysql.fi>2003-01-09 22:43:23 +0200
committerunknown <monty@mashka.mysql.fi>2003-01-09 22:43:23 +0200
commit91f18f0a26e3714bd9edc78b1c6fe7a1fd243167 (patch)
tree5ffbc6660efade54ba4bc490d83c1538515feb3e /sql
parentac2aea8c4a36175e844bbc884dfd5d38167cf181 (diff)
parentf7ff1cca148b8cb0742f3d23c0e05e797c673dc0 (diff)
downloadmariadb-git-91f18f0a26e3714bd9edc78b1c6fe7a1fd243167.tar.gz
Merge work:/home/bk/mysql-4.1 into mashka.mysql.fi:/home/my/mysql-4.1
innobase/mem/mem0pool.c: Auto merged sql/sql_lex.cc: Auto merged sql/sql_select.cc: Auto merged sql/sql_show.cc: Auto merged sql/sql_yacc.yy: Auto merged
Diffstat (limited to 'sql')
-rw-r--r--sql/lex.h1
-rw-r--r--sql/log_event.cc65
-rw-r--r--sql/log_event.h5
-rw-r--r--sql/mysql_priv.h5
-rw-r--r--sql/mysqld.cc43
-rw-r--r--sql/opt_range.cc4
-rw-r--r--sql/protocol.cc5
-rw-r--r--sql/slave.cc8
-rw-r--r--sql/sql_base.cc6
-rw-r--r--sql/sql_lex.cc8
-rw-r--r--sql/sql_lex.h7
-rw-r--r--sql/sql_parse.cc33
-rw-r--r--sql/sql_select.cc3
-rw-r--r--sql/sql_show.cc2
-rw-r--r--sql/sql_yacc.yy65
-rw-r--r--sql/table.h2
16 files changed, 195 insertions, 67 deletions
diff --git a/sql/lex.h b/sql/lex.h
index 2ddc540991b..a505911ccf6 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -161,6 +161,7 @@ static SYMBOL symbols[] = {
{ "FLUSH", SYM(FLUSH_SYM),0,0},
{ "FALSE", SYM(FALSE_SYM),0,0},
{ "FOREIGN", SYM(FOREIGN),0,0},
+ { "FORCE", SYM(FORCE_SYM),0,0},
{ "RAID_TYPE", SYM(RAID_TYPE),0,0},
{ "RAID_CHUNKS", SYM(RAID_CHUNKS),0,0},
{ "RAID_CHUNKSIZE", SYM(RAID_CHUNKSIZE),0,0},
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 8f98fa511a0..d025f8a57a7 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -294,7 +294,19 @@ Log_event::Log_event(const char* buf, bool old_format)
****************************************************************************/
int Log_event::exec_event(struct st_relay_log_info* rli)
{
- if (rli) // QQ When is this not true ?
+ /*
+ rli is null when (as far as I (Guilhem) know)
+ the caller is
+ Load_log_event::exec_event *and* that one is called from
+ Execute_load_log_event::exec_event.
+ In this case, we don't do anything here ;
+ Execute_load_log_event::exec_event will call Log_event::exec_event
+ again later with the proper rli.
+ Strictly speaking, if we were sure that rli is null
+ only in the case discussed above, 'if (rli)' is useless here.
+ But as we are not 100% sure, keep it for now.
+ */
+ if (rli)
{
if (rli->inside_transaction)
rli->inc_pending(get_event_len());
@@ -1435,13 +1447,36 @@ void Load_log_event::set_fields(List<Item> &field_list)
}
#endif // !MYSQL_CLIENT
-/*****************************************************************************
-
- Load_log_event::exec_event()
-
- ****************************************************************************/
#ifndef MYSQL_CLIENT
-int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli)
+
+/*
+ Does the data loading job when executing a LOAD DATA on the slave
+
+ SYNOPSIS
+ Load_log_event::exec_event
+ net
+ rli
+ use_rli_only_for_errors - if set to 1, rli is provided to
+ Load_log_event::exec_event only for this
+ function to have RPL_LOG_NAME and
+ rli->last_slave_error, both being used by
+ error reports. rli's position advancing
+ is skipped (done by the caller which is
+ Execute_load_log_event::exec_event).
+ - if set to 0, rli is provided for full use,
+ i.e. for error reports and position
+ advancing.
+
+ DESCRIPTION
+ Does the data loading job when executing a LOAD DATA on the slave
+
+ RETURN VALUE
+ 0 Success
+ 1 Failure
+*/
+
+int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
+ bool use_rli_only_for_errors)
{
init_sql_alloc(&thd->mem_root, 8192,0);
thd->db = rewrite_db((char*)db);
@@ -1503,9 +1538,15 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli)
TL_WRITE))
thd->query_error = 1;
if (thd->cuted_fields)
+ {
+ /*
+ log_pos is the position of the LOAD
+ event in the master log
+ */
sql_print_error("Slave: load data infile at position %s in log \
-'%s' produced %d warning(s)", llstr(rli->master_log_pos,llbuff), RPL_LOG_NAME,
+'%s' produced %d warning(s)", llstr(log_pos,llbuff), RPL_LOG_NAME,
thd->cuted_fields );
+ }
if (net)
net->pkt_nr= thd->net.pkt_nr;
}
@@ -1544,7 +1585,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli)
return 1;
}
- return Log_event::exec_event(rli);
+ return ( use_rli_only_for_errors ? 0 : Log_event::exec_event(rli) );
}
#endif // !MYSQL_CLIENT
@@ -2680,7 +2721,11 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli)
save_options = thd->options;
thd->options &= ~ (ulong) (OPTION_BIN_LOG);
lev->thd = thd;
- if (lev->exec_event(0,0))
+ /*
+ lev->exec_event should use rli only for errors
+ i.e. should not advance rli's position
+ */
+ if (lev->exec_event(0,rli,1))
{
slave_print_error(rli,my_errno, "Failed executing load from '%s'", fname);
thd->options = save_options;
diff --git a/sql/log_event.h b/sql/log_event.h
index ec3b4819e74..80c448e1550 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -460,9 +460,10 @@ public:
const char* get_db() { return db; }
int exec_event(struct st_relay_log_info* rli)
{
- return exec_event(thd->slave_net,rli);
+ return exec_event(thd->slave_net,rli,0);
}
- int exec_event(NET* net, struct st_relay_log_info* rli);
+ int exec_event(NET* net, struct st_relay_log_info* rli,
+ bool use_rli_only_for_errors);
#else
void print(FILE* file, bool short_form = 0, char* last_db = 0);
#endif
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 655e4d7b972..cdc668d9b28 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -235,6 +235,10 @@ void debug_sync_point(const char* lock_name, uint lock_timeout);
#define SHOW_LOG_STATUS_FREE "FREE"
#define SHOW_LOG_STATUS_INUSE "IN USE"
+/* Options to add_table_to_list() */
+#define TL_OPTION_UPDATING 1
+#define TL_OPTION_FORCE_INDEX 2
+
/* Some portable defines */
#define portable_sizeof_char_ptr 8
@@ -820,7 +824,6 @@ uint calc_week(TIME *ltime, bool with_year, bool sunday_first_day_of_week,
void find_date(char *pos,uint *vek,uint flag);
TYPELIB *convert_strings_to_array_type(my_string *typelibs, my_string *end);
TYPELIB *typelib(List<String> &strings);
-void clean_up(bool print_message=1);
ulong get_form_pos(File file, uchar *head, TYPELIB *save_names);
ulong make_new_entry(File file,uchar *fileinfo,TYPELIB *formnames,
const char *newname);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index d6a5c0b8412..f66122e72a6 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -491,6 +491,7 @@ extern "C" pthread_handler_decl(handle_slave,arg);
static uint set_maximum_open_files(uint max_file_limit);
#endif
static ulong find_bit_type(const char *x, TYPELIB *bit_lib);
+static void clean_up(bool print_message);
/****************************************************************************
** Code to end mysqld
@@ -763,13 +764,13 @@ void kill_mysql(void)
#if defined(OS2)
extern "C" void kill_server(int sig_ptr)
-#define RETURN_FROM_KILL_SERVER return
+#define RETURN_FROM_KILL_SERVER DBUG_RETURN
#elif !defined(__WIN__)
static void *kill_server(void *sig_ptr)
-#define RETURN_FROM_KILL_SERVER return 0
+#define RETURN_FROM_KILL_SERVER DBUG_RETURN(0)
#else
static void __cdecl kill_server(int sig_ptr)
-#define RETURN_FROM_KILL_SERVER return
+#define RETURN_FROM_KILL_SERVER DBUG_RETURN
#endif
{
int sig=(int) (long) sig_ptr; // This is passed a int
@@ -848,7 +849,7 @@ extern "C" sig_handler print_signal_warning(int sig)
void unireg_end(void)
{
- clean_up();
+ clean_up(1);
my_thread_end();
#ifdef SIGNALS_DONT_BREAK_READ
exit(0);
@@ -863,7 +864,7 @@ extern "C" void unireg_abort(int exit_code)
DBUG_ENTER("unireg_abort");
if (exit_code)
sql_print_error("Aborting\n");
- clean_up(); /* purecov: inspected */
+ clean_up(1); /* purecov: inspected */
DBUG_PRINT("quit",("done with cleanup in unireg_abort"));
my_thread_end();
exit(exit_code); /* purecov: inspected */
@@ -908,12 +909,12 @@ void clean_up(bool print_message)
regex_end();
#endif
+ if (print_message && errmesg)
+ sql_print_error(ER(ER_SHUTDOWN_COMPLETE),my_progname);
#if !defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
if (!opt_bootstrap)
(void) my_delete(pidfile_name,MYF(0)); // This may not always exist
#endif
- if (print_message && errmesg)
- sql_print_error(ER(ER_SHUTDOWN_COMPLETE),my_progname);
x_free((gptr) my_errmsg[ERRMAPP]); /* Free messages */
DBUG_PRINT("quit", ("Error messages freed"));
/* Tell main we are ready */
@@ -923,6 +924,10 @@ void clean_up(bool print_message)
/* do the broadcast inside the lock to ensure that my_end() is not called */
(void) pthread_cond_broadcast(&COND_thread_count);
(void) pthread_mutex_unlock(&LOCK_thread_count);
+ /*
+ The following lines may never be executed as the main thread may have
+ killed us
+ */
DBUG_PRINT("quit", ("done with cleanup"));
} /* clean_up */
@@ -1502,7 +1507,7 @@ static void init_signals(void)
/* Change limits so that we will get a core file */
struct rlimit rl;
rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
- if (setrlimit(RLIMIT_CORE, &rl))
+ if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
sql_print_error("Warning: setrlimit could not change the size of core files to 'infinity'; We may not be able to generate a core file on signals");
}
#endif
@@ -1571,8 +1576,11 @@ extern "C" void *signal_hand(void *arg __attribute__((unused)))
my_thread_init(); // Init new thread
DBUG_ENTER("signal_hand");
SIGNAL_THD;
- /* Setup alarm handler */
- init_thr_alarm(max_connections+max_insert_delayed_threads);
+ /*
+ Setup alarm handler
+ The two extra handlers are for slave threads
+ */
+ init_thr_alarm(max_connections+max_insert_delayed_threads+2);
#if SIGINT != THR_KILL_SIGNAL
(void) sigemptyset(&set); // Setup up SIGINT for debug
(void) sigaddset(&set,SIGINT); // For debugging
@@ -1660,12 +1668,15 @@ extern "C" void *signal_hand(void *arg __attribute__((unused)))
}
break;
case SIGHUP:
- reload_acl_and_cache((THD*) 0,
- (REFRESH_LOG | REFRESH_TABLES | REFRESH_FAST |
- REFRESH_STATUS | REFRESH_GRANT | REFRESH_THREADS |
- REFRESH_HOSTS),
- (TABLE_LIST*) 0); // Flush logs
- mysql_print_status((THD*) 0); // Send debug some info
+ if (!abort_loop)
+ {
+ reload_acl_and_cache((THD*) 0,
+ (REFRESH_LOG | REFRESH_TABLES | REFRESH_FAST |
+ REFRESH_STATUS | REFRESH_GRANT |
+ REFRESH_THREADS | REFRESH_HOSTS),
+ (TABLE_LIST*) 0); // Flush logs
+ mysql_print_status((THD*) 0); // Send debug some info
+ }
break;
#ifdef USE_ONE_SIGNAL_HAND
case THR_SERVER_ALARM:
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 887ce6c561a..0adde4d39e0 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -603,12 +603,14 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables,
records++; /* purecov: inspected */
scan_time=(double) records / TIME_FOR_COMPARE+1;
read_time=(double) head->file->scan_time()+ scan_time + 1.0;
+ if (head->force_index)
+ scan_time= read_time= DBL_MAX;
if (limit < records)
read_time=(double) records+scan_time+1; // Force to use index
else if (read_time <= 2.0 && !force_quick_range)
DBUG_RETURN(0); /* No need for quick select */
- DBUG_PRINT("info",("Time to scan table: %ld",(long) read_time));
+ DBUG_PRINT("info",("Time to scan table: %g", read_time));
keys_to_use&=head->keys_in_use_for_query;
if (keys_to_use)
diff --git a/sql/protocol.cc b/sql/protocol.cc
index 15f4ca9ad94..48ef9ecb71e 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -171,7 +171,10 @@ net_printf(THD *thd, uint errcode, ...)
{
if (thd->bootstrap)
{
- /* In bootstrap it's ok to print on stderr */
+ /*
+ In bootstrap it's ok to print on stderr
+ This may also happen when we get an error from a slave thread
+ */
fprintf(stderr,"ERROR: %d %s\n",errcode,text_pos);
thd->fatal_error=1;
}
diff --git a/sql/slave.cc b/sql/slave.cc
index 342a35b8821..271fe8bc2d6 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -413,6 +413,7 @@ int terminate_slave_threads(MASTER_INFO* mi,int thread_mask,bool skip_lock)
}
if ((thread_mask & (SLAVE_IO|SLAVE_FORCE_ALL)) && mi->slave_running)
{
+ DBUG_PRINT("info",("Terminating IO thread"));
mi->abort_slave=1;
if ((error=terminate_slave_thread(mi->io_thd,io_lock,
io_cond_lock,
@@ -423,6 +424,7 @@ int terminate_slave_threads(MASTER_INFO* mi,int thread_mask,bool skip_lock)
}
if ((thread_mask & (SLAVE_SQL|SLAVE_FORCE_ALL)) && mi->rli.slave_running)
{
+ DBUG_PRINT("info",("Terminating SQL thread"));
DBUG_ASSERT(mi->rli.sql_thd != 0) ;
mi->rli.abort_slave=1;
if ((error=terminate_slave_thread(mi->rli.sql_thd,sql_lock,
@@ -2572,12 +2574,6 @@ static int process_io_rotate(MASTER_INFO *mi, Rotate_log_event *rev)
memcpy(mi->master_log_name, rev->new_log_ident, rev->ident_len+1);
mi->master_log_pos= rev->pos;
-
- pthread_mutex_lock(&mi->rli.data_lock);
- memcpy(mi->rli.master_log_name, rev->new_log_ident, rev->ident_len+1);
- mi->rli.master_log_pos= rev->pos;
- pthread_mutex_unlock(&mi->rli.data_lock);
-
DBUG_PRINT("info", ("master_log_pos: '%s' %d",
mi->master_log_name, (ulong) mi->master_log_pos));
#ifndef DBUG_OFF
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index b5178076258..a384e723e32 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -747,7 +747,7 @@ TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
table->tablenr=thd->current_tablenr++;
table->used_fields=0;
table->const_table=0;
- table->outer_join=table->null_row=table->maybe_null=0;
+ table->outer_join= table->null_row= table->maybe_null= table->force_index= 0;
table->status=STATUS_NO_RECORD;
table->keys_in_use_for_query= table->keys_in_use;
table->used_keys= table->keys_for_keyread;
@@ -906,7 +906,7 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
table->tablenr=thd->current_tablenr++;
table->used_fields=0;
table->const_table=0;
- table->outer_join=table->null_row=table->maybe_null=0;
+ table->outer_join= table->null_row= table->maybe_null= table->force_index= 0;
table->status=STATUS_NO_RECORD;
table->keys_in_use_for_query= table->keys_in_use;
table->used_keys= table->keys_for_keyread;
@@ -977,6 +977,7 @@ bool reopen_table(TABLE *table,bool locked)
tmp.status= table->status;
tmp.keys_in_use_for_query= tmp.keys_in_use;
tmp.used_keys= tmp.keys_for_keyread;
+ tmp.force_index= tmp.force_index;
/* Get state */
tmp.key_length= table->key_length;
@@ -1969,6 +1970,7 @@ bool setup_tables(TABLE_LIST *tables)
table->maybe_null=test(table->outer_join=table_list->outer_join);
table->tablenr=tablenr;
table->map= (table_map) 1 << tablenr;
+ table->force_index= table_list->force_index;
if (table_list->use_index)
{
key_map map= get_key_map_from_key_list(table,
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index c7c7a97cdc2..dda3d4e822e 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1171,13 +1171,14 @@ List<String>* st_select_lex_node::get_use_index() { return 0; }
List<String>* st_select_lex_node::get_ignore_index() { return 0; }
TABLE_LIST *st_select_lex_node::add_table_to_list(THD *thd, Table_ident *table,
LEX_STRING *alias,
- bool updating,
+ ulong table_join_options,
thr_lock_type flags,
List<String> *use_index,
List<String> *ignore_index)
{
return 0;
}
+ulong st_select_lex_node::get_table_join_options() { return 0; }
/*
This is used for UNION & subselect to create a new table list of all used
@@ -1334,6 +1335,11 @@ List<String>* st_select_lex::get_ignore_index()
return ignore_index_ptr;
}
+ulong st_select_lex::get_table_join_options()
+{
+ return table_join_options;
+}
+
/*
There are st_select_lex::add_table_to_list &
st_select_lex::set_lock_for_tables in sql_parse.cc
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 9b8f4a47515..4b6ac927f07 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -243,9 +243,10 @@ public:
virtual List<Item>* get_item_list();
virtual List<String>* get_use_index();
virtual List<String>* get_ignore_index();
+ virtual ulong get_table_join_options();
virtual TABLE_LIST *add_table_to_list(THD *thd, Table_ident *table,
LEX_STRING *alias,
- bool updating,
+ ulong table_options,
thr_lock_type flags= TL_UNLOCK,
List<String> *use_index= 0,
List<String> *ignore_index= 0);
@@ -336,6 +337,7 @@ public:
List<Item_func_match> ftfunc_list_alloc;
JOIN *join; /* after JOIN::prepare it is pointer to corresponding JOIN */
const char *type; /* type of select for EXPLAIN */
+ ulong table_join_options;
uint in_sum_expr;
uint select_number; /* number of select (used for EXPLAIN) */
bool braces; /* SELECT ... UNION (SELECT ... ) <- this braces */
@@ -373,9 +375,10 @@ public:
List<Item>* get_item_list();
List<String>* get_use_index();
List<String>* get_ignore_index();
+ ulong get_table_join_options();
TABLE_LIST* add_table_to_list(THD *thd, Table_ident *table,
LEX_STRING *alias,
- bool updating,
+ ulong table_options,
thr_lock_type flags= TL_UNLOCK,
List<String> *use_index= 0,
List<String> *ignore_index= 0);
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index f6e21e421d9..81fb5a6d12c 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -518,7 +518,8 @@ check_connections(THD *thd)
vio_in_addr(net->vio,&thd->remote.sin_addr);
thd->host=ip_to_hostname(&thd->remote.sin_addr,&connect_errors);
/* Cut very long hostnames to avoid possible overflows */
- thd->host[min(strlen(thd->host), HOSTNAME_LENGTH)]= 0;
+ if (thd->host)
+ thd->host[min(strlen(thd->host), HOSTNAME_LENGTH)]= 0;
if (connect_errors > max_connect_errors)
return(ER_HOST_IS_BLOCKED);
}
@@ -3597,11 +3598,30 @@ bool add_to_list(THD *thd, SQL_LIST &list,Item *item,bool asc)
}
+/*
+ Add a table to list of used tables
+
+ SYNOPSIS
+ add_table_to_list()
+ table Table to add
+ alias alias for table (or null if no alias)
+ table_options A set of the following bits:
+ TL_OPTION_UPDATING Table will be updated
+ TL_OPTION_FORCE_INDEX Force usage of index
+ lock_type How table should be locked
+ use_index List of indexed used in USE INDEX
+ ignore_index List of indexed used in IGNORE INDEX
+
+ RETURN
+ 0 Error
+ # Pointer to TABLE_LIST element added to the total table list
+*/
+
TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
Table_ident *table,
LEX_STRING *alias,
- bool updating,
- thr_lock_type flags,
+ ulong table_options,
+ thr_lock_type lock_type,
List<String> *use_index,
List<String> *ignore_index)
{
@@ -3658,8 +3678,9 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
}
ptr->real_name=table->table.str;
ptr->real_name_length=table->table.length;
- ptr->lock_type=flags;
- ptr->updating=updating;
+ ptr->lock_type= lock_type;
+ ptr->updating= test(table_options & TL_OPTION_UPDATING);
+ ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX);
ptr->derived= (SELECT_LEX_UNIT *) table->sel;
if (use_index)
ptr->use_index=(List<String> *) thd->memdup((gptr) use_index,
@@ -3669,7 +3690,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
sizeof(*ignore_index));
/* check that used name is unique */
- if (flags != TL_IGNORE)
+ if (lock_type != TL_IGNORE)
{
for (TABLE_LIST *tables=(TABLE_LIST*) table_list.first ;
tables ;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index e7784cad04d..aab8d883204 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -2305,7 +2305,8 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
!(s->quick && best_key && s->quick->index == best_key->key &&
best_max_key_part >= s->table->quick_key_parts[best_key->key]) &&
!((s->table->file->table_flags() & HA_TABLE_SCAN_ON_INDEX) &&
- s->table->used_keys && best_key))
+ s->table->used_keys && best_key) &&
+ !(s->table->force_index && best_key))
{ // Check full join
if (s->on_expr)
{
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index b01555effa8..281fa92de6a 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1497,6 +1497,7 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables,
case SHOW_RPL_STATUS:
end= strmov(buff, rpl_status_type[(int)rpl_status]);
break;
+#ifndef EMBEDDED_LIBRARY
case SHOW_SLAVE_RUNNING:
{
LOCK_ACTIVE_MI;
@@ -1505,6 +1506,7 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables,
UNLOCK_ACTIVE_MI;
break;
}
+#endif
case SHOW_OPENTABLES:
end= int10_to_str((long) cached_tables(), buff, 10);
break;
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index e83b4da728f..8fa17f0d5ed 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2001 MySQL AB
+/* Copyright (C) 2000-2003 MySQL AB
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
@@ -222,6 +222,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token FIRST_SYM
%token FIXED_SYM
%token FLOAT_NUM
+%token FORCE_SYM
%token FOREIGN
%token FROM
%token FULL
@@ -823,7 +824,8 @@ create:
($2 &
HA_LEX_CREATE_TMP_TABLE ?
&tmp_table_alias :
- (LEX_STRING*) 0),1,
+ (LEX_STRING*) 0),
+ TL_OPTION_UPDATING,
((using_update_log)?
TL_READ_NO_INSERT:
TL_READ)))
@@ -844,7 +846,8 @@ create:
{
LEX *lex=Lex;
lex->sql_command= SQLCOM_CREATE_INDEX;
- if (!lex->current_select->add_table_to_list(lex->thd, $7,NULL,1))
+ if (!lex->current_select->add_table_to_list(lex->thd, $7, NULL,
+ TL_OPTION_UPDATING))
YYABORT;
lex->create_list.empty();
lex->key_list.empty();
@@ -1380,6 +1383,7 @@ opt_unique_or_fulltext:
key_alg:
/* empty */ { $$= HA_KEY_ALG_UNDEF; }
| USING opt_btree_or_rtree { $$= $2; };
+ | TYPE_SYM opt_btree_or_rtree { $$= $2; };
opt_btree_or_rtree:
BTREE_SYM { $$= HA_KEY_ALG_BTREE; }
@@ -1413,7 +1417,8 @@ alter:
LEX *lex=&thd->lex;
lex->sql_command = SQLCOM_ALTER_TABLE;
lex->name=0;
- if (!lex->select_lex.add_table_to_list(thd, $4, NULL,1))
+ if (!lex->select_lex.add_table_to_list(thd, $4, NULL,
+ TL_OPTION_UPDATING))
YYABORT;
lex->drop_primary=0;
lex->create_list.empty();
@@ -1679,8 +1684,10 @@ table_to_table:
{
LEX *lex=Lex;
SELECT_LEX_NODE *sl= lex->current_select;
- if (!sl->add_table_to_list(lex->thd, $1,NULL,1,TL_IGNORE) ||
- !sl->add_table_to_list(lex->thd, $3,NULL,1,TL_IGNORE))
+ if (!sl->add_table_to_list(lex->thd, $1,NULL,TL_OPTION_UPDATING,
+ TL_IGNORE) ||
+ !sl->add_table_to_list(lex->thd, $3,NULL,TL_OPTION_UPDATING,
+ TL_IGNORE))
YYABORT;
};
@@ -2532,12 +2539,14 @@ join_table:
{
SELECT_LEX *sel= Select->select_lex();
sel->use_index_ptr=sel->ignore_index_ptr=0;
+ sel->table_join_options= 0;
}
table_ident opt_table_alias opt_key_definition
{
LEX *lex= Lex;
SELECT_LEX_NODE *sel= lex->current_select;
- if (!($$= sel->add_table_to_list(lex->thd, $2, $3, 0,
+ if (!($$= sel->add_table_to_list(lex->thd, $2, $3,
+ sel->get_table_join_options(),
lex->lock_option,
sel->get_use_index(),
sel->get_ignore_index())))
@@ -2583,6 +2592,13 @@ opt_key_definition:
sel->use_index= *$2;
sel->use_index_ptr= &sel->use_index;
}
+ | FORCE_SYM key_usage_list
+ {
+ SELECT_LEX *sel= Select->select_lex();
+ sel->use_index= *$2;
+ sel->use_index_ptr= &sel->use_index;
+ sel->table_join_options|= TL_OPTION_FORCE_INDEX;
+ }
| IGNORE_SYM key_usage_list
{
SELECT_LEX *sel= Select->select_lex();
@@ -2592,8 +2608,14 @@ opt_key_definition:
key_usage_list:
key_or_index { Select->select_lex()->interval_list.empty(); }
- '(' key_usage_list2 ')'
- { $$= &Select->select_lex()->interval_list; };
+ '(' key_list_or_empty ')'
+ { $$= &Select->select_lex()->interval_list; }
+ ;
+
+key_list_or_empty:
+ /* empty */ {}
+ | key_usage_list2 {}
+ ;
key_usage_list2:
key_usage_list2 ',' ident
@@ -2954,7 +2976,8 @@ drop:
lex->drop_list.empty();
lex->drop_list.push_back(new Alter_drop(Alter_drop::KEY,
$3.str));
- if (!lex->current_select->add_table_to_list(lex->thd, $5,NULL, 1))
+ if (!lex->current_select->add_table_to_list(lex->thd, $5, NULL,
+ TL_OPTION_UPDATING))
YYABORT;
}
| DROP DATABASE if_exists ident
@@ -2978,7 +3001,11 @@ table_list:
table_name:
table_ident
- { if (!Select->add_table_to_list(YYTHD, $1, NULL, 1)) YYABORT; };
+ {
+ if (!Select->add_table_to_list(YYTHD, $1, NULL, TL_OPTION_UPDATING))
+ YYABORT;
+ }
+ ;
if_exists:
/* empty */ { $$= 0; }
@@ -3213,7 +3240,8 @@ delete:
single_multi:
FROM table_ident
{
- if (!Select->add_table_to_list(YYTHD, $2, NULL, 1, Lex->lock_option))
+ if (!Select->add_table_to_list(YYTHD, $2, NULL, TL_OPTION_UPDATING,
+ Lex->lock_option))
YYABORT;
}
where_clause opt_order_clause
@@ -3234,14 +3262,15 @@ table_wild_list:
table_wild_one:
ident opt_wild opt_table_alias
{
- if (!Select->add_table_to_list(YYTHD, new Table_ident($1), $3, 1,
- Lex->lock_option))
+ if (!Select->add_table_to_list(YYTHD, new Table_ident($1), $3,
+ TL_OPTION_UPDATING, Lex->lock_option))
YYABORT;
}
| ident '.' ident opt_wild opt_table_alias
{
if (!Select->add_table_to_list(YYTHD, new Table_ident($1, $3, 0),
- $5, 1, Lex->lock_option))
+ $5, TL_OPTION_UPDATING,
+ Lex->lock_option))
YYABORT;
}
;
@@ -3405,7 +3434,7 @@ show_param:
| CREATE TABLE_SYM table_ident
{
Lex->sql_command = SQLCOM_SHOW_CREATE;
- if(!Select->add_table_to_list(YYTHD, $3, NULL,0))
+ if (!Select->add_table_to_list(YYTHD, $3, NULL,0))
YYABORT;
}
| MASTER_SYM STATUS_SYM
@@ -3574,14 +3603,14 @@ load: LOAD DATA_SYM load_data_lock opt_local INFILE TEXT_STRING
opt_duplicate INTO TABLE_SYM table_ident opt_field_term opt_line_term
opt_ignore_lines opt_field_spec
{
- if (!Select->add_table_to_list(YYTHD, $11, NULL, 1))
+ if (!Select->add_table_to_list(YYTHD, $11, NULL, TL_OPTION_UPDATING))
YYABORT;
}
|
LOAD TABLE_SYM table_ident FROM MASTER_SYM
{
Lex->sql_command = SQLCOM_LOAD_MASTER_TABLE;
- if (!Select->add_table_to_list(YYTHD, $3, NULL, 1))
+ if (!Select->add_table_to_list(YYTHD, $3, NULL, TL_OPTION_UPDATING))
YYABORT;
}
diff --git a/sql/table.h b/sql/table.h
index d24e4e1e422..6291b250787 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -91,6 +91,7 @@ struct st_table {
my_bool copy_blobs; /* copy_blobs when storing */
my_bool null_row; /* All columns are null */
my_bool maybe_null,outer_join; /* Used with OUTER JOIN */
+ my_bool force_index;
my_bool distinct,const_table,no_rows;
my_bool key_read, bulk_insert;
my_bool crypted;
@@ -168,6 +169,7 @@ typedef struct st_table_list
bool straight; /* optimize with prev table */
bool updating; /* for replicate-do/ignore table */
bool do_redirect; /* To get the struct in UNION's */
+ bool force_index; /* Prefer index over table scan */
} TABLE_LIST;
typedef struct st_changed_table_list