diff options
author | unknown <monty@mashka.mysql.fi> | 2003-01-09 22:43:23 +0200 |
---|---|---|
committer | unknown <monty@mashka.mysql.fi> | 2003-01-09 22:43:23 +0200 |
commit | 91f18f0a26e3714bd9edc78b1c6fe7a1fd243167 (patch) | |
tree | 5ffbc6660efade54ba4bc490d83c1538515feb3e /sql | |
parent | ac2aea8c4a36175e844bbc884dfd5d38167cf181 (diff) | |
parent | f7ff1cca148b8cb0742f3d23c0e05e797c673dc0 (diff) | |
download | mariadb-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.h | 1 | ||||
-rw-r--r-- | sql/log_event.cc | 65 | ||||
-rw-r--r-- | sql/log_event.h | 5 | ||||
-rw-r--r-- | sql/mysql_priv.h | 5 | ||||
-rw-r--r-- | sql/mysqld.cc | 43 | ||||
-rw-r--r-- | sql/opt_range.cc | 4 | ||||
-rw-r--r-- | sql/protocol.cc | 5 | ||||
-rw-r--r-- | sql/slave.cc | 8 | ||||
-rw-r--r-- | sql/sql_base.cc | 6 | ||||
-rw-r--r-- | sql/sql_lex.cc | 8 | ||||
-rw-r--r-- | sql/sql_lex.h | 7 | ||||
-rw-r--r-- | sql/sql_parse.cc | 33 | ||||
-rw-r--r-- | sql/sql_select.cc | 3 | ||||
-rw-r--r-- | sql/sql_show.cc | 2 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 65 | ||||
-rw-r--r-- | sql/table.h | 2 |
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 |