diff options
Diffstat (limited to 'sql')
74 files changed, 3190 insertions, 2310 deletions
diff --git a/sql/field.cc b/sql/field.cc index 75cbedbb71b..39e32a9cdc4 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -63,8 +63,8 @@ const char field_separator=','; *****************************************************************************/ /* - ** Calculate length of number and its parts - ** Increment cuted_fields if wrong number + Calculate length of number and its parts + Increment cuted_fields if wrong number */ static bool @@ -233,6 +233,8 @@ Field::Field(char *ptr_arg,uint32 length_arg,uchar *null_ptr_arg, field_length(length_arg),null_bit(null_bit_arg) { flags=null_ptr ? 0: NOT_NULL_FLAG; + comment.str= (char*) ""; + comment.length=0; } uint Field::offset() @@ -384,13 +386,34 @@ Field_decimal::reset(void) void Field_decimal::overflow(bool negative) { uint len=field_length; - char *to=ptr; - if (negative && !unsigned_flag) + char *to=ptr, filler= '9'; + if (negative) { - *to++ = '-'; - len--; + if (!unsigned_flag) + { + /* Put - sign as a first digit so we'll have -999..999 or 999..999 */ + *to++ = '-'; + len--; + } + else + { + filler= '0'; // Fill up with 0 + if (!zerofill) + { + /* + Handle unsigned integer without zerofill, in which case + the number should be of format ' 0' or ' 0.000' + */ + uint whole_part=field_length- (dec ? dec+2 : 1); + // Fill with spaces up to the first digit + bfill(to, whole_part, ' '); + to+= whole_part; + len-= whole_part; + // The main code will also handle the 0 before the decimal point + } + } } - bfill(to,len,negative && unsigned_flag ? '0' : '9'); + bfill(to, len, filler); if (dec) ptr[field_length-dec-1]='.'; return; @@ -425,10 +448,15 @@ void Field_decimal::store(const char *from,uint len,CHARSET_INFO *cs) from++; if (unsigned_flag) // No sign with zerofill { - if (!error) - current_thd->cuted_fields++; - Field_decimal::overflow(1); - return; + if (decstr.sign_char == '+') // just remove "+" + decstr.sign= 0; + else + { + if (!error) + current_thd->cuted_fields++; + Field_decimal::overflow(1); + return; + } } } /* @@ -4489,9 +4517,7 @@ void Field_enum::sql_type(String &res) const { if (flag) res.append(','); - res.append('\''); - append_unescaped(&res,*pos); - res.append('\''); + append_unescaped(&res, *pos, strlen(*pos)); flag=1; } res.append(')'); @@ -4610,9 +4636,7 @@ void Field_set::sql_type(String &res) const { if (flag) res.append(','); - res.append('\''); - append_unescaped(&res,*pos); - res.append('\''); + append_unescaped(&res, *pos, strlen(*pos)); flag=1; } res.append(')'); @@ -4713,6 +4737,7 @@ uint pack_length_to_packflag(uint type) Field *make_field(char *ptr, uint32 field_length, uchar *null_pos, uchar null_bit, uint pack_flag, + enum_field_types field_type, Field::utype unireg_check, TYPELIB *interval, const char *field_name, @@ -4728,7 +4753,8 @@ Field *make_field(char *ptr, uint32 field_length, if (!f_is_packed(pack_flag)) return new Field_string(ptr,field_length,null_pos,null_bit, unireg_check, field_name, table, - f_is_binary(pack_flag) != 0, default_charset_info); + f_is_binary(pack_flag) != 0, + default_charset_info); uint pack_length=calc_pack_length((enum_field_types) f_packtype(pack_flag), @@ -4756,7 +4782,7 @@ Field *make_field(char *ptr, uint32 field_length, } } - switch ((enum enum_field_types) f_packtype(pack_flag)) { + switch (field_type) { case FIELD_TYPE_DECIMAL: return new Field_decimal(ptr,field_length,null_pos,null_bit, unireg_check, field_name, table, @@ -4837,6 +4863,8 @@ create_field::create_field(Field *old_field,Field *orig_field) unireg_check=old_field->unireg_check; pack_length=old_field->pack_length(); sql_type= old_field->real_type(); + charset= old_field->charset(); // May be NULL ptr + comment= old_field->comment; /* Fix if the original table had 4 byte pointer blobs */ if (flags & BLOB_FLAG) @@ -4845,6 +4873,7 @@ create_field::create_field(Field *old_field,Field *orig_field) decimals= old_field->decimals(); if (sql_type == FIELD_TYPE_STRING) { + /* Change CHAR -> VARCHAR if dynamic record length */ sql_type=old_field->type(); decimals=0; } diff --git a/sql/field.h b/sql/field.h index cf7c2a50218..f84b54271ce 100644 --- a/sql/field.h +++ b/sql/field.h @@ -41,6 +41,7 @@ public: uchar *null_ptr; // Byte where null_bit is struct st_table *table; // Pointer for table const char *table_name,*field_name; + LEX_STRING comment; ulong query_id; // For quick test of used fields // Field is part of the following keys key_map key_start,part_of_key,part_of_sortkey; @@ -189,6 +190,7 @@ public: uint fill_cache_field(struct st_cache_field *copy); virtual bool get_date(TIME *ltime,bool fuzzydate); virtual bool get_time(TIME *ltime); + virtual CHARSET_INFO *charset(void) { return 0; } friend bool reopen_table(THD *,struct st_table *,bool); friend int cre_myisam(my_string name, register TABLE *form, uint options, ulonglong auto_increment_value); @@ -248,10 +250,10 @@ public: { field_charset=charset; } Item_result result_type () const { return STRING_RESULT; } uint decimals() const { return NOT_FIXED_DEC; } - friend class create_field; void make_field(Send_field *); uint size_of() const { return sizeof(*this); } - inline CHARSET_INFO *charset() const { return field_charset; } + CHARSET_INFO *charset(void) { return field_charset; } + inline void set_charset(CHARSET_INFO *charset) { field_charset=charset; } inline int cmp_image(char *buff,uint length) { @@ -260,7 +262,7 @@ public: else return my_strncasecmp(field_charset,ptr,buff,length); } - + friend class create_field; }; @@ -1013,6 +1015,7 @@ public: const char *field_name; const char *change; // If done with alter table const char *after; // Put column after this one + LEX_STRING comment; // Comment for field Item *def; // Default value enum enum_field_types sql_type; uint32 length; @@ -1020,6 +1023,7 @@ public: Field::utype unireg_check; TYPELIB *interval; // Which interval to use Field *field; // For alter table + CHARSET_INFO *charset; uint8 row,col,sc_length,interval_id; // For rea_create_table uint offset,pack_flag; @@ -1067,7 +1071,8 @@ public: Field *make_field(char *ptr, uint32 field_length, uchar *null_pos, uchar null_bit, - uint pack_flag, Field::utype unireg_check, + uint pack_flag, enum_field_types field_type, + Field::utype unireg_check, TYPELIB *interval, const char *field_name, struct st_table *table); uint pack_length_to_packflag(uint type); diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc index 918ec753f68..6cec0b160b7 100644 --- a/sql/gen_lex_hash.cc +++ b/sql/gen_lex_hash.cc @@ -22,13 +22,13 @@ #ifndef __GNU_LIBRARY__ #define __GNU_LIBRARY__ // Skip warnings in getopt.h #endif -#include <getopt.h> +#include <my_getopt.h> #include "mysql_version.h" #include "lex.h" -bool opt_search=0; -int opt_verbose=0; -ulong opt_count=100000; +my_bool opt_search; +int opt_verbose; +ulong opt_count; #define max_allowed_array 16000 // Don't generate bigger arrays than this #define max_symbol 32767 // Use this for 'not found' @@ -55,6 +55,35 @@ static uchar bits[how_much_and/8+1]; static uint primes[max_allowed_array+1]; static ulong hash_results[type_count][how_much_for_plus+1][total_symbols]; static ulong start_value=0; +static uint best_type; +static ulong best_t1,best_t2, best_start_value; + +static struct my_option my_long_options[] = +{ + {"help", '?', "Display help and exit", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"count", 'c', "Try count times to find a optimal hash table", + (gptr*) &opt_count, (gptr*) &opt_count, 0, GET_ULONG, REQUIRED_ARG, + 100000, 0, 0, 0, 0, 0}, + {"search", 'S', "Search after good rnd1 and rnd2 values", + (gptr*) &opt_search, (gptr*) &opt_search, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, + 0, 0}, + {"verbose", 'v', "Write some information while the program executes", + (gptr*) &opt_verbose, (gptr*) &opt_verbose, 0, GET_INT, NO_ARG, 0, 0, 0, + 0, 0, 0}, + {"version", 'V', "Output version information and exit", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"rnd1", 'r', "Set 1 part of rnd value for hash generator", + (gptr*) &best_t1, (gptr*) &best_t1, 0, GET_ULONG, REQUIRED_ARG, 6657025L, + 0, 0, 0, 0, 0}, + {"rnd2", 'R', "Set 2 part of rnd value for hash generator", + (gptr*) &best_t2, (gptr*) &best_t2, 0, GET_ULONG, REQUIRED_ARG, 6114496L, + 0, 0, 0, 0, 0}, + {"type", 't', "Set type of char table to generate", + (gptr*) &best_type, (gptr*) &best_type, 0, GET_UINT, REQUIRED_ARG, 1, 0, 0, + 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} +}; struct rand_struct { unsigned long seed1,seed2,max_value; @@ -325,82 +354,48 @@ void print_arrays() } -static struct option long_options[] = -{ - {"count", required_argument, 0, 'c'}, - {"search", no_argument, 0, 'S'}, - {"verbose", no_argument, 0, 'v'}, - {"version", no_argument, 0, 'V'}, - {"rnd1", required_argument, 0, 'r'}, - {"rnd2", required_argument, 0, 'R'}, - {"type", required_argument, 0, 't'}, - {0, 0, 0, 0} -}; - - static void usage(int version) { - printf("%s Ver 3.3 Distrib %s, for %s (%s)\n", + printf("%s Ver 3.5 Distrib %s, for %s (%s)\n", my_progname, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE); if (version) return; puts("Copyright (C) 2001 MySQL AB, by Sinisa and Monty"); puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n"); puts("This program generates a perfect hashing function for the sql_lex.cc"); - printf("Usage: %s [OPTIONS]\n", my_progname); - printf("\n\ --c, --count=# Try count times to find a optimal hash table\n\ --r, --rnd1=# Set 1 part of rnd value for hash generator\n\ --R, --rnd2=# Set 2 part of rnd value for hash generator\n\ --t, --type=# Set type of char table to generate\n\ --S, --search Search after good rnd1 and rnd2 values\n\ --v, --verbose Write some information while the program executes\n\ --V, --version Output version information and exit\n"); + printf("Usage: %s [OPTIONS]\n\n", my_progname); + my_print_help(my_long_options); + my_print_variables(my_long_options); +} + +static my_bool +get_one_option(int optid, const struct my_option *opt __attribute__((unused)), + char *argument __attribute__((unused))) +{ + switch(optid) { + case 'v': + opt_verbose++; + break; + case 'V': + usage(1); + exit(0); + case 'I': + case '?': + usage(0); + exit(0); + } + return 0; } -static uint best_type; -static ulong best_t1,best_t2, best_start_value; static int get_options(int argc, char **argv) { - int c,option_index=0; + int ho_error; + + if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) + exit(ho_error); - while ((c=getopt_long(argc,argv,"?SvVc:r:R:t:", - long_options, &option_index)) != EOF) - { - switch(c) { - case 'c': - opt_count=atol(optarg); - break; - case 'r': - best_t1=atol(optarg); - break; - case 'R': - best_t2=atol(optarg); - break; - case 't': - best_type=atoi(optarg); - break; - case 'S': - opt_search=1; - break; - case 'v': - opt_verbose++; - break; - case 'V': usage(1); exit(0); - case 'I': - case '?': - usage(0); - exit(0); - default: - fprintf(stderr,"illegal option: -%c\n",opterr); - usage(0); - exit(1); - } - } - argc-=optind; - argv+=optind; if (argc >= 1) { usage(0); @@ -483,7 +478,7 @@ int main(int argc,char **argv) MY_INIT(argv[0]); - start_value=1109118L; best_t1=6657025L; best_t2=6114496L; best_type=1; /* mode=4903 add=3 type: 0 */ + start_value=1109118L; /* mode=4903 add=3 type: 0 */ if (get_options(argc,(char **) argv)) exit(1); diff --git a/sql/ha_hash.h b/sql/ha_hash.h deleted file mode 100644 index 80416611406..00000000000 --- a/sql/ha_hash.h +++ /dev/null @@ -1,31 +0,0 @@ - -int ha_hash::create(my_string name, register TABLE *form, - ulonglong auto_increment_value) -{ - register uint i,j; - char buff[FN_REFLEN]; - KEY *pos; - H_KEYDEF keydef[MAX_KEY]; - DBUG_ENTER("cre_hash"); - - pos=form->key_info; - for (i=0; i < form->keys ; i++, pos++) - { - keydef[i].hk_flag= pos->flags & HA_NOSAME; - for (j=0 ; (int7) j < pos->key_parts ; j++) - { - uint flag=pos->key_part[j].key_type; - if (!f_is_packed(flag) && f_packtype(flag) == (int) FIELD_TYPE_DECIMAL && - !(flag & FIELDFLAG_BINARY)) - keydef[i].hk_keyseg[j].key_type= (int) HA_KEYTYPE_TEXT; - else - keydef[i].hk_keyseg[j].key_type= (int) HA_KEYTYPE_BINARY; - keydef[i].hk_keyseg[j].start= pos->key_part[j].offset; - keydef[i].hk_keyseg[j].length= pos->key_part[j].length; - } - keydef[i].hk_keyseg[j].key_type= 0; - } - DBUG_RETURN(h_create(fn_format(buff,name,"","",2+4+16),i, - keydef,form->reclength,form->max_rows,form->min_rows, - 0)); -} /* cre_hash */ diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index b93d9fa0108..455d890758f 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -102,13 +102,14 @@ my_bool innobase_use_native_aio = FALSE; my_bool innobase_fast_shutdown = TRUE; /* - Set default InnoDB size to 64M and let it be auto-extending. Thus users - can use InnoDB without having to specify any startup options. + Set default InnoDB data file size to 10 MB and let it be + auto-extending. Thus users can use InnoDB without having to + specify any startup options. */ /* innobase_data_file_path=ibdata:15,idata2:1,... */ -char *innobase_data_file_path= (char*) "ibdata1:64M:autoextend"; +char *innobase_data_file_path= (char*) "ibdata1:10M:autoextend"; static char *internal_innobase_data_file_path=0; /* The following counter is used to convey information to InnoDB @@ -653,6 +654,7 @@ innobase_close_connection( (thd->transaction.all.innobase_tid)); trx_free_for_mysql((trx_t*) (thd->transaction.all.innobase_tid)); + thd->transaction.all.innobase_tid = NULL; } return(0); diff --git a/sql/handler.h b/sql/handler.h index 668453f8905..45865c39154 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -149,22 +149,23 @@ enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED, typedef struct st_ha_create_information { - ulong table_options; - enum db_type db_type; - enum row_type row_type; - ulong avg_row_length; - ulonglong max_rows,min_rows; - ulonglong auto_increment_value; + CHARSET_INFO *table_charset; char *comment,*password; char *data_file_name, *index_file_name; char *create_statement; - uint options; /* OR of HA_CREATE_ options */ - uint raid_type,raid_chunks; + ulonglong max_rows,min_rows; + ulonglong auto_increment_value; + ulong table_options; + ulong avg_row_length; ulong raid_chunksize; - bool if_not_exists; ulong used_fields; SQL_LIST merge_list; + enum db_type db_type; + enum row_type row_type; + uint options; /* OR of HA_CREATE_ options */ + uint raid_type,raid_chunks; uint merge_insert_method; + bool if_not_exists; } HA_CREATE_INFO; diff --git a/sql/hostname.cc b/sql/hostname.cc index 0b35f970c42..bcc8ea87281 100644 --- a/sql/hostname.cc +++ b/sql/hostname.cc @@ -57,8 +57,11 @@ void hostname_cache_refresh() bool hostname_cache_init() { + host_entry *tmp; + uint offset= (uint) ((char*) (&tmp->ip) - (char*) tmp); (void) pthread_mutex_init(&LOCK_hostname,MY_MUTEX_INIT_SLOW); - if (!(hostname_cache=new hash_filo(HOST_CACHE_SIZE,offsetof(host_entry,ip), + + if (!(hostname_cache=new hash_filo(HOST_CACHE_SIZE, offset, sizeof(struct in_addr),NULL, (void (*)(void*)) free))) return 1; @@ -171,17 +174,22 @@ my_string ip_to_hostname(struct in_addr *in, uint *errors) { DBUG_PRINT("error",("gethostbyname_r returned %d",tmp_errno)); add_wrong_ip(in); + my_gethostbyname_r_free(); DBUG_RETURN(0); } if (!hp->h_name[0]) { DBUG_PRINT("error",("Got an empty hostname")); add_wrong_ip(in); + my_gethostbyname_r_free(); DBUG_RETURN(0); // Don't allow empty hostnames } if (!(name=my_strdup(hp->h_name,MYF(0)))) + { + my_gethostbyname_r_free(); DBUG_RETURN(0); // out of memory - + } + my_gethostbyname_r_free(); #else VOID(pthread_mutex_lock(&LOCK_hostname)); if (!(hp=gethostbyaddr((char*) in,sizeof(*in), AF_INET))) diff --git a/sql/item.h b/sql/item.h index 927e86398c2..b878da5661e 100644 --- a/sql/item.h +++ b/sql/item.h @@ -364,6 +364,25 @@ public: }; +/* + The following class is used to optimize comparing of date columns + We need to save the original item, to be able to set the field to the + original value in 'opt_range'. +*/ + +class Item_int_with_ref :public Item_int +{ + Item *ref; +public: + Item_int_with_ref(longlong i, Item *ref_arg) :Item_int(i), ref(ref_arg) + {} + bool save_in_field(Field *field) + { + return ref->save_in_field(field); + } +}; + + #include "spatial.h" #include "item_sum.h" #include "item_func.h" diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 072eaf51567..8433ae5bfba 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -26,9 +26,9 @@ /* -** Test functions -** These returns 0LL if false and 1LL if true and null if some arg is null -** 'AND' and 'OR' never return null + Test functions + These returns 0LL if false and 1LL if true and null if some arg is null + 'AND' and 'OR' never return null */ longlong Item_func_not::val_int() @@ -46,8 +46,8 @@ static bool convert_constant_item(Field *field, Item **item) (*item)->save_in_field(field); if (!((*item)->null_value)) { - Item *tmp=new Item_int(field->val_int()); - if ((tmp)) + Item *tmp=new Item_int_with_ref(field->val_int(), *item); + if (tmp) *item=tmp; return 1; } @@ -60,8 +60,10 @@ void Item_bool_func2::fix_length_and_dec() { max_length=1; - /* As some compare functions are generated after sql_yacc, - we have to check for out of memory conditons here */ + /* + As some compare functions are generated after sql_yacc, + we have to check for out of memory conditons here + */ if (!args[0] || !args[1]) return; // Make a special case of compare with fields to get nicer DATE comparisons @@ -337,8 +339,10 @@ void Item_func_between::fix_length_and_dec() { max_length=1; - /* As some compare functions are generated after sql_yacc, - we have to check for out of memory conditons here */ + /* + As some compare functions are generated after sql_yacc, + we have to check for out of memory conditons here + */ if (!args[0] || !args[1] || !args[2]) return; cmp_type=args[0]->result_type(); @@ -390,7 +394,7 @@ longlong Item_func_between::val_int() { longlong value=args[0]->val_int(),a,b; if ((null_value=args[0]->null_value)) - return 0; /* purecov: inspected */ + return 0; /* purecov: inspected */ a=args[1]->val_int(); b=args[2]->val_int(); if (!args[1]->null_value && !args[2]->null_value) @@ -410,7 +414,7 @@ longlong Item_func_between::val_int() { double value=args[0]->val(),a,b; if ((null_value=args[0]->null_value)) - return 0; /* purecov: inspected */ + return 0; /* purecov: inspected */ a=args[1]->val(); b=args[2]->val(); if (!args[1]->null_value && !args[2]->null_value) @@ -491,8 +495,12 @@ Item_func_if::fix_length_and_dec() decimals=max(args[1]->decimals,args[2]->decimals); enum Item_result arg1_type=args[1]->result_type(); enum Item_result arg2_type=args[2]->result_type(); + binary=1; if (arg1_type == STRING_RESULT || arg2_type == STRING_RESULT) + { cached_result_type = STRING_RESULT; + binary=args[1]->binary | args[2]->binary; + } else if (arg1_type == REAL_RESULT || arg2_type == REAL_RESULT) cached_result_type = REAL_RESULT; else @@ -591,11 +599,10 @@ Item_func_nullif::val_str(String *str) } /* -** CASE expression + CASE expression + Return the matching ITEM or NULL if all compares (including else) failed */ -/* Return the matching ITEM or NULL if all compares (including else) failed */ - Item *Item_func_case::find_item(String *str) { String *first_expr_str,*tmp; @@ -783,7 +790,7 @@ void Item_func_case::print(String *str) } /* -** Coalesce - return first not NULL argument. + Coalesce - return first not NULL argument. */ String *Item_func_coalesce::val_str(String *str) @@ -839,7 +846,7 @@ void Item_func_coalesce::fix_length_and_dec() } /**************************************************************************** -** classes and function for the IN operator + Classes and function for the IN operator ****************************************************************************/ static int cmp_longlong(longlong *a,longlong *b) @@ -915,7 +922,7 @@ byte *in_longlong::get_value(Item *item) { tmp=item->val_int(); if (item->null_value) - return 0; /* purecov: inspected */ + return 0; /* purecov: inspected */ return (byte*) &tmp; } @@ -933,7 +940,7 @@ byte *in_double::get_value(Item *item) { tmp=item->val(); if (item->null_value) - return 0; /* purecov: inspected */ + return 0; /* purecov: inspected */ return (byte*) &tmp; } @@ -1171,9 +1178,11 @@ longlong Item_cond_and::val_int() { if (item->val_int() == 0) { - /* TODO: In case of NULL, ANSI would require us to continue evaluation - until we get a FALSE value or run out of values; This would - require a lot of unnecessary evaluation, which we skip for now */ + /* + TODO: In case of NULL, ANSI would require us to continue evaluation + until we get a FALSE value or run out of values; This would + require a lot of unnecessary evaluation, which we skip for now + */ null_value=item->null_value; return 0; } @@ -1202,6 +1211,12 @@ longlong Item_cond_or::val_int() longlong Item_func_isnull::val_int() { + /* + Handle optimization if the argument can't be null + This has to be here because of the test in update_used_tables(). + */ + if (!used_tables_cache) + return cached_value; return args[0]->is_null() ? 1: 0; } @@ -1217,23 +1232,23 @@ void Item_func_like::fix_length_and_dec() // cmp_type=STRING_RESULT; // For quick select } - longlong Item_func_like::val_int() { - String *res,*res2; - res=args[0]->val_str(&tmp_value1); + String* res = args[0]->val_str(&tmp_value1); if (args[0]->null_value) { null_value=1; return 0; } - res2=args[1]->val_str(&tmp_value2); + String* res2 = args[1]->val_str(&tmp_value2); if (args[1]->null_value) { null_value=1; return 0; } null_value=0; + if (canDoTurboBM) + return turboBM_matches(res->ptr(), res->length()) ? 1 : 0; if (binary) return wild_compare(*res,*res2,escape) ? 0 : 1; else @@ -1257,6 +1272,55 @@ Item_func::optimize_type Item_func_like::select_optimize() const return OPTIMIZE_NONE; } +bool Item_func_like::fix_fields(THD *thd,struct st_table_list *tlist) +{ + if (Item_bool_func2::fix_fields(thd, tlist)) + return 1; + + /* + TODO--we could do it for non-const, but we'd have to + recompute the tables for each row--probably not worth it. + */ + if (args[1]->const_item() && !(specialflag & SPECIAL_NO_NEW_FUNC)) + { + String* res2 = args[1]->val_str(&tmp_value2); + if (!res2) + return 0; // Null argument + + const size_t len = res2->length(); + const char* first = res2->ptr(); + const char* last = first + len - 1; + /* + len must be > 2 ('%pattern%') + heuristic: only do TurboBM for pattern_len > 2 + */ + + if (len > MIN_TURBOBM_PATTERN_LEN + 2 && + *first == wild_many && + *last == wild_many) + { + const char* tmp = first + 1; + for ( ; *tmp != wild_many && *tmp != wild_one && *tmp != escape; tmp++) ; + canDoTurboBM = tmp == last; + } + + if (canDoTurboBM) + { + pattern = first + 1; + pattern_len = len - 2; + DBUG_PRINT("info", ("Initializing pattern: '%s'", first)); + int *suff = (int*) thd->alloc(sizeof(int)*((pattern_len + 1)*2+ + alphabet_size)); + bmGs = suff + pattern_len + 1; + bmBc = bmGs + pattern_len + 1; + turboBM_compute_good_suffix_shifts(suff); + turboBM_compute_bad_character_shifts(); + DBUG_PRINT("info",("done")); + } + } + return 0; +} + #ifdef USE_REGEX bool @@ -1297,7 +1361,6 @@ Item_func_regex::fix_fields(THD *thd,TABLE_LIST *tables) return 0; } - longlong Item_func_regex::val_int() { char buff[MAX_FIELD_WIDTH]; @@ -1357,6 +1420,226 @@ Item_func_regex::~Item_func_regex() #endif /* USE_REGEX */ +#ifdef LIKE_CMP_TOUPPER +#define likeconv(cs,A) (uchar) (cs)->toupper(A) +#else +#define likeconv(cs,A) (uchar) (cs)->sort_order[(uchar) (A)] +#endif + + +/********************************************************************** + turboBM_compute_suffixes() + Precomputation dependent only on pattern_len. +**********************************************************************/ + +void Item_func_like::turboBM_compute_suffixes(int* suff) +{ + const int plm1 = pattern_len - 1; + int f = 0; + int g = plm1; + int *const splm1 = suff + plm1; + CHARSET_INFO *cs=system_charset_info; // QQ Needs to be fixed + + *splm1 = pattern_len; + + if (binary) + { + int i; + for (i = pattern_len - 2; i >= 0; i--) + { + int tmp = *(splm1 + i - f); + if (g < i && tmp < i - g) + suff[i] = tmp; + else + { + if (i < g) + g = i; // g = min(i, g) + f = i; + while (g >= 0 && pattern[g] == pattern[g + plm1 - f]) + g--; + suff[i] = f - g; + } + } + } + else + { + int i; + for (i = pattern_len - 2; 0 <= i; --i) + { + int tmp = *(splm1 + i - f); + if (g < i && tmp < i - g) + suff[i] = tmp; + else + { + if (i < g) + g = i; // g = min(i, g) + f = i; + while (g >= 0 && likeconv(cs, pattern[g]) == + likeconv(cs, pattern[g + plm1 - f])) + g--; + suff[i] = f - g; + } + } + } +} + + +/********************************************************************** + turboBM_compute_good_suffix_shifts() + Precomputation dependent only on pattern_len. +**********************************************************************/ + +void Item_func_like::turboBM_compute_good_suffix_shifts(int* suff) +{ + turboBM_compute_suffixes(suff); + + int* end = bmGs + pattern_len; + int* k; + for (k = bmGs; k < end; k++) + *k = pattern_len; + + int tmp; + int i; + int j = 0; + const int plm1 = pattern_len - 1; + for (i = plm1; i > -1; i--) + { + if (suff[i] == i + 1) + { + for (tmp = plm1 - i; j < tmp; j++) + { + int* tmp2 = bmGs + j; + if (*tmp2 == pattern_len) + *tmp2 = tmp; + } + } + } + + int* tmp2; + for (tmp = plm1 - i; j < tmp; j++) + { + tmp2 = bmGs + j; + if (*tmp2 == pattern_len) + *tmp2 = tmp; + } + + tmp2 = bmGs + plm1; + for (i = 0; i <= pattern_len - 2; i++) + *(tmp2 - suff[i]) = plm1 - i; +} + + +/********************************************************************** + turboBM_compute_bad_character_shifts() + Precomputation dependent on pattern_len. +**********************************************************************/ + +void Item_func_like::turboBM_compute_bad_character_shifts() +{ + int *i; + int *end = bmBc + alphabet_size; + int j; + const int plm1 = pattern_len - 1; + CHARSET_INFO *cs=system_charset_info; // QQ Needs to be fixed + + for (i = bmBc; i < end; i++) + *i = pattern_len; + + if (binary) + { + for (j = 0; j < plm1; j++) + bmBc[pattern[j]] = plm1 - j; + } + else + { + for (j = 0; j < plm1; j++) + bmBc[likeconv(cs,pattern[j])] = plm1 - j; + } +} + + +/********************************************************************** + turboBM_matches() + Search for pattern in text, returns true/false for match/no match +**********************************************************************/ + +bool Item_func_like::turboBM_matches(const char* text, int text_len) const +{ + register int bcShift; + register int turboShift; + int shift = pattern_len; + int j = 0; + int u = 0; + CHARSET_INFO *cs=system_charset_info; // QQ Needs to be fixed + + const int plm1 = pattern_len - 1; + const int tlmpl = text_len - pattern_len; + + /* Searching */ + if (binary) + { + while (j <= tlmpl) + { + register int i = plm1; + while (i >= 0 && pattern[i] == text[i + j]) + { + i--; + if (i == plm1 - shift) + i -= u; + } + if (i < 0) + return true; + + register const int v = plm1 - i; + turboShift = u - v; + bcShift = bmBc[text[i + j]] - plm1 + i; + shift = max(turboShift, bcShift); + shift = max(shift, bmGs[i]); + if (shift == bmGs[i]) + u = min(pattern_len - shift, v); + else + { + if (turboShift < bcShift) + shift = max(shift, u + 1); + u = 0; + } + j += shift; + } + return false; + } + else + { + while (j <= tlmpl) + { + register int i = plm1; + while (i >= 0 && likeconv(cs,pattern[i]) == likeconv(cs,text[i + j])) + { + i--; + if (i == plm1 - shift) + i -= u; + } + if (i < 0) + return true; + + register const int v = plm1 - i; + turboShift = u - v; + bcShift = bmBc[likeconv(cs, text[i + j])] - plm1 + i; + shift = max(turboShift, bcShift); + shift = max(shift, bmGs[i]); + if (shift == bmGs[i]) + u = min(pattern_len - shift, v); + else + { + if (turboShift < bcShift) + shift = max(shift, u + 1); + u = 0; + } + j += shift; + } + return false; + } +} + /**************************************************************** Classes and functions for spatial relations *****************************************************************/ diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 350e369eaac..302ad88905e 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -430,6 +430,7 @@ class Item_func_in :public Item_int_func class Item_func_isnull :public Item_bool_func { + longlong cached_value; public: Item_func_isnull(Item *a) :Item_bool_func(a) {} longlong val_int(); @@ -450,6 +451,12 @@ public: args[0]->update_used_tables(); used_tables_cache=args[0]->used_tables(); } + if (!used_tables_cache) + { + /* Remember if the value is always NULL or never NULL */ + args[0]->val(); + cached_value= args[0]->null_value ? (longlong) 1 : (longlong) 0; + } } optimize_type select_optimize() const { return OPTIMIZE_NULL; } }; @@ -471,8 +478,26 @@ public: class Item_func_like :public Item_bool_func2 { char escape; + + // Turbo Boyer-Moore data + bool canDoTurboBM; // pattern is '%abcd%' case + const char* pattern; + int pattern_len; + + // TurboBM buffers, *this is owner + int* bmGs; // good suffix shift table, size is pattern_len + 1 + int* bmBc; // bad character shift table, size is alphabet_size + + void turboBM_compute_suffixes(int* suff); + void turboBM_compute_good_suffix_shifts(int* suff); + void turboBM_compute_bad_character_shifts(); + bool turboBM_matches(const char* text, int text_len) const; + enum { alphabet_size = 256 }; + public: - Item_func_like(Item *a,Item *b, char* escape_arg) :Item_bool_func2(a,b),escape(*escape_arg) + Item_func_like(Item *a,Item *b, char* escape_arg) + :Item_bool_func2(a,b), escape(*escape_arg), canDoTurboBM(false), + pattern(0), pattern_len(0), bmGs(0), bmBc(0) {} longlong val_int(); enum Functype functype() const { return LIKE_FUNC; } @@ -480,6 +505,7 @@ public: cond_result eq_cmp_result() const { return COND_TRUE; } const char *func_name() const { return "like"; } void fix_length_and_dec(); + bool fix_fields(THD *thd,struct st_table_list *tlist); }; #ifdef USE_REGEX diff --git a/sql/item_func.cc b/sql/item_func.cc index 057518fb5f2..0675bf81dab 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -61,7 +61,7 @@ bool Item_func::fix_fields(THD *thd,TABLE_LIST *tables) { Item **arg,**arg_end; - char buff[sizeof(double)]; // Max argument in function + char buff[STACK_BUFF_ALLOC]; // Max argument in function binary=0; used_tables_cache=0; const_item_cache=1; @@ -629,7 +629,12 @@ double Item_func_round::val() log_10[abs_dec] : pow(10.0,(double) abs_dec)); if (truncate) - return dec < 0 ? floor(value/tmp)*tmp : floor(value*tmp)/tmp; + { + if (value >= 0) + return dec < 0 ? floor(value/tmp)*tmp : floor(value*tmp)/tmp; + else + return dec < 0 ? ceil(value/tmp)*tmp : ceil(value*tmp)/tmp; + } return dec < 0 ? rint(value/tmp)*tmp : rint(value*tmp)/tmp; } @@ -1089,7 +1094,7 @@ bool udf_handler::fix_fields(THD *thd,TABLE_LIST *tables,Item_result_field *func, uint arg_count, Item **arguments) { - char buff[sizeof(double)]; // Max argument in function + char buff[STACK_BUFF_ALLOC]; // Max argument in function DBUG_ENTER("Item_udf_func::fix_fields"); if (thd) @@ -1610,7 +1615,7 @@ longlong Item_func_get_lock::val_int() set_timespec(abstime,timeout); while (!thd->killed && (error=pthread_cond_timedwait(&ull->cond,&LOCK_user_locks,&abstime)) - != ETIME && error != ETIMEDOUT && ull->locked) ; + != ETIME && error != ETIMEDOUT && error != EINVAL && ull->locked) ; if (thd->killed) error=EINTR; // Return NULL if (ull->locked) @@ -2042,6 +2047,11 @@ void Item_func_match::init_search(bool no_order) if (ft_handler) return; + if (key == NO_SUCH_KEY) + concat=new Item_func_concat_ws(new Item_string(" ",1, + default_charset_info), + fields); + if (master) { join_key=master->join_key=join_key|master->join_key; @@ -2051,9 +2061,6 @@ void Item_func_match::init_search(bool no_order) return; } - if (key == NO_SUCH_KEY) - concat=new Item_func_concat_ws (new Item_string(" ",1,default_charset_info), fields); - String *ft_tmp=0; char tmp1[FT_QUERY_MAXLEN]; String tmp2(tmp1,sizeof(tmp1),default_charset_info); @@ -2251,10 +2258,13 @@ double Item_func_match::val() Item *get_system_var(LEX_STRING name) { - if (!strcmp(name.str,"IDENTITY")) + if (!my_strcasecmp(system_charset_info, name.str, "IDENTITY")) return new Item_int((char*) "@@IDENTITY", current_thd->insert_id(),21); - my_error(ER_UNKNOWN_SYSTEM_VARIABLE,MYF(0),name); + if (!my_strcasecmp(system_charset_info, name.str, "VERSION")) + return new Item_string("@@VERSION",server_version, + (uint) strlen(server_version), system_charset_info); + net_printf(¤t_thd->net, ER_UNKNOWN_SYSTEM_VARIABLE, name.str); return 0; } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 8f77f736c86..5275da95b6e 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -475,7 +475,7 @@ null: void Item_func_concat_ws::fix_length_and_dec() { - max_length=0; + max_length=separator->max_length*(arg_count-1); for (uint i=0 ; i < arg_count ; i++) max_length+=args[i]->max_length; if (max_length > MAX_BLOB_WIDTH) @@ -2342,7 +2342,8 @@ String *Item_func_spatial_collection::val_str(String *str) } else { - uint32 wkb_type, len=res->length(); + enum Geometry::wkbType wkb_type; + uint32 len=res->length(); const char *data=res->ptr()+1; /* @@ -2351,75 +2352,74 @@ String *Item_func_spatial_collection::val_str(String *str) do this checking now */ - if (len<5) + if (len < 5) goto ret; - wkb_type=uint4korr(data); + wkb_type= (Geometry::wkbType) uint4korr(data); data+=4; len-=5; - if ( wkb_type != item_type ) + if (wkb_type != item_type) goto ret; - switch(coll_type) - { - case Geometry::wkbMultiPoint: - case Geometry::wkbMultiLineString: - case Geometry::wkbMultiPolygon: - if (len<WKB_HEADER_SIZE) - goto ret; + switch (coll_type) { + case Geometry::wkbMultiPoint: + case Geometry::wkbMultiLineString: + case Geometry::wkbMultiPolygon: + if (len < WKB_HEADER_SIZE) + goto ret; - data+=WKB_HEADER_SIZE; - len-=WKB_HEADER_SIZE; - if (str->reserve(len,512)) - goto ret; - str->q_append(data,len); - break; - - case Geometry::wkbLineString: - if (str->reserve(POINT_DATA_SIZE,512)) - goto ret; - str->q_append(data,POINT_DATA_SIZE); - break; - - case Geometry::wkbPolygon: - { - uint32 n_points; - double x1, y1, x2, y2; - - if (len < WKB_HEADER_SIZE + 4 + 8 + 8) - goto ret; - data+=WKB_HEADER_SIZE; - len-=WKB_HEADER_SIZE; - - uint32 llen=len; - const char *ldata=data; + data+=WKB_HEADER_SIZE; + len-=WKB_HEADER_SIZE; + if (str->reserve(len,512)) + goto ret; + str->q_append(data,len); + break; + + case Geometry::wkbLineString: + if (str->reserve(POINT_DATA_SIZE,512)) + goto ret; + str->q_append(data,POINT_DATA_SIZE); + break; + + case Geometry::wkbPolygon: + { + uint32 n_points; + double x1, y1, x2, y2; + + if (len < WKB_HEADER_SIZE + 4 + 8 + 8) + goto ret; + data+=WKB_HEADER_SIZE; + len-=WKB_HEADER_SIZE; + + uint32 llen=len; + const char *ldata=data; - n_points=uint4korr(data); - data+=4; - float8get(x1,data); - data+=8; - float8get(y1,data); - data+=8; + n_points=uint4korr(data); + data+=4; + float8get(x1,data); + data+=8; + float8get(y1,data); + data+=8; - len-= 4 + 8 + 8; + len-= 4 + 8 + 8; - if (len < n_points * POINT_DATA_SIZE) - goto ret; - data+=(n_points-2) * POINT_DATA_SIZE; + if (len < n_points * POINT_DATA_SIZE) + goto ret; + data+=(n_points-2) * POINT_DATA_SIZE; - float8get(x2,data); - float8get(y2,data+8); + float8get(x2,data); + float8get(y2,data+8); - if ((x1 != x2) || (y1 != y2)) - goto ret; + if ((x1 != x2) || (y1 != y2)) + goto ret; - if (str->reserve(llen,512)) - goto ret; - str->q_append(ldata, llen); - } - break; + if (str->reserve(llen,512)) + goto ret; + str->q_append(ldata, llen); + } + break; - default: - goto ret; + default: + goto ret; } } } diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 9ff2734f460..53beb78e1d4 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -47,7 +47,7 @@ public: Item_func_to_days(Item *a) :Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "to_days"; } - void fix_length_and_dec() { decimals=0; max_length=6; } + void fix_length_and_dec() { decimals=0; max_length=6; maybe_null=1; } }; diff --git a/sql/lex.h b/sql/lex.h index ea712523993..dd1a69f9c83 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -232,6 +232,8 @@ static SYMBOL symbols[] = { { "MASTER_USER", SYM(MASTER_USER_SYM),0,0}, { "MAX_ROWS", SYM(MAX_ROWS),0,0}, { "MAX_QUERIES_PER_HOUR", SYM(MAX_QUERIES_PER_HOUR), 0,0}, + { "MAX_UPDATES_PER_HOUR", SYM(MAX_UPDATES_PER_HOUR), 0,0}, + { "MAX_CONNECTIONS_PER_HOUR", SYM(MAX_CONNECTIONS_PER_HOUR), 0,0}, { "MATCH", SYM(MATCH),0,0}, { "MEDIUMBLOB", SYM(MEDIUMBLOB),0,0}, { "MEDIUMTEXT", SYM(MEDIUMTEXT),0,0}, @@ -293,6 +295,7 @@ static SYMBOL symbols[] = { { "REPEATABLE", SYM(REPEATABLE_SYM),0,0}, { "REQUIRE", SYM(REQUIRE_SYM),0,0}, { "RESET", SYM(RESET_SYM),0,0}, + { "USER_RESOURCES", SYM(RESOURCES),0,0}, { "RESTORE", SYM(RESTORE_SYM),0,0}, { "RESTRICT", SYM(RESTRICT),0,0}, { "RETURNS", SYM(UDF_RETURNS_SYM),0,0}, @@ -309,6 +312,7 @@ static SYMBOL symbols[] = { { "SESSION", SYM(SESSION_SYM),0,0}, { "SET", SYM(SET),0,0}, { "SIGNED", SYM(SIGNED_SYM),0,0}, + { "SIMPLE", SYM(SIMPLE_SYM),0,0}, { "SHARE", SYM(SHARE_SYM),0,0}, { "SHOW", SYM(SHOW),0,0}, { "SHUTDOWN", SYM(SHUTDOWN),0,0}, diff --git a/sql/log.cc b/sql/log.cc index 39a8ff3f81f..02ebb4348ac 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -531,14 +531,14 @@ int MYSQL_LOG::purge_logs(THD* thd, const char* to_log) error = LOG_INFO_MEM; goto err; } - if (init_dynamic_array(&logs_to_purge, sizeof(char*), 1024, 1024)) + if (my_init_dynamic_array(&logs_to_purge, sizeof(char*), 1024, 1024)) { error = LOG_INFO_MEM; goto err; } logs_to_purge_inited = 1; - if (init_dynamic_array(&logs_to_keep, sizeof(char*), 1024, 1024)) + if (my_init_dynamic_array(&logs_to_keep, sizeof(char*), 1024, 1024)) { error = LOG_INFO_MEM; goto err; diff --git a/sql/mini_client.cc b/sql/mini_client.cc index c31fa573fea..ffb5d659238 100644 --- a/sql/mini_client.cc +++ b/sql/mini_client.cc @@ -620,7 +620,6 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user, memcpy_fixed(&sock_addr.sin_addr,&ip_addr,sizeof(ip_addr)); } else -#if defined(HAVE_GETHOSTBYNAME_R) && defined(_REENTRANT) && defined(THREAD) { int tmp_errno; struct hostent tmp_hostent,*hp; @@ -631,22 +630,12 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user, { net->last_errno=CR_UNKNOWN_HOST; sprintf(net->last_error, ER(CR_UNKNOWN_HOST), host, tmp_errno); + my_gethostbyname_r_free(); goto error; } memcpy(&sock_addr.sin_addr,hp->h_addr, (size_t) hp->h_length); + my_gethostbyname_r_free(); } -#else - { - struct hostent *hp; - if (!(hp=gethostbyname(host))) - { - net->last_errno=CR_UNKNOWN_HOST; - sprintf(net->last_error, ER(CR_UNKNOWN_HOST), host, socket_errno); - goto error; - } - memcpy(&sock_addr.sin_addr,hp->h_addr, (size_t) hp->h_length); - } -#endif sock_addr.sin_port = (ushort) htons((ushort) port); if (mc_sock_connect(sock,(struct sockaddr *) &sock_addr, sizeof(sock_addr), mysql->options.connect_timeout) <0) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 4c71e845207..e6c44f949ab 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -75,22 +75,30 @@ char* query_table_status(THD *thd,const char *db,const char *table_name); #define MAX_FIELDS_BEFORE_HASH 32 #define USER_VARS_HASH_SIZE 16 #define STACK_MIN_SIZE 8192 // Abort if less stack during eval. +#define STACK_BUFF_ALLOC 32 // For stack overrun checks #ifndef MYSQLD_NET_RETRY_COUNT #define MYSQLD_NET_RETRY_COUNT 10 // Abort read after this many int. #endif #define TEMP_POOL_SIZE 128 -/* The following parameters is to decide when to use an extra cache to - optimise seeks when reading a big table in sorted order */ +/* + The following parameters is to decide when to use an extra cache to + optimise seeks when reading a big table in sorted order +*/ #define MIN_FILE_LENGTH_TO_USE_ROW_CACHE (16L*1024*1024) #define MIN_ROWS_TO_USE_TABLE_CACHE 100 -// The following is used to decide if MySQL should use table scanning -// instead of reading with keys. The number says how many evaluation of the -// WHERE clause is comparable to reading one extra row from a table. +/* + The following is used to decide if MySQL should use table scanning + instead of reading with keys. The number says how many evaluation of the + WHERE clause is comparable to reading one extra row from a table. +*/ #define TIME_FOR_COMPARE 5 // 5 compares == one read -// Number of rows in a reference table when refereed through a not unique key. -// This value is only used when we don't know anything about the key -// distribution. + +/* + Number of rows in a reference table when refereed through a not unique key. + This value is only used when we don't know anything about the key + distribution. +*/ #define MATCHING_ROWS_IN_OTHER_TABLE 10 /* Don't pack string keys shorter than this (if PACK_KEYS=1 isn't used) */ @@ -474,8 +482,9 @@ int mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes,char *, void set_item_name(Item *item,char *pos,uint length); bool add_field_to_list(char *field_name, enum enum_field_types type, char *length, char *decimal, - uint type_modifier, Item *default_value,char *change, - TYPELIB *interval); + uint type_modifier, + Item *default_value, Item *comment, + char *change, TYPELIB *interval); void store_position_for_column(const char *name); bool add_to_list(SQL_LIST &list,Item *group,bool asc=0); TABLE_LIST *add_table_to_list(Table_ident *table,LEX_STRING *alias, @@ -610,7 +619,7 @@ extern pthread_cond_t COND_refresh,COND_thread_count; extern pthread_attr_t connection_attrib; extern bool opt_endinfo, using_udf_functions, locked_in_memory, opt_using_transactions, use_temp_pool, mysql_embedded; -extern bool opt_local_infile; +extern my_bool opt_local_infile; extern char f_fyllchar; extern ulong ha_read_count, ha_write_count, ha_delete_count, ha_update_count, ha_read_key_count, ha_read_next_count, ha_read_prev_count, @@ -726,7 +735,7 @@ ulong get_form_pos(File file, uchar *head, TYPELIB *save_names); ulong make_new_entry(File file,uchar *fileinfo,TYPELIB *formnames, const char *newname); ulong next_io_size(ulong pos); -void append_unescaped(String *res,const char *pos); +void append_unescaped(String *res, const char *pos, uint length); int create_frm(char *name,uint reclength,uchar *fileinfo, HA_CREATE_INFO *create_info, uint keys); void update_create_info_from_table(HA_CREATE_INFO *info, TABLE *form); @@ -739,7 +748,7 @@ int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr); int wild_compare(const char *str,const char *str_end, const char *wildstr,const char *wildend,char escape); int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *str_end, - const char *wildstr,const char *wildend,char escape); + const char *wildstr,const char *wildend,char escape); /* from hostname.cc */ struct in_addr; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 19ff66b24fc..98bfa162242 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -65,7 +65,7 @@ extern "C" { // Because of SCO 3.2V4.2 #ifndef __GNU_LIBRARY__ #define __GNU_LIBRARY__ // Skip warnings in getopt.h #endif -#include <getopt.h> +#include <my_getopt.h> #ifdef HAVE_SYSENT_H #include <sysent.h> #endif @@ -101,6 +101,16 @@ extern "C" { // Because of SCO 3.2V4.2 #endif /* NEED_SYS_SYSLOG_H */ int allow_severity = LOG_INFO; int deny_severity = LOG_WARNING; + +#ifdef __linux__ +#define my_fromhost(A) fromhost() +#define my_hosts_access(A) hosts_access() +#define my_eval_client(A) eval_client() +#else +#define my_fromhost(A) fromhost(A) +#define my_hosts_access(A) hosts_access(A) +#define my_eval_client(A) eval_client(A) +#endif #endif /* HAVE_LIBWRAP */ #ifdef HAVE_SYS_MMAN_H @@ -227,6 +237,11 @@ SHOW_COMP_OPTION have_query_cache=SHOW_OPTION_NO; #endif bool opt_skip_slave_start = 0; // If set, slave is not autostarted + +/* if set, some standard measures to enforce + slave data intergity will not be performed + */ +bool opt_reckless_slave = 0; static bool opt_do_pstack = 0; static ulong opt_specialflag=SPECIAL_ENGLISH; static ulong back_log,connect_timeout,concurrency; @@ -235,6 +250,8 @@ static my_socket unix_sock= INVALID_SOCKET,ip_sock= INVALID_SOCKET; static my_string opt_logname=0,opt_update_logname=0, opt_binlog_index_name = 0,opt_slow_logname=0; static char mysql_home[FN_REFLEN],pidfile_name[FN_REFLEN]; +static char* mysql_home_ptr= mysql_home; +static char* pidfile_name_ptr= pidfile_name; static pthread_t select_thread; 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, @@ -291,8 +308,9 @@ ulong keybuff_size,sortbuff_size,max_item_sort_length,table_cache_size, ulong com_stat[(uint) SQLCOM_END], com_other; ulong slave_net_timeout; ulong thread_cache_size=0, binlog_cache_size=0, max_binlog_cache_size=0; +ulong query_cache_size=0; #ifdef HAVE_QUERY_CACHE -ulong query_cache_size=0, query_cache_limit=0, query_cache_startup_type=1; +ulong query_cache_limit=0, query_cache_startup_type=1; Query_cache query_cache; #endif @@ -316,7 +334,7 @@ ulong bytes_sent = 0L, bytes_received = 0L; bool opt_endinfo,using_udf_functions,low_priority_updates, locked_in_memory; bool opt_using_transactions, using_update_log, opt_warnings=0; -bool opt_local_infile=1; +my_bool opt_local_infile=1; bool volatile abort_loop,select_thread_in_use,grant_option; bool volatile ready_to_exit,shutdown_in_progress; ulong refresh_version=1L,flush_version=1L; /* Increments on each reload */ @@ -341,6 +359,8 @@ char mysql_real_data_home[FN_REFLEN], default_charset[LIBLEN],mysql_charsets_dir[FN_REFLEN], *charsets_list, blob_newline,f_fyllchar,max_sort_char,*mysqld_user,*mysqld_chroot, *opt_init_file; +char *language_ptr= language; +char *default_charset_ptr= default_charset; #ifndef EMBEDDED_LIBRARY char mysql_data_home_buff[2], *mysql_data_home=mysql_data_home_buff; bool mysql_embedded=0; @@ -401,6 +421,7 @@ enum db_type default_table_type=DB_TYPE_MYISAM; #include <process.h> #if !defined(EMBEDDED_LIBRARY) HANDLE hEventShutdown; +static char *event_name; #include "nt_servc.h" static NTService Service; // Service object for WinNT #endif @@ -978,24 +999,22 @@ static void server_init(void) IPaddr.sin_addr.s_addr = my_bind_addr; IPaddr.sin_port = (unsigned short) htons((unsigned short) mysql_port); (void) setsockopt(ip_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,sizeof(arg)); - for(;;) + if (bind(ip_sock, my_reinterpret_cast(struct sockaddr *) (&IPaddr), + sizeof(IPaddr)) < 0) { - if (bind(ip_sock, my_reinterpret_cast(struct sockaddr *) (&IPaddr), - sizeof(IPaddr)) >= 0) - break; DBUG_PRINT("error",("Got error: %d from bind",socket_errno)); - sql_perror("Can't start server: Bind on TCP/IP port");/* Had a loop here */ + sql_perror("Can't start server: Bind on TCP/IP port"); sql_print_error("Do you already have another mysqld server running on port: %d ?",mysql_port); unireg_abort(1); } if (listen(ip_sock,(int) back_log) < 0) { + sql_perror("Can't start server: listen() on TCP/IP port"); sql_print_error("Error: listen() on TCP/IP failed with error %d", socket_errno); unireg_abort(1); } } - if (mysqld_chroot) set_root(mysqld_chroot); set_user(mysqld_user); // Works also with mysqld_user==NULL @@ -2045,7 +2064,7 @@ The server will not act as a slave."); (void) thr_setconcurrency(concurrency); // 10 by default #if defined(__WIN__) && !defined(EMBEDDED_LIBRARY) //IRENA { - hEventShutdown=CreateEvent(0, FALSE, FALSE, "MySqlShutdown"); + hEventShutdown=CreateEvent(0, FALSE, FALSE, event_name); pthread_t hThread; if (pthread_create(&hThread,&connection_attrib,handle_shutdown,0)) sql_print_error("Warning: Can't create thread to handle shutdown requests"); @@ -2180,46 +2199,70 @@ int mysql_service(void *p) int main(int argc, char **argv) { - // check environment variable OS - if (Service.GetOS()) // "OS" defined; Should be NT + if (Service.GetOS()) /* true NT family */ { + char file_path[FN_REFLEN]; + my_path(file_path, argv[0], ""); /* Find name in path */ + fn_format(file_path,argv[0],file_path,"",1+4+16); /* Force use of full path */ + if (argc == 2) + { + if (Service.got_service_option(argv, "install")) + { + Service.Install(1, MYSQL_SERVICENAME, MYSQL_SERVICENAME, file_path); + return 0; + } + else if (Service.got_service_option(argv, "install-manual")) + { + Service.Install(0, MYSQL_SERVICENAME, MYSQL_SERVICENAME, file_path); + return 0; + } + else if (Service.got_service_option(argv, "remove")) + { + Service.Remove(MYSQL_SERVICENAME); + return 0; + } + else if (Service.IsService(argv[1])) + { + /* start an optional service */ + load_default_groups[0]= argv[1]; + event_name= argv[1]; + start_mode= 1; + Service.Init(event_name, mysql_service ); + return 0; + } + } + else if (argc == 3) /* install or remove any optional service */ { - char path[FN_REFLEN]; - my_path(path, argv[0], ""); // Find name in path - fn_format(path,argv[0],path,"",1+4+16); // Force use of full path - - if (!strcmp(argv[1],"-install") || !strcmp(argv[1],"--install")) + uint length=strlen(file_path); + file_path[sizeof(file_path)-1]=0; + strxnmov(file_path + length, sizeof(file_path)-2, " ", argv[2], NullS); + if (Service.got_service_option(argv, "install")) { - Service.Install(1,MYSQL_SERVICENAME,MYSQL_SERVICENAME,path); - return 0; + Service.Install(1, argv[2], argv[2], file_path); + return 0; } - else if (!strcmp(argv[1],"-install-manual") || !strcmp(argv[1],"--install-manual")) + else if (Service.got_service_option(argv, "install-manual")) { - Service.Install(0,MYSQL_SERVICENAME,MYSQL_SERVICENAME,path); - return 0; + Service.Install(0, argv[2], argv[2], file_path); + return 0; } - else if (!strcmp(argv[1],"-remove") || !strcmp(argv[1],"--remove")) + else if (Service.got_service_option(argv, "remove")) { - Service.Remove(MYSQL_SERVICENAME); - return 0; + Service.Remove(argv[2]); + return 0; } } - else if (argc == 1) // No arguments; start as a service + else if (argc == 1 && Service.IsService(MYSQL_SERVICENAME)) { - // init service - start_mode = 1; - long tmp=Service.Init(MYSQL_SERVICENAME,mysql_service); + /* start the default service */ + start_mode= 1; + event_name= "MySqlShutdown"; + Service.Init(MYSQL_SERVICENAME, mysql_service); return 0; } } - - /* - This is a WIN95 machine or a start of mysqld as a standalone program - we have to pass the arguments, in case of NT-service this will be done - by ServiceMain() - */ - + /* Start as standalone server */ Service.my_argc=argc; Service.my_argv=argv; mysql_service(NULL); @@ -2326,7 +2369,6 @@ static void create_new_thread(THD *thd) if (cached_thread_count > wake_thread) { start_cached_thread(thd); - (void) pthread_mutex_unlock(&LOCK_thread_count); } else { @@ -2353,9 +2395,9 @@ static void create_new_thread(THD *thd) (void) pthread_mutex_unlock(&LOCK_thread_count); DBUG_VOID_RETURN; } - - (void) pthread_mutex_unlock(&LOCK_thread_count); } + (void) pthread_mutex_unlock(&LOCK_thread_count); + } DBUG_PRINT("info",("Thread created")); DBUG_VOID_RETURN; @@ -2365,7 +2407,7 @@ static void create_new_thread(THD *thd) inline void kill_broken_server() { /* hack to get around signals ignored in syscalls for problem OS's */ - if (unix_sock == INVALID_SOCKET || ip_sock ==INVALID_SOCKET) + if (unix_sock == INVALID_SOCKET || (!opt_disable_networking && ip_sock ==INVALID_SOCKET)) { select_thread_in_use = 0; kill_server((void*)MYSQL_KILL_SIGNAL); /* never returns */ @@ -2499,24 +2541,16 @@ pthread_handler_decl(handle_connections_sockets,arg __attribute__((unused))) struct request_info req; signal(SIGCHLD, SIG_DFL); request_init(&req, RQ_DAEMON, libwrapName, RQ_FILE, new_sock, NULL); -#ifndef __linux__ - fromhost(&req); - if (!hosts_access(&req)) + my_fromhost(&req); + if (!my_hosts_access(&req)) { /* This may be stupid but refuse() includes an exit(0) which we surely don't want... clean_exit() - same stupid thing ... */ - syslog(deny_severity, "refused connect from %s", eval_client(&req)); -#else - fromhost(); - if (!hosts_access()) - { - syslog(deny_severity, "refused connect from %s", eval_client()); -#endif - if (req.sink) - ((void (*)(int))req.sink)(req.fd); + syslog(deny_severity, "refused connect from %s", + my_eval_client(&req)); /* C++ sucks (the gibberish in front just translates the supplied @@ -2524,7 +2558,10 @@ pthread_handler_decl(handle_connections_sockets,arg __attribute__((unused))) to a void(*sink)(int) if you omit the cast, the C++ compiler will cry... */ - (void) shutdown(new_sock,2); // This looks fine to me... + if (req.sink) + ((void (*)(int))req.sink)(req.fd); + + (void) shutdown(new_sock,2); (void) closesocket(new_sock); continue; } @@ -2695,7 +2732,7 @@ enum options { OPT_BOOTSTRAP, OPT_SKIP_SHOW_DB, OPT_TABLE_TYPE, OPT_INIT_FILE, OPT_DELAY_KEY_WRITE, OPT_SLOW_QUERY_LOG, - OPT_SKIP_DELAY_KEY_WRITE, OPT_CHARSETS_DIR, + OPT_USE_DELAY_KEY_WRITE, OPT_CHARSETS_DIR, OPT_BDB_HOME, OPT_BDB_LOG, OPT_BDB_TMP, OPT_BDB_NOSYNC, OPT_BDB_LOCK, OPT_BDB_SKIP, @@ -2709,7 +2746,7 @@ enum options { OPT_SQL_BIN_UPDATE_SAME, OPT_REPLICATE_DO_DB, OPT_REPLICATE_IGNORE_DB, OPT_LOG_SLAVE_UPDATES, OPT_BINLOG_DO_DB, OPT_BINLOG_IGNORE_DB, - OPT_WANT_CORE, OPT_SKIP_CONCURRENT_INSERT, + OPT_WANT_CORE, OPT_CONCURRENT_INSERT, OPT_MEMLOCK, OPT_MYISAM_RECOVER, OPT_REPLICATE_REWRITE_DB, OPT_SERVER_ID, OPT_SKIP_SLAVE_START, OPT_SKIP_INNOBASE, @@ -2740,347 +2777,767 @@ enum options { OPT_RPL_RECOVERY_RANK,OPT_INIT_RPL_ROLE, OPT_RELAY_LOG, OPT_RELAY_LOG_INDEX, OPT_RELAY_LOG_INFO_FILE, OPT_SLAVE_SKIP_ERRORS, OPT_DES_KEY_FILE, OPT_LOCAL_INFILE, + OPT_RECKLESS_SLAVE, OPT_SSL_SSL, OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA, - OPT_SSL_CAPATH, OPT_SSL_CIPHER + OPT_SSL_CAPATH, OPT_SSL_CIPHER, + OPT_BACK_LOG, OPT_BINLOG_CACHE_SIZE, + OPT_CONNECT_TIMEOUT, OPT_DELAYED_INSERT_TIMEOUT, + OPT_DELAYED_INSERT_LIMIT, OPT_DELAYED_QUEUE_SIZE, + OPT_FLUSH_TIME, OPT_FT_MIN_WORD_LEN, + OPT_FT_MAX_WORD_LEN, OPT_FT_MAX_WORD_LEN_FOR_SORT, + OPT_INTERACTIVE_TIMEOUT, OPT_JOIN_BUFF_SIZE, + OPT_KEY_BUFFER_SIZE, OPT_LONG_QUERY_TIME, + OPT_LOWER_CASE_TABLE_NAMES, OPT_MAX_ALLOWED_PACKET, + OPT_MAX_BINLOG_CACHE_SIZE, OPT_MAX_BINLOG_SIZE, + OPT_MAX_CONNECTIONS, OPT_MAX_CONNECT_ERRORS, + OPT_MAX_DELAYED_THREADS, OPT_MAX_HEP_TABLE_SIZE, + OPT_MAX_JOIN_SIZE, OPT_MAX_SORT_LENGTH, + OPT_MAX_TMP_TABLES, OPT_MAX_USER_CONNECTIONS, + OPT_MAX_WRITE_LOCK_COUNT, OPT_MYISAM_BULK_INSERT_TREE_SIZE, + OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE, + OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE, + OPT_NET_BUFFER_LENGTH, OPT_NET_RETRY_COUNT, + OPT_NET_READ_TIMEOUT, OPT_NET_WRITE_TIMEOUT, + OPT_OPEN_FILES_LIMIT, OPT_QUERY_BUFFER_SIZE, + OPT_QUERY_CACHE_LIMIT, OPT_QUERY_CACHE_SIZE, + OPT_QUERY_CACHE_STARTUP_TYPE, OPT_RECORD_BUFFER, + OPT_RECORD_RND_BUFFER, OPT_RELAY_LOG_SPACE_LIMIT, + OPT_SLAVE_NET_TIMEOUT, OPT_SLOW_LAUNCH_TIME, + OPT_SORT_BUFFER, OPT_TABLE_CACHE, + OPT_THREAD_CONCURRENCY, OPT_THREAD_CACHE_SIZE, + OPT_TMP_TABLE_SIZE, OPT_THREAD_STACK, + OPT_WAIT_TIMEOUT, + OPT_INNODB_MIRRORED_LOG_GROUPS, + OPT_INNODB_LOG_FILES_IN_GROUP, + OPT_INNODB_LOG_FILE_SIZE, + OPT_INNODB_LOG_BUFFER_SIZE, + OPT_INNODB_BUFFER_POOL_SIZE, + OPT_INNODB_ADDITIONAL_MEM_POOL_SIZE, + OPT_INNODB_FILE_IO_THREADS, + OPT_INNODB_LOCK_WAIT_TIMEOUT, + OPT_INNODB_THREAD_CONCURRENCY, + OPT_INNODB_FORCE_RECOVERY, + OPT_BDB_CACHE_SIZE, + OPT_BDB_LOG_BUFFER_SIZE, + OPT_BDB_MAX_LOCK }; -static struct option long_options[] = { - {"ansi", no_argument, 0, 'a'}, - {"basedir", required_argument, 0, 'b'}, + +#define LONG_TIMEOUT ((ulong) 3600L*24L*365L) + +static struct my_option my_long_options[] = +{ + {"ansi", 'a', "Use ANSI SQL syntax instead of MySQL syntax", 0, 0, 0, + GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"basedir", 'b', + "Path to installation directory. All paths are usually resolved relative to this.", + (gptr*) &mysql_home_ptr, (gptr*) &mysql_home_ptr, 0, GET_STR, REQUIRED_ARG, + 0, 0, 0, 0, 0, 0}, #ifdef HAVE_BERKELEY_DB - {"bdb-home", required_argument, 0, (int) OPT_BDB_HOME}, - {"bdb-lock-detect", required_argument, 0, (int) OPT_BDB_LOCK}, - {"bdb-logdir", required_argument, 0, (int) OPT_BDB_LOG}, - {"bdb-no-recover", no_argument, 0, (int) OPT_BDB_NO_RECOVER}, - {"bdb-no-sync", no_argument, 0, (int) OPT_BDB_NOSYNC}, - {"bdb-shared-data", no_argument, 0, (int) OPT_BDB_SHARED}, - {"bdb-tmpdir", required_argument, 0, (int) OPT_BDB_TMP}, -#endif - {"big-tables", no_argument, 0, (int) OPT_BIG_TABLES}, - {"binlog-do-db", required_argument, 0, (int) OPT_BINLOG_DO_DB}, - {"binlog-ignore-db", required_argument, 0, (int) OPT_BINLOG_IGNORE_DB}, - {"bind-address", required_argument, 0, (int) OPT_BIND_ADDRESS}, - {"bootstrap", no_argument, 0, (int) OPT_BOOTSTRAP}, + {"bdb-home", OPT_BDB_HOME, "Berkeley home directory", (gptr*) &berkeley_home, + (gptr*) &berkeley_home, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"bdb-lock-detect", OPT_BDB_LOCK, + "Berkeley lock detect (DEFAULT, OLDEST, RANDOM or YOUNGEST, # sec)", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"bdb-logdir", OPT_BDB_LOG, "Berkeley DB log file directory", + (gptr*) &berkeley_logdir, (gptr*) &berkeley_logdir, 0, GET_STR, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"bdb-no-recover", OPT_BDB_NO_RECOVER, + "Don't try to recover Berkeley DB tables on start", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, + {"bdb-no-sync", OPT_BDB_NOSYNC, "Don't synchronously flush logs", 0, 0, 0, + GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"bdb-shared-data", OPT_BDB_SHARED, + "Start Berkeley DB in multi-process mode", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, + 0, 0, 0, 0, 0}, + {"bdb-tmpdir", OPT_BDB_TMP, "Berkeley DB tempfile name", + (gptr*) &berkeley_tmpdir, (gptr*) &berkeley_tmpdir, 0, GET_STR, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, +#endif /* HAVE_BERKELEY_DB */ + {"skip-bdb", OPT_BDB_SKIP, "Don't use berkeley db (will save memory)", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"big-tables", OPT_BIG_TABLES, + "Allow big result sets by saving all temporary sets on file (Solves most 'table full' errors)", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"binlog-do-db", OPT_BINLOG_DO_DB, + "Tells the master it should log updates for the specified database, and exclude all others not explicitly mentioned.", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"binlog-ignore-db", OPT_BINLOG_IGNORE_DB, + "Tells the master that updates to the given database should not be logged tothe binary log", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"bind-address", OPT_BIND_ADDRESS, "Ip address to bind to", + (gptr*) &my_bind_addr, (gptr*) &my_bind_addr, 0, GET_ULONG, REQUIRED_ARG, 0, + 0, 0, 0, 0, 0}, + {"bootstrap", OPT_BOOTSTRAP, "Used by mysql installation scripts", 0, 0, 0, + GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifdef __WIN__ - {"console", no_argument, 0, (int) OPT_CONSOLE}, -#endif - {"core-file", no_argument, 0, (int) OPT_WANT_CORE}, - {"chroot", required_argument, 0, 'r'}, - {"character-sets-dir", required_argument, 0, (int) OPT_CHARSETS_DIR}, - {"datadir", required_argument, 0, 'h'}, - {"debug", optional_argument, 0, '#'}, - {"des-key-file", required_argument, 0, (int) OPT_DES_KEY_FILE}, - {"default-character-set", required_argument, 0, 'C'}, - {"default-table-type", required_argument, 0, (int) OPT_TABLE_TYPE}, - {"delay-key-write-for-all-tables", - no_argument, 0, (int) OPT_DELAY_KEY_WRITE}, - {"enable-locking", no_argument, 0, (int) OPT_ENABLE_LOCK}, - {"enable-named-pipe", no_argument, 0, (int) OPT_HAVE_NAMED_PIPE}, - {"enable-pstack", no_argument, 0, (int) OPT_DO_PSTACK}, - {"exit-info", optional_argument, 0, 'T'}, - {"flush", no_argument, 0, (int) OPT_FLUSH}, - {"init-rpl-role", required_argument, 0, (int) OPT_INIT_RPL_ROLE}, - /* We must always support this option to make scripts like mysqltest easier - to do */ - {"innodb_data_file_path", required_argument, 0, - OPT_INNODB_DATA_FILE_PATH}, + {"console", OPT_CONSOLE, "Don't remove the console window", + (gptr*) &opt_console, (gptr*) &opt_console, 0, GET_BOOL, NO_ARG, 0, 0, 0, + 0, 0, 0}, + {"standalone", OPT_STANDALONE, + "Dummy option to start as a standalone program (NT)", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, +#endif + {"core-file", OPT_WANT_CORE, "Write core on errors", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, + {"chroot", 'r', "Chroot mysqld daemon during startup.", + (gptr*) &mysqld_chroot, (gptr*) &mysqld_chroot, 0, GET_STR, REQUIRED_ARG, + 0, 0, 0, 0, 0, 0}, + {"character-sets-dir", OPT_CHARSETS_DIR, + "Directory where character sets are", (gptr*) &charsets_dir, + (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"datadir", 'h', "Path to the database root", (gptr*) &mysql_data_home, + (gptr*) &mysql_data_home, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, +#ifndef DBUG_OFF + {"debug", '#', "Debug log.", (gptr*) &default_dbug_option, + (gptr*) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, +#ifdef SAFEMALLOC + {"skip-safemalloc", OPT_SKIP_SAFEMALLOC, + "Don't use the memory allocation checking", 0, 0, 0, GET_NO_ARG, NO_ARG, + 0, 0, 0, 0, 0, 0}, +#endif +#endif +#ifdef HAVE_OPENSSL + {"des-key-file", OPT_DES_KEY_FILE, + "Load keys for des_encrypt() and des_encrypt from given file", + (gptr*) &des_key_file, (gptr*) &des_key_file, 0, GET_STR, REQUIRED_ARG, + 0, 0, 0, 0, 0, 0}, +#endif /* HAVE_OPENSSL */ + {"default-character-set", 'C', "Set the default character set", + (gptr*) &default_charset_ptr, (gptr*) &default_charset_ptr, 0, GET_STR, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"default-table-type", OPT_TABLE_TYPE, + "Set the default table type for tables", (gptr*) &default_table_type_name, + (gptr*) &default_table_type_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, + 0}, + {"delay-key-write-for-all-tables", OPT_DELAY_KEY_WRITE, + "Don't flush key buffers between writes for any MyISAM table", 0, 0, 0, + GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"enable-locking", OPT_ENABLE_LOCK, "Enable system locking", 0, 0, 0, + GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, +#ifdef __NT__ + {"enable-named-pipe", OPT_HAVE_NAMED_PIPE, "Enable the named pipe (NT)", + (gptr*) &opt_enable_named_pipe, (gptr*) &opt_enable_named_pipe, 0, GET_BOOL, + NO_ARG, 0, 0, 0, 0, 0, 0}, +#endif + {"enable-pstack", OPT_DO_PSTACK, "Print a symbolic stack trace on failure", + (gptr*) &opt_do_pstack, (gptr*) &opt_do_pstack, 0, GET_BOOL, NO_ARG, 0, 0, + 0, 0, 0, 0}, + {"exit-info", 'T', "Used for debugging; Use at your own risk!", 0, 0, 0, + GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"flush", OPT_FLUSH, "Flush tables to disk between SQL commands", 0, 0, 0, + GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + /* We must always support the next option to make scripts like mysqltest + easier to do */ + {"init-rpl-role", OPT_INIT_RPL_ROLE, "Set the replication role", 0, 0, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"innodb_data_file_path", OPT_INNODB_DATA_FILE_PATH, + "Path to individual files and their sizes", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #ifdef HAVE_INNOBASE_DB - {"innodb_data_home_dir", required_argument, 0, - OPT_INNODB_DATA_HOME_DIR}, - {"innodb_log_group_home_dir", required_argument, 0, - OPT_INNODB_LOG_GROUP_HOME_DIR}, - {"innodb_log_arch_dir", required_argument, 0, - OPT_INNODB_LOG_ARCH_DIR}, - {"innodb_log_archive", optional_argument, 0, - OPT_INNODB_LOG_ARCHIVE}, - {"innodb_flush_log_at_trx_commit", optional_argument, 0, - OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT}, - {"innodb_fast_shutdown", optional_argument, 0, - OPT_INNODB_FAST_SHUTDOWN}, - {"innodb_flush_method", required_argument, 0, - OPT_INNODB_FLUSH_METHOD}, -#endif - {"help", no_argument, 0, '?'}, - {"init-file", required_argument, 0, (int) OPT_INIT_FILE}, - {"log", optional_argument, 0, 'l'}, - {"language", required_argument, 0, 'L'}, - {"local-infile", optional_argument, 0, (int) OPT_LOCAL_INFILE}, - {"log-bin", optional_argument, 0, (int) OPT_BIN_LOG}, - {"log-bin-index", required_argument, 0, (int) OPT_BIN_LOG_INDEX}, - {"log-isam", optional_argument, 0, (int) OPT_ISAM_LOG}, - {"log-update", optional_argument, 0, (int) OPT_UPDATE_LOG}, - {"log-slow-queries", optional_argument, 0, (int) OPT_SLOW_QUERY_LOG}, - {"log-long-format", no_argument, 0, (int) OPT_LONG_FORMAT}, - {"log-slave-updates", no_argument, 0, (int) OPT_LOG_SLAVE_UPDATES}, - {"low-priority-updates", no_argument, 0, (int) OPT_LOW_PRIORITY_UPDATES}, - {"master-host", required_argument, 0, (int) OPT_MASTER_HOST}, - {"master-user", required_argument, 0, (int) OPT_MASTER_USER}, - {"master-password", required_argument, 0, (int) OPT_MASTER_PASSWORD}, - {"master-port", required_argument, 0, (int) OPT_MASTER_PORT}, - {"master-connect-retry", required_argument, 0, (int) OPT_MASTER_CONNECT_RETRY}, - {"master-retry-count", required_argument, 0, (int) OPT_MASTER_RETRY_COUNT}, - {"master-info-file", required_argument, 0, (int) OPT_MASTER_INFO_FILE}, - {"master-ssl", optional_argument, 0, (int) OPT_MASTER_SSL}, - {"master-ssl-key", optional_argument, 0, (int) OPT_MASTER_SSL_KEY}, - {"master-ssl-cert", optional_argument, 0, (int) OPT_MASTER_SSL_CERT}, - {"myisam-recover", optional_argument, 0, (int) OPT_MYISAM_RECOVER}, - {"memlock", no_argument, 0, (int) OPT_MEMLOCK}, + {"innodb_data_home_dir", OPT_INNODB_DATA_HOME_DIR, + "The common part for Innodb table spaces", (gptr*) &innobase_data_home_dir, + (gptr*) &innobase_data_home_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, + 0}, + {"innodb_log_group_home_dir", OPT_INNODB_LOG_GROUP_HOME_DIR, + "Path to innodb log files.", (gptr*) &innobase_log_group_home_dir, + (gptr*) &innobase_log_group_home_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, + 0, 0}, + {"innodb_log_arch_dir", OPT_INNODB_LOG_ARCH_DIR, + "Where full logs should be archived", (gptr*) &innobase_log_arch_dir, + (gptr*) &innobase_log_arch_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"innodb_log_archive", OPT_INNODB_LOG_ARCHIVE, + "Set to 1 if you want to have logs archived", 0, 0, 0, GET_LONG, OPT_ARG, + 0, 0, 0, 0, 0, 0}, + {"innodb_flush_log_at_trx_commit", OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT, + "Set to 0 if you don't want to flush logs", 0, 0, 0, GET_LONG, OPT_ARG, + 0, 0, 0, 0, 0, 0}, + {"innodb_flush_method", OPT_INNODB_FLUSH_METHOD, + "With which method to flush data", (gptr*) &innobase_unix_file_flush_method, + (gptr*) &innobase_unix_file_flush_method, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, + 0, 0, 0}, + {"innodb_fast_shutdown", OPT_INNODB_FAST_SHUTDOWN, + "Speeds up server shutdown process", (gptr*) &innobase_fast_shutdown, + (gptr*) &innobase_fast_shutdown, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, +#endif /* End HAVE_INNOBASE_DB */ + {"help", '?', "Display this help and exit", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, + 0, 0, 0, 0, 0}, + {"init-file", OPT_INIT_FILE, "Read SQL commands from this file at startup", + (gptr*) &opt_init_file, (gptr*) &opt_init_file, 0, GET_STR, REQUIRED_ARG, + 0, 0, 0, 0, 0, 0}, + {"log", 'l', "Log connections and queries to file", (gptr*) &opt_logname, + (gptr*) &opt_logname, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"language", 'L', + "Client error messages in given language. May be given as a full path", + (gptr*) &language_ptr, (gptr*) &language_ptr, 0, GET_STR, REQUIRED_ARG, + 0, 0, 0, 0, 0, 0}, + {"local-infile", OPT_LOCAL_INFILE, + "Enable/disable LOAD DATA LOCAL INFILE (takes values 1|0)", + (gptr*) &opt_local_infile, (gptr*) &opt_local_infile, 0, GET_BOOL, OPT_ARG, + 1, 0, 0, 0, 0, 0}, + {"log-bin", OPT_BIN_LOG, + "Log queries in new binary format (for replication)", + (gptr*) &opt_bin_logname, (gptr*) &opt_bin_logname, 0, GET_STR_ALLOC, + OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"log-bin-index", OPT_BIN_LOG_INDEX, + "File that holds the names for last binary log files", + (gptr*) &opt_binlog_index_name, (gptr*) &opt_binlog_index_name, 0, GET_STR, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"log-isam", OPT_ISAM_LOG, "Log all MyISAM changes to file", + (gptr*) &myisam_log_filename, (gptr*) &myisam_log_filename, 0, GET_STR, + OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"log-update", OPT_UPDATE_LOG, + "Log updates to file.# where # is a unique number if not given.", + (gptr*) &opt_update_logname, (gptr*) &opt_update_logname, 0, GET_STR, + OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"log-slow-queries", OPT_SLOW_QUERY_LOG, + "Log slow queries to this log file. Defaults logging to hostname-slow.log", + (gptr*) &opt_slow_logname, (gptr*) &opt_slow_logname, 0, GET_STR, OPT_ARG, + 0, 0, 0, 0, 0, 0}, + {"log-long-format", OPT_LONG_FORMAT, + "Log some extra information to update log", 0, 0, 0, GET_NO_ARG, NO_ARG, + 0, 0, 0, 0, 0, 0}, + {"log-slave-updates", OPT_LOG_SLAVE_UPDATES, + "Tells the slave to log the updates from the slave thread to the binary log. Off by default. You will need to turn it on if you plan to daisy-chain the slaves.", + (gptr*) &opt_log_slave_updates, (gptr*) &opt_log_slave_updates, 0, GET_BOOL, + NO_ARG, 0, 0, 0, 0, 0, 0}, + {"low-priority-updates", OPT_LOW_PRIORITY_UPDATES, + "INSERT/DELETE/UPDATE has lower priority than selects", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, + {"master-host", OPT_MASTER_HOST, + "Master hostname or IP address for replication. If not set, the slave thread will not be started. Note that the setting of master-host will be ignored if there exists a valid master.info file.", + (gptr*) &master_host, (gptr*) &master_host, 0, GET_STR, REQUIRED_ARG, 0, 0, + 0, 0, 0, 0}, + {"master-user", OPT_MASTER_USER, + "The username the slave thread will use for authentication when connecting to the master. The user must have FILE privilege. If the master user is not set, user test is assumed. The value in master.info will take precedence if it can be read.", + (gptr*) &master_user, (gptr*) &master_user, 0, GET_STR, REQUIRED_ARG, 0, 0, + 0, 0, 0, 0}, + {"master-password", OPT_MASTER_PASSWORD, + "The password the slave thread will authenticate with when connecting to the master. If not set, an empty password is assumed.The value in master.info will take precedence if it can be read.", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"master-port", OPT_MASTER_PORT, + "The port the master is listening on. If not set, the compiled setting of MYSQL_PORT is assumed. If you have not tinkered with configure options, this should be 3306. The value in master.info will take precedence if it can be read", + (gptr*) &master_port, (gptr*) &master_port, 0, GET_UINT, REQUIRED_ARG, + MYSQL_PORT, 0, 0, 0, 0, 0}, + {"master-connect-retry", OPT_MASTER_CONNECT_RETRY, + "The number of seconds the slave thread will sleep before retrying to connect to the master in case the master goes down or the connection is lost.", + (gptr*) &master_connect_retry, (gptr*) &master_connect_retry, 0, GET_UINT, + REQUIRED_ARG, 60, 0, 0, 0, 0, 0}, + {"master-retry-count", OPT_MASTER_RETRY_COUNT, + "The number of tries the slave will make to connect to the master before giving up.", + (gptr*) &master_retry_count, (gptr*) &master_retry_count, 0, GET_ULONG, + REQUIRED_ARG, 60, 0, 0, 0, 0, 0}, + {"master-info-file", OPT_MASTER_INFO_FILE, + "The location of the file that remembers where we left off on the master during the replication process. The default is `master.info' in the data directory. You should not need to change this.", + (gptr*) &master_info_file, (gptr*) &master_info_file, 0, GET_STR, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"master-ssl", OPT_MASTER_SSL, + "Turn SSL on for replication. Be warned that is this is a relatively new feature.", + (gptr*) &master_ssl, (gptr*) &master_ssl, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, + 0, 0}, + {"master-ssl-key", OPT_MASTER_SSL_KEY, + "Master SSL keyfile name. Only applies if you have enabled master-ssl.", + (gptr*) &master_ssl_key, (gptr*) &master_ssl_key, 0, GET_STR, OPT_ARG, + 0, 0, 0, 0, 0, 0}, + {"master-ssl-cert", OPT_MASTER_SSL_CERT, + "Master SSL certificate file name. Only applies if you have enabled master-ssl.", + (gptr*) &master_ssl_cert, (gptr*) &master_ssl_cert, 0, GET_STR, OPT_ARG, + 0, 0, 0, 0, 0, 0}, + {"myisam-recover", OPT_MYISAM_RECOVER, + "Syntax: myisam-recover[=option[,option...]], where option can be DEFAULT, BACKUP or FORCE.", + (gptr*) &myisam_recover_options_str, (gptr*) &myisam_recover_options_str, 0, + GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, /* Option needs to be available for the test case to pass in non-debugging mode. is a no-op. */ - {"disconnect-slave-event-count", required_argument, 0, - (int) OPT_DISCONNECT_SLAVE_EVENT_COUNT}, - {"abort-slave-event-count", required_argument, 0, - (int) OPT_ABORT_SLAVE_EVENT_COUNT}, - {"max-binlog-dump-events", required_argument, 0, - (int) OPT_MAX_BINLOG_DUMP_EVENTS}, - {"sporadic-binlog-dump-fail", no_argument, 0, - (int) OPT_SPORADIC_BINLOG_DUMP_FAIL}, - {"safemalloc-mem-limit", required_argument, 0, (int) - OPT_SAFEMALLOC_MEM_LIMIT}, - {"new", no_argument, 0, 'n'}, + {"memlock", OPT_MEMLOCK, "Lock mysqld in memory", (gptr*) &locked_in_memory, + (gptr*) &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"disconnect-slave-event-count", OPT_DISCONNECT_SLAVE_EVENT_COUNT, + "Undocumented: Meant for debugging and testing of replication", + (gptr*) &disconnect_slave_event_count, + (gptr*) &disconnect_slave_event_count, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, + 0, 0, 0}, + {"abort-slave-event-count", OPT_ABORT_SLAVE_EVENT_COUNT, + "Undocumented: Meant for debugging and testing of replication", + (gptr*) &abort_slave_event_count, (gptr*) &abort_slave_event_count, + 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"max-binlog-dump-events", OPT_MAX_BINLOG_DUMP_EVENTS, "Undocumented", + (gptr*) &max_binlog_dump_events, (gptr*) &max_binlog_dump_events, 0, + GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"sporadic-binlog-dump-fail", OPT_SPORADIC_BINLOG_DUMP_FAIL, "Undocumented", + (gptr*) &opt_sporadic_binlog_dump_fail, + (gptr*) &opt_sporadic_binlog_dump_fail, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, + 0}, + {"safemalloc-mem-limit", OPT_SAFEMALLOC_MEM_LIMIT, + "Simulate memory shortage when compiled with the --with-debug=full option", + 0, 0, 0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"new", 'n', "Use very new possible 'unsafe' functions", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, #ifdef NOT_YET - {"no-mix-table-types", no_argument, 0, (int) OPT_NO_MIX_TYPE}, -#endif - {"old-protocol", no_argument, 0, 'o'}, - {"old-rpl-compat", no_argument, 0, (int) OPT_OLD_RPL_COMPAT}, + {"no-mix-table-types", OPT_NO_MIX_TYPE, "Undocumented", + (gptr*) &opt_no_mix_types, (gptr*) &opt_no_mix_types, 0, GET_BOOL, NO_ARG, + 0, 0, 0, 0, 0, 0}, +#endif + {"old-protocol", 'o', "Use the old (3.20) protocol", + (gptr*) &protocol_version, (gptr*) &protocol_version, 0, GET_UINT, NO_ARG, + PROTOCOL_VERSION, 0, 0, 0, 0, 0}, + {"old-rpl-compat", OPT_OLD_RPL_COMPAT, "Undocumented", + (gptr*) &opt_old_rpl_compat, (gptr*) &opt_old_rpl_compat, 0, GET_BOOL, + NO_ARG, 0, 0, 0, 0, 0, 0}, #ifdef ONE_THREAD - {"one-thread", no_argument, 0, (int) OPT_ONE_THREAD}, -#endif - {"pid-file", required_argument, 0, (int) OPT_PID_FILE}, - {"port", required_argument, 0, 'P'}, - {"replicate-do-db", required_argument, 0, (int) OPT_REPLICATE_DO_DB}, - {"replicate-do-table", required_argument, 0, - (int) OPT_REPLICATE_DO_TABLE}, - {"replicate-wild-do-table", required_argument, 0, - (int) OPT_REPLICATE_WILD_DO_TABLE}, - {"replicate-ignore-db", required_argument, 0, - (int) OPT_REPLICATE_IGNORE_DB}, - {"replicate-ignore-table", required_argument, 0, - (int) OPT_REPLICATE_IGNORE_TABLE}, - {"replicate-wild-ignore-table", required_argument, 0, - (int) OPT_REPLICATE_WILD_IGNORE_TABLE}, - {"replicate-rewrite-db", required_argument, 0, - (int) OPT_REPLICATE_REWRITE_DB}, + {"one-thread", OPT_ONE_THREAD, + "Only use one thread (for debugging under Linux)", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, +#endif + {"pid-file", OPT_PID_FILE, "Pid file used by safe_mysqld", + (gptr*) &pidfile_name_ptr, (gptr*) &pidfile_name_ptr, 0, GET_STR, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"port", 'P', "Port number to use for connection.", (gptr*) &mysql_port, + (gptr*) &mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"reckless-slave", OPT_RECKLESS_SLAVE, "Undocumented", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, + {"replicate-do-db", OPT_REPLICATE_DO_DB, + "Tells the slave thread to restrict replication to the specified database. To specify more than one database, use the directive multiple times, once for each database. Note that this will only work if you do not use cross-database queries such as UPDATE some_db.some_table SET foo='bar' while having selected a different or no database. If you need cross database updates to work, make sure you have 3.23.28 or later, and use replicate-wild-do-table=db_name.%.", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"replicate-do-table", OPT_REPLICATE_DO_TABLE, + "Tells the slave thread to restrict replication to the specified table. To specify more than one table, use the directive multiple times, once for each table. This will work for cross-database updates, in contrast to replicate-do-db.", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"replicate-wild-do-table", OPT_REPLICATE_WILD_DO_TABLE, + "Tells the slave thread to restrict replication to the tables that match the specified wildcard pattern. To specify more than one table, use the directive multiple times, once for each table. This will work for cross-database updates. Example: replicate-wild-do-table=foo%.bar% will replicate only updates to tables in all databases that start with foo and whose table names start with bar", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"replicate-ignore-db", OPT_REPLICATE_IGNORE_DB, + "Tells the slave thread to not replicate to the specified database. To specify more than one database to ignore, use the directive multiple times, once for each database. This option will not work if you use cross database updates. If you need cross database updates to work, make sure you have 3.23.28 or later, and use replicate-wild-ignore-table=db_name.%. ", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"replicate-ignore-table", OPT_REPLICATE_IGNORE_TABLE, + "Tells the slave thread to not replicate to the specified table. To specify more than one table to ignore, use the directive multiple times, once for each table. This will work for cross-datbase updates, in contrast to replicate-ignore-db.", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"replicate-wild-ignore-table", OPT_REPLICATE_WILD_IGNORE_TABLE, + "Tells the slave thread to not replicate to the tables that match the given wildcard pattern. To specify more than one table to ignore, use the directive multiple times, once for each table. This will work for cross-database updates. Example: replicate-wild-ignore-table=foo%.bar% will not do updates to tables in databases that start with foo and whose table names start with bar.", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"replicate-rewrite-db", OPT_REPLICATE_REWRITE_DB, + "Updates to a database with a different name than the original. Example: replicate-rewrite-db=master_db_name->slave_db_name", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, // In replication, we may need to tell the other servers how to connect - {"report-host", required_argument, 0, (int) OPT_REPORT_HOST}, - {"report-user", required_argument, 0, (int) OPT_REPORT_USER}, - {"report-password", required_argument, 0, (int) OPT_REPORT_PASSWORD}, - {"report-port", required_argument, 0, (int) OPT_REPORT_PORT}, - {"rpl-recovery-rank", required_argument, 0, (int) OPT_RPL_RECOVERY_RANK}, - {"relay-log", required_argument, 0, (int) OPT_RELAY_LOG}, - {"relay-log-index", required_argument, 0, (int) OPT_RELAY_LOG_INDEX}, - {"safe-mode", no_argument, 0, (int) OPT_SAFE}, - {"safe-show-database", no_argument, 0, (int) OPT_SAFE_SHOW_DB}, - {"safe-user-create", no_argument, 0, (int) OPT_SAFE_USER_CREATE}, - {"server-id", required_argument, 0, (int) OPT_SERVER_ID}, - {"set-variable", required_argument, 0, 'O'}, - {"show-slave-auth-info", no_argument, 0, - (int) OPT_SHOW_SLAVE_AUTH_INFO}, - {"skip-bdb", no_argument, 0, (int) OPT_BDB_SKIP}, - {"skip-innodb", no_argument, 0, (int) OPT_INNODB_SKIP}, - {"skip-concurrent-insert", no_argument, 0, (int) OPT_SKIP_CONCURRENT_INSERT}, - {"skip-delay-key-write", no_argument, 0, (int) OPT_SKIP_DELAY_KEY_WRITE}, - {"skip-grant-tables", no_argument, 0, (int) OPT_SKIP_GRANT}, - {"skip-locking", no_argument, 0, (int) OPT_SKIP_LOCK}, - {"skip-host-cache", no_argument, 0, (int) OPT_SKIP_HOST_CACHE}, - {"skip-name-resolve", no_argument, 0, (int) OPT_SKIP_RESOLVE}, - {"skip-networking", no_argument, 0, (int) OPT_SKIP_NETWORKING}, - {"skip-new", no_argument, 0, (int) OPT_SKIP_NEW}, - {"skip-safemalloc", no_argument, 0, (int) OPT_SKIP_SAFEMALLOC}, - {"skip-show-database", no_argument, 0, (int) OPT_SKIP_SHOW_DB}, - {"skip-slave-start", no_argument, 0, (int) OPT_SKIP_SLAVE_START}, - {"skip-stack-trace", no_argument, 0, (int) OPT_SKIP_STACK_TRACE}, - {"skip-symlink", no_argument, 0, (int) OPT_SKIP_SYMLINKS}, - {"skip-thread-priority", no_argument, 0, (int) OPT_SKIP_PRIOR}, - {"relay-log-info-file", required_argument, 0, - (int) OPT_RELAY_LOG_INFO_FILE}, - {"slave-load-tmpdir", required_argument, 0, (int) OPT_SLAVE_LOAD_TMPDIR}, - {"slave-skip-errors", required_argument, 0, - (int) OPT_SLAVE_SKIP_ERRORS}, - {"socket", required_argument, 0, (int) OPT_SOCKET}, - {"sql-bin-update-same", no_argument, 0, (int) OPT_SQL_BIN_UPDATE_SAME}, - {"sql-mode", required_argument, 0, (int) OPT_SQL_MODE}, + {"report-host", OPT_REPORT_HOST, + "Hostname or IP of the slave to be reported to to the master during slave registration. Will appear in the output of SHOW SLAVE HOSTS. Leave unset if you do not want the slave to register itself with the master. Note that it is not sufficient for the master to simply read the IP of the slave off the socket once the slave connects. Due to NAT and other routing issues, that IP may not be valid for connecting to the slave from the master or other hosts.", + (gptr*) &report_host, (gptr*) &report_host, 0, GET_STR, REQUIRED_ARG, 0, 0, + 0, 0, 0, 0}, + {"report-user", OPT_REPORT_USER, "Undocumented", (gptr*) &report_user, + (gptr*) &report_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"report-password", OPT_REPORT_PASSWORD, "Undocumented", + (gptr*) &report_password, (gptr*) &report_password, 0, GET_STR, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"report-port", OPT_REPORT_PORT, + "Port for connecting to slave reported to the master during slave registration. Set it only if the slave is listening on a non-default port or if you have a special tunnel from the master or other clients to the slave. If not sure, leave this option unset.", + (gptr*) &report_port, (gptr*) &report_port, 0, GET_UINT, REQUIRED_ARG, + MYSQL_PORT, 0, 0, 0, 0, 0}, + {"rpl-recovery-rank", OPT_RPL_RECOVERY_RANK, "Undocumented", + (gptr*) &rpl_recovery_rank, (gptr*) &rpl_recovery_rank, 0, GET_UINT, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"relay-log", OPT_RELAY_LOG, "Undocumented", + (gptr*) &opt_relay_logname, (gptr*) &opt_relay_logname, 0, + GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"relay-log-index", OPT_RELAY_LOG_INDEX, "Undocumented", + (gptr*) &opt_relaylog_index_name, (gptr*) &opt_relaylog_index_name, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"safe-mode", OPT_SAFE, "Skip some optimize stages (for testing).", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"safe-show-database", OPT_SAFE_SHOW_DB, + "Don't show databases for which the user has no privileges", + (gptr*) &opt_safe_show_db, (gptr*) &opt_safe_show_db, 0, GET_BOOL, NO_ARG, + 0, 0, 0, 0, 0, 0}, + {"safe-user-create", OPT_SAFE_USER_CREATE, + "Don't allow new user creation by the user who has no write privileges to the mysql.user table", + (gptr*) &opt_safe_user_create, (gptr*) &opt_safe_user_create, 0, GET_BOOL, + NO_ARG, 0, 0, 0, 0, 0, 0}, + {"server-id", OPT_SERVER_ID, + "Uniquely identifies the server instance in the community of replication partners", + (gptr*) &server_id, (gptr*) &server_id, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, + 0, 0, 0}, + {"set-variable", 'O', + "Change the value of a variable. Please note that this option is deprecated;you can set variables directly with --variable-name=value.", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"show-slave-auth-info", OPT_SHOW_SLAVE_AUTH_INFO, "Undocumented", + (gptr*) &opt_show_slave_auth_info, (gptr*) &opt_show_slave_auth_info, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"concurrent-insert", OPT_CONCURRENT_INSERT, + "Use concurrent insert with MyISAM. Disable with prefix --skip-", + (gptr*) &myisam_concurrent_insert, (gptr*) &myisam_concurrent_insert, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"delay-key-write", OPT_USE_DELAY_KEY_WRITE, + "Use delay_key_write option for all tables. Disable with prefix --skip-", + (gptr*) &myisam_delay_key_write, (gptr*) &myisam_delay_key_write, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"skip-grant-tables", OPT_SKIP_GRANT, + "Start without grant tables. This gives all users FULL ACCESS to all tables!", + (gptr*) &opt_noacl, (gptr*) &opt_noacl, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, + 0}, + {"skip-innodb", OPT_INNODB_SKIP, "Don't use Innodb (will save memory)", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"skip-locking", OPT_SKIP_LOCK, + "Don't use system locking. To use isamchk one has to shut down the server.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"skip-host-cache", OPT_SKIP_HOST_CACHE, "Don't cache host names", 0, 0, 0, + GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"skip-name-resolve", OPT_SKIP_RESOLVE, + "Don't resolve hostnames. All hostnames are IP's or 'localhost'", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"skip-networking", OPT_SKIP_NETWORKING, + "Don't allow connection with TCP/IP.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, + 0, 0, 0}, + {"skip-new", OPT_SKIP_NEW, "Don't use new, possible wrong routines.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"skip-show-database", OPT_SKIP_SHOW_DB, + "Don't allow 'SHOW DATABASE' commands", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, + 0, 0, 0, 0}, + {"skip-slave-start", OPT_SKIP_SLAVE_START, + "If set, slave is not autostarted.", (gptr*) &opt_skip_slave_start, + (gptr*) &opt_skip_slave_start, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"skip-stack-trace", OPT_SKIP_STACK_TRACE, + "Don't print a stack trace on failure", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, + 0, 0, 0, 0}, + {"skip-symlink", OPT_SKIP_SYMLINKS, "Don't allow symlinking of tables", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"skip-thread-priority", OPT_SKIP_PRIOR, + "Don't give threads different priorities.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, + 0, 0, 0, 0, 0}, + {"relay-log-info-file", OPT_RELAY_LOG_INFO_FILE, "Undocumented", + (gptr*) &relay_log_info_file, (gptr*) &relay_log_info_file, 0, GET_STR, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"slave-load-tmpdir", OPT_SLAVE_LOAD_TMPDIR, "Undocumented", + (gptr*) &slave_load_tmpdir, (gptr*) &slave_load_tmpdir, 0, GET_STR_ALLOC, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"slave-skip-errors", OPT_SLAVE_SKIP_ERRORS, + "Tells the slave thread to continue replication when a query returns an error from the provided list", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"socket", OPT_SOCKET, "Socket file to use for connection", + (gptr*) &mysql_unix_port, (gptr*) &mysql_unix_port, 0, GET_STR, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"sql-bin-update-same", OPT_SQL_BIN_UPDATE_SAME, + "If set, setting SQL_LOG_BIN to a value will automatically set SQL_LOG_UPDATE to the same value and vice versa.", + (gptr*) &opt_sql_bin_update, (gptr*) &opt_sql_bin_update, 0, GET_BOOL, + NO_ARG, 0, 0, 0, 0, 0, 0}, + {"sql-mode", OPT_SQL_MODE, + "Syntax: sql-mode=option[,option[,option...]] where option can be one of: REAL_AS_FLOAT, PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, SERIALIZE, ONLY_FULL_GROUP_BY, NO_UNSIGNED_SUBTRACTION.", + (gptr*) &sql_mode_str, (gptr*) &sql_mode_str, 0, GET_STR, REQUIRED_ARG, 0, + 0, 0, 0, 0, 0}, #ifdef HAVE_OPENSSL - {"ssl", no_argument, 0, OPT_SSL_SSL}, - {"ssl-key", required_argument, 0, OPT_SSL_KEY}, - {"ssl-cert", required_argument, 0, OPT_SSL_CERT}, - {"ssl-ca", required_argument, 0, OPT_SSL_CA}, - {"ssl-capath", required_argument, 0, OPT_SSL_CAPATH}, - {"ssl-cipher", required_argument, 0, OPT_SSL_CIPHER}, -#endif -#ifdef __WIN__ - {"standalone", no_argument, 0, (int) OPT_STANDALONE}, -#endif - {"transaction-isolation", required_argument, 0, (int) OPT_TX_ISOLATION}, - {"temp-pool", no_argument, 0, (int) OPT_TEMP_POOL}, - {"tmpdir", required_argument, 0, 't'}, - {"use-locking", no_argument, 0, (int) OPT_USE_LOCKING}, +#include "sslopt-longopts.h" +#endif + {"temp-pool", OPT_TEMP_POOL, + "Using this option will cause most temporary files created to use a small set of names, rather than a unique name for each new file.", + (gptr*) &use_temp_pool, (gptr*) &use_temp_pool, 0, GET_BOOL, NO_ARG, 0, 0, + 0, 0, 0, 0}, + {"tmpdir", 't', "Path for temporary files", (gptr*) &mysql_tmpdir, + (gptr*) &mysql_tmpdir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"transaction-isolation", OPT_TX_ISOLATION, + "Default transaction isolation level", (gptr*) &default_tx_isolation_name, + (gptr*) &default_tx_isolation_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, + 0, 0}, + {"use-locking", OPT_USE_LOCKING, "Use system (external) locking", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifdef USE_SYMDIR - {"use-symbolic-links", no_argument, 0, 's'}, -#endif - {"user", required_argument, 0, 'u'}, - {"version", no_argument, 0, 'V'}, - {"warnings", no_argument, 0, 'W'}, - {0, 0, 0, 0} -}; - -#define LONG_TIMEOUT ((ulong) 3600L*24L*365L) - -CHANGEABLE_VAR changeable_vars[] = { - { "back_log", (long*) &back_log, - 50, 1, 65535, 0, 1 }, + {"use-symbolic-links", 's', "Enable symbolic link support", + (gptr*) &my_use_symdir, (gptr*) &my_use_symdir, 0, GET_BOOL, NO_ARG, 0, 0, + 0, 0, 0, 0}, +#endif + {"user", 'u', "Run mysqld daemon as user", (gptr*) &mysqld_user, + (gptr*) &mysqld_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"version", 'V', "Output version information and exit", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, + {"version", 'v', "Synonym for option -v", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, + 0, 0, 0, 0}, + {"warnings", 'W', "Log some not critical warnings to the log file", + (gptr*) &opt_warnings, (gptr*) &opt_warnings, 0, GET_BOOL, NO_ARG, 0, 0, 0, + 0, 0, 0}, + { "back_log", OPT_BACK_LOG, + "The number of outstanding connection requests MySQL can have. This comes into play when the main MySQL thread gets very many connection requests in a very short time.", (gptr*) &back_log, (gptr*) &back_log, 0, GET_ULONG, + REQUIRED_ARG, 50, 1, 65535, 0, 1, 0 }, #ifdef HAVE_BERKELEY_DB - { "bdb_cache_size", (long*) &berkeley_cache_size, - KEY_CACHE_SIZE, 20*1024, (long) ~0, 0, IO_SIZE }, - {"bdb_log_buffer_size", (long*) &berkeley_log_buffer_size, 0, 256*1024L, - ~0L, 0, 1024}, - { "bdb_max_lock", (long*) &berkeley_max_lock, - 10000, 0, (long) ~0, 0, 1 }, - /* QQ: The following should be removed soon! */ - { "bdb_lock_max", (long*) &berkeley_max_lock, - 10000, 0, (long) ~0, 0, 1 }, -#endif - { "binlog_cache_size", (long*) &binlog_cache_size, - 32*1024L, IO_SIZE, ~0L, 0, IO_SIZE }, - { "connect_timeout", (long*) &connect_timeout, - CONNECT_TIMEOUT, 2, LONG_TIMEOUT, 0, 1 }, - { "delayed_insert_timeout", (long*) &delayed_insert_timeout, - DELAYED_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 }, - { "delayed_insert_limit", (long*) &delayed_insert_limit, - DELAYED_LIMIT, 1, ~0L, 0, 1 }, - { "delayed_queue_size", (long*) &delayed_queue_size, - DELAYED_QUEUE_SIZE, 1, ~0L, 0, 1 }, - { "flush_time", (long*) &flush_time, - FLUSH_TIME, 0, LONG_TIMEOUT, 0, 1 }, - { "ft_min_word_len", (long*) &ft_min_word_len, - 4, 1, HA_FT_MAXLEN, 0, 1 }, - { "ft_max_word_len", (long*) &ft_max_word_len, - HA_FT_MAXLEN, 10, HA_FT_MAXLEN, 0, 1 }, - { "ft_max_word_len_for_sort",(long*) &ft_max_word_len_for_sort, - 20, 4, HA_FT_MAXLEN, 0, 1 }, + { "bdb_cache_size", OPT_BDB_CACHE_SIZE, + "The buffer that is allocated to cache index and rows for BDB tables.", + (gptr*) &berkeley_cache_size, (gptr*) &berkeley_cache_size, 0, GET_ULONG, + REQUIRED_ARG, KEY_CACHE_SIZE, 20*1024, (long) ~0, 0, IO_SIZE, 0}, + {"bdb_log_buffer_size", OPT_BDB_LOG_BUFFER_SIZE, + "The buffer that is allocated to cache index and rows for BDB tables.", + (gptr*) &berkeley_log_buffer_size, (gptr*) &berkeley_log_buffer_size, 0, + GET_ULONG, REQUIRED_ARG, 0, 256*1024L, ~0L, 0, 1024, 0}, + {"bdb_max_lock", OPT_BDB_MAX_LOCK, + "The maximum number of locks you can have active on a BDB table.", + (gptr*) &berkeley_max_lock, (gptr*) &berkeley_max_lock, 0, GET_ULONG, + REQUIRED_ARG, 10000, 0, (long) ~0, 0, 1, 0}, + /* QQ: The following should be removed soon! */ + {"bdb_lock_max", OPT_BDB_MAX_LOCK, "Synonym for bdb_max_lock", + (gptr*) &berkeley_max_lock, (gptr*) &berkeley_max_lock, 0, GET_ULONG, + REQUIRED_ARG, 10000, 0, (long) ~0, 0, 1, 0}, +#endif /* HAVE_BERKELEY_DB */ + {"binlog_cache_size", OPT_BINLOG_CACHE_SIZE, + "The size of the cache to hold the SQL statements for the binary log during a transaction. If you often use big, multi-statement transactions you can increase this to get more performance.", + (gptr*) &binlog_cache_size, (gptr*) &binlog_cache_size, 0, GET_ULONG, + REQUIRED_ARG, 32*1024L, IO_SIZE, ~0L, 0, IO_SIZE, 0}, + {"connect_timeout", OPT_CONNECT_TIMEOUT, + "The number of seconds the mysqld server is waiting for a connect packet before responding with Bad handshake", + (gptr*) &connect_timeout, (gptr*) &connect_timeout, 0, GET_ULONG, + REQUIRED_ARG, CONNECT_TIMEOUT, 2, LONG_TIMEOUT, 0, 1, 0 }, + {"delayed_insert_timeout", OPT_DELAYED_INSERT_TIMEOUT, + "How long a INSERT DELAYED thread should wait for INSERT statements before terminating.", + (gptr*) &delayed_insert_timeout, (gptr*) &delayed_insert_timeout, 0, + GET_ULONG, REQUIRED_ARG, DELAYED_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0}, + {"delayed_insert_limit", OPT_DELAYED_INSERT_LIMIT, + "After inserting delayed_insert_limit rows, the INSERT DELAYED handler will check if there are any SELECT statements pending. If so, it allows these to execute before continuing.", + (gptr*) &delayed_insert_limit, (gptr*) &delayed_insert_limit, 0, GET_ULONG, + REQUIRED_ARG, DELAYED_LIMIT, 1, ~0L, 0, 1, 0}, + { "delayed_queue_size", OPT_DELAYED_QUEUE_SIZE, + "What size queue (in rows) should be allocated for handling INSERT DELAYED. If the queue becomes full, any client that does INSERT DELAYED will wait until there is room in the queue again.", + (gptr*) &delayed_queue_size, (gptr*) &delayed_queue_size, 0, GET_ULONG, + REQUIRED_ARG, DELAYED_QUEUE_SIZE, 1, ~0L, 0, 1, 0}, + { "flush_time", OPT_FLUSH_TIME, + "A dedicated thread is created to flush all tables at the given interval.", + (gptr*) &flush_time, (gptr*) &flush_time, 0, GET_ULONG, REQUIRED_ARG, + FLUSH_TIME, 0, LONG_TIMEOUT, 0, 1, 0}, + { "ft_min_word_len", OPT_FT_MIN_WORD_LEN, + "The minimum length of the word to be included in a FULLTEXT index. Note: FULLTEXT indexes must be rebuilt after changing this variable.", + (gptr*) &ft_min_word_len, (gptr*) &ft_min_word_len, 0, GET_ULONG, + REQUIRED_ARG, 4, 1, HA_FT_MAXLEN, 0, 1, 0}, + { "ft_max_word_len", OPT_FT_MAX_WORD_LEN, + "The maximum length of the word to be included in a FULLTEXT index. Note: FULLTEXT indexes must be rebuilt after changing this variable.", + (gptr*) &ft_max_word_len, (gptr*) &ft_max_word_len, 0, GET_ULONG, + REQUIRED_ARG, HA_FT_MAXLEN, 10, HA_FT_MAXLEN, 0, 1, 0}, + { "ft_max_word_len_for_sort", OPT_FT_MAX_WORD_LEN_FOR_SORT, + "Undocumented", (gptr*) &ft_max_word_len_for_sort, + (gptr*) &ft_max_word_len_for_sort, 0, GET_ULONG, REQUIRED_ARG, 20, 4, + HA_FT_MAXLEN, 0, 1, 0}, #ifdef HAVE_INNOBASE_DB - {"innodb_mirrored_log_groups", - (long*) &innobase_mirrored_log_groups, 1, 1, 10, 0, 1}, - {"innodb_log_files_in_group", - (long*) &innobase_log_files_in_group, 2, 2, 100, 0, 1}, - {"innodb_log_file_size", - (long*) &innobase_log_file_size, 5*1024*1024L, 1*1024*1024L, - ~0L, 0, 1024*1024L}, - {"innodb_log_buffer_size", - (long*) &innobase_log_buffer_size, 1024*1024L, 256*1024L, - ~0L, 0, 1024}, - {"innodb_buffer_pool_size", - (long*) &innobase_buffer_pool_size, 8*1024*1024L, 1024*1024L, - ~0L, 0, 1024*1024L}, - {"innodb_additional_mem_pool_size", - (long*) &innobase_additional_mem_pool_size, 1*1024*1024L, 512*1024L, - ~0L, 0, 1024}, - {"innodb_file_io_threads", - (long*) &innobase_file_io_threads, 4, 4, 64, 0, 1}, - {"innodb_lock_wait_timeout", - (long*) &innobase_lock_wait_timeout, 50, 1, - 1024 * 1024 * 1024, 0, 1}, - {"innodb_thread_concurrency", - (long*) &innobase_thread_concurrency, 8, 1, 1000, 0, 1}, - {"innodb_force_recovery", - (long*) &innobase_force_recovery, 0, 0, 6, 0, 1}, -#endif - { "interactive_timeout", (long*) &net_interactive_timeout, - NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 }, - { "join_buffer_size", (long*) &join_buff_size, - 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE }, - { "key_buffer_size", (long*) &keybuff_size, - KEY_CACHE_SIZE, MALLOC_OVERHEAD, (long) ~0, MALLOC_OVERHEAD, IO_SIZE }, - { "long_query_time", (long*) &long_query_time, - 10, 1, LONG_TIMEOUT, 0, 1 }, - { "lower_case_table_names", (long*) &lower_case_table_names, - IF_WIN(1,0), 0, 1, 0, 1 }, - { "max_allowed_packet", (long*) &max_allowed_packet, - 1024*1024L, 80, 64*1024*1024L, MALLOC_OVERHEAD, 1024 }, - { "max_binlog_cache_size", (long*) &max_binlog_cache_size, - ~0L, IO_SIZE, ~0L, 0, IO_SIZE }, - { "max_binlog_size", (long*) &max_binlog_size, - 1024*1024L*1024L, 1024, 1024*1024L*1024L, 0, 1 }, - { "max_connections", (long*) &max_connections, - 100, 1, 16384, 0, 1 }, - { "max_connect_errors", (long*) &max_connect_errors, - MAX_CONNECT_ERRORS, 1, ~0L, 0, 1 }, - { "max_delayed_threads", (long*) &max_insert_delayed_threads, - 20, 1, 16384, 0, 1 }, - { "max_heap_table_size", (long*) &max_heap_table_size, - 16*1024*1024L, 16384, ~0L, MALLOC_OVERHEAD, 1024 }, - { "max_join_size", (long*) &max_join_size, - ~0L, 1, ~0L, 0, 1 }, - { "max_sort_length", (long*) &max_item_sort_length, - 1024, 4, 8192*1024L, 0, 1 }, - { "max_tmp_tables", (long*) &max_tmp_tables, - 32, 1, ~0L, 0, 1 }, - { "max_user_connections", (long*) &max_user_connections, - 0, 1, ~0L, 0, 1 }, - { "max_write_lock_count", (long*) &max_write_lock_count, - ~0L, 1, ~0L, 0, 1 }, - { "myisam_bulk_insert_tree_size", (long*) &myisam_bulk_insert_tree_size, - 8192*1024, 0, ~0L, 0, 1 }, - { "myisam_block_size", (long*) &opt_myisam_block_size, - MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH, MI_MAX_KEY_BLOCK_LENGTH, - 0, MI_MIN_KEY_BLOCK_LENGTH }, - { "myisam_max_extra_sort_file_size", - (long*) &myisam_max_extra_sort_file_size, - (long) (MI_MAX_TEMP_LENGTH/(1024L*1024L)), 0, ~0L, 0, 1 }, - { "myisam_max_sort_file_size", (long*) &myisam_max_sort_file_size, - (long) (LONG_MAX/(1024L*1024L)), 0, ~0L, 0, 1 }, - { "myisam_sort_buffer_size", (long*) &myisam_sort_buffer_size, - 8192*1024, 4, ~0L, 0, 1 }, - { "net_buffer_length", (long*) &net_buffer_length, - 16384, 1024, 1024*1024L, MALLOC_OVERHEAD, 1024 }, - { "net_retry_count", (long*) &mysqld_net_retry_count, - MYSQLD_NET_RETRY_COUNT, 1, ~0L, 0, 1 }, - { "net_read_timeout", (long*) &net_read_timeout, - NET_READ_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 }, - { "net_write_timeout", (long*) &net_write_timeout, - NET_WRITE_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 }, - { "open_files_limit", (long*) &open_files_limit, - 0, 0, 65535, 0, 1}, - { "query_buffer_size", (long*) &query_buff_size, - 0, MALLOC_OVERHEAD, (long) ~0, MALLOC_OVERHEAD, IO_SIZE }, + {"innodb_mirrored_log_groups", OPT_INNODB_MIRRORED_LOG_GROUPS, + "Number of identical copies of log groups we keep for the database. Currently this should be set to 1.", + (gptr*) &innobase_mirrored_log_groups, + (gptr*) &innobase_mirrored_log_groups, 0, GET_LONG, REQUIRED_ARG, 1, 1, 10, + 0, 1, 0}, + {"innodb_log_files_in_group", OPT_INNODB_LOG_FILES_IN_GROUP, + "Number of log files in the log group. InnoDB writes to the files in a circular fashion. Value 3 is recommended here.", + (gptr*) &innobase_log_files_in_group, (gptr*) &innobase_log_files_in_group, + 0, GET_LONG, REQUIRED_ARG, 2, 2, 100, 0, 1, 0}, + {"innodb_log_file_size", OPT_INNODB_LOG_FILE_SIZE, + "Size of each log file in a log group in megabytes.", + (gptr*) &innobase_log_file_size, (gptr*) &innobase_log_file_size, 0, + GET_LONG, REQUIRED_ARG, 5*1024*1024L, 1*1024*1024L, ~0L, 0, 1024*1024L, 0}, + {"innodb_log_buffer_size", OPT_INNODB_LOG_BUFFER_SIZE, + "The size of the buffer which InnoDB uses to write log to the log files on disk.", + (gptr*) &innobase_log_buffer_size, (gptr*) &innobase_log_buffer_size, 0, + GET_LONG, REQUIRED_ARG, 1024*1024L, 256*1024L, ~0L, 0, 1024, 0}, + {"innodb_buffer_pool_size", OPT_INNODB_BUFFER_POOL_SIZE, + "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.", + (gptr*) &innobase_buffer_pool_size, (gptr*) &innobase_buffer_pool_size, 0, + GET_LONG, REQUIRED_ARG, 8*1024*1024L, 1024*1024L, ~0L, 0, 1024*1024L, 0}, + {"innodb_additional_mem_pool_size", OPT_INNODB_ADDITIONAL_MEM_POOL_SIZE, + "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.", + (gptr*) &innobase_additional_mem_pool_size, + (gptr*) &innobase_additional_mem_pool_size, 0, GET_LONG, REQUIRED_ARG, + 1*1024*1024L, 512*1024L, ~0L, 0, 1024, 0}, + {"innodb_file_io_threads", OPT_INNODB_FILE_IO_THREADS, + "Number of file I/O threads in InnoDB.", (gptr*) &innobase_file_io_threads, + (gptr*) &innobase_file_io_threads, 0, GET_LONG, REQUIRED_ARG, 4, 4, 64, 0, + 1, 0}, + {"innodb_lock_wait_timeout", OPT_INNODB_LOCK_WAIT_TIMEOUT, + "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back.", + (gptr*) &innobase_lock_wait_timeout, (gptr*) &innobase_lock_wait_timeout, + 0, GET_LONG, REQUIRED_ARG, 50, 1, 1024 * 1024 * 1024, 0, 1, 0}, + {"innodb_thread_concurrency", OPT_INNODB_THREAD_CONCURRENCY, + "Helps in performance tuning in heavily concurrent environments.", + (gptr*) &innobase_thread_concurrency, (gptr*) &innobase_thread_concurrency, + 0, GET_LONG, REQUIRED_ARG, 8, 1, 1000, 0, 1, 0}, + {"innodb_force_recovery", OPT_INNODB_FORCE_RECOVERY, + "Helps to save your data in case the disk image of the database becomes corrupt.", + (gptr*) &innobase_force_recovery, (gptr*) &innobase_force_recovery, 0, + GET_LONG, REQUIRED_ARG, 0, 0, 6, 0, 1, 0}, +#endif /* HAVE_INNOBASE_DB */ + {"interactive_timeout", OPT_INTERACTIVE_TIMEOUT, + "The number of seconds the server waits for activity on an interactive connection before closing it.", + (gptr*) &net_interactive_timeout, (gptr*) &net_interactive_timeout, 0, + GET_ULONG, REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0}, + {"join_buffer_size", OPT_JOIN_BUFF_SIZE, + "The size of the buffer that is used for full joins.", + (gptr*) &join_buff_size, (gptr*) &join_buff_size, 0, GET_ULONG, + REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, + IO_SIZE, 0}, + {"key_buffer_size", OPT_KEY_BUFFER_SIZE, + "The size of the buffer used for index blocks. Increase this to get better index handling (for all reads and multiple writes) to as much as you can afford; 64M on a 256M machine that mainly runs MySQL is quite common.", + (gptr*) &keybuff_size, (gptr*) &keybuff_size, 0, GET_ULONG, REQUIRED_ARG, + KEY_CACHE_SIZE, MALLOC_OVERHEAD, (long) ~0, MALLOC_OVERHEAD, IO_SIZE, 0}, + {"long_query_time", OPT_LONG_QUERY_TIME, + "Log all queries that have taken more than long_query_time seconds to execute to file.", + (gptr*) &long_query_time, (gptr*) &long_query_time, 0, GET_ULONG, + REQUIRED_ARG, 10, 1, LONG_TIMEOUT, 0, 1, 0}, + {"lower_case_table_names", OPT_LOWER_CASE_TABLE_NAMES, + "If set to 1 table names are stored in lowercase on disk and table names will be case-insensitive.", + (gptr*) &lower_case_table_names, (gptr*) &lower_case_table_names, 0, + GET_ULONG, REQUIRED_ARG, IF_WIN(1,0), 0, 1, 0, 1, 0}, + {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, + "Max packetlength to send/receive from to server.", + (gptr*) &max_allowed_packet, (gptr*) &max_allowed_packet, 0, GET_ULONG, + REQUIRED_ARG, 1024*1024L, 80, 64*1024*1024L, MALLOC_OVERHEAD, 1024, 0}, + {"max_binlog_cache_size", OPT_MAX_BINLOG_CACHE_SIZE, + "Can be used to restrict the total size used to cache a multi-transaction query.", + (gptr*) &max_binlog_cache_size, (gptr*) &max_binlog_cache_size, 0, + GET_ULONG, REQUIRED_ARG, ~0L, IO_SIZE, ~0L, 0, IO_SIZE, 0}, + {"max_binlog_size", OPT_MAX_BINLOG_SIZE, + "Binary log will be rotated automatically when the size crosses the limit.", + (gptr*) &max_binlog_size, (gptr*) &max_binlog_size, 0, GET_ULONG, + REQUIRED_ARG, 1024*1024L*1024L, 1024, 1024*1024L*1024L, 0, 1, 0}, + {"max_connections", OPT_MAX_CONNECTIONS, + "The number of simultaneous clients allowed.", (gptr*) &max_connections, + (gptr*) &max_connections, 0, GET_ULONG, REQUIRED_ARG, 100, 1, 16384, 0, 1, + 0}, + {"max_connect_errors", OPT_MAX_CONNECT_ERRORS, + "If there is more than this number of interrupted connections from a host this host will be blocked from further connections.", + (gptr*) &max_connect_errors, (gptr*) &max_connect_errors, 0, GET_ULONG, + REQUIRED_ARG, MAX_CONNECT_ERRORS, 1, ~0L, 0, 1, 0}, + {"max_delayed_threads", OPT_MAX_DELAYED_THREADS, + "Don't start more than this number of threads to handle INSERT DELAYED statements.", + (gptr*) &max_insert_delayed_threads, (gptr*) &max_insert_delayed_threads, + 0, GET_ULONG, REQUIRED_ARG, 20, 1, 16384, 0, 1, 0}, + {"max_heap_table_size", OPT_MAX_HEP_TABLE_SIZE, + "Don't allow creation of heap tables bigger than this.", + (gptr*) &max_heap_table_size, (gptr*) &max_heap_table_size, 0, GET_ULONG, + REQUIRED_ARG, 16*1024*1024L, 16384, ~0L, MALLOC_OVERHEAD, 1024, 0}, + {"max_join_size", OPT_MAX_JOIN_SIZE, + "Joins that are probably going to read more than max_join_size records return an error.", + (gptr*) &max_join_size, (gptr*) &max_join_size, 0, GET_ULONG, REQUIRED_ARG, + ~0L, 1, ~0L, 0, 1, 0}, + {"max_sort_length", OPT_MAX_SORT_LENGTH, + "The number of bytes to use when sorting BLOB or TEXT values (only the first max_sort_length bytes of each value are used; the rest are ignored).", + (gptr*) &max_item_sort_length, (gptr*) &max_item_sort_length, 0, GET_ULONG, + REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0}, + {"max_tmp_tables", OPT_MAX_TMP_TABLES, + "Maximum number of temporary tables a client can keep open at a time.", + (gptr*) &max_tmp_tables, (gptr*) &max_tmp_tables, 0, GET_ULONG, + REQUIRED_ARG, 32, 1, ~0L, 0, 1, 0}, + {"max_user_connections", OPT_MAX_USER_CONNECTIONS, + "The maximum number of active connections for a single user (0 = no limit).", + (gptr*) &max_user_connections, (gptr*) &max_user_connections, 0, GET_ULONG, + REQUIRED_ARG, 0, 1, ~0L, 0, 1, 0}, + {"max_write_lock_count", OPT_MAX_WRITE_LOCK_COUNT, + "After this many write locks, allow some read locks to run in between.", + (gptr*) &max_write_lock_count, (gptr*) &max_write_lock_count, 0, GET_ULONG, + REQUIRED_ARG, ~0L, 1, ~0L, 0, 1, 0}, + {"myisam_bulk_insert_tree_size", OPT_MYISAM_BULK_INSERT_TREE_SIZE, + "Size of tree cache used in bulk insert optimisation. Note that this is a limit per thread!", + (gptr*) &myisam_bulk_insert_tree_size, + (gptr*) &myisam_bulk_insert_tree_size, 0, GET_ULONG, REQUIRED_ARG, + 8192*1024, 0, ~0L, 0, 1, 0}, + {"myisam_block_size", OPT_MYISAM_BLOCK_SIZE, + "Undocumented", (gptr*) &opt_myisam_block_size, + (gptr*) &opt_myisam_block_size, 0, GET_ULONG, REQUIRED_ARG, + MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH, MI_MAX_KEY_BLOCK_LENGTH, + 0, MI_MIN_KEY_BLOCK_LENGTH, 0}, + {"myisam_max_extra_sort_file_size", OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE, + "Used to help MySQL to decide when to use the slow but safe key cache index create method. Note that this parameter is given in megabytes!", + (gptr*) &myisam_max_extra_sort_file_size, + (gptr*) &myisam_max_extra_sort_file_size, 0, GET_ULONG, REQUIRED_ARG, + (long) (MI_MAX_TEMP_LENGTH/(1024L*1024L)), 0, ~0L, 0, 1, 0}, + {"myisam_max_sort_file_size", OPT_MYISAM_MAX_SORT_FILE_SIZE, + "Don't use the fast sort index method to created index if the temporary file would get bigger than this. Note that this paramter is given in megabytes!", + (gptr*) &myisam_max_sort_file_size, (gptr*) &myisam_max_sort_file_size, 0, + GET_ULONG, REQUIRED_ARG, (long) (LONG_MAX/(1024L*1024L)), 0, ~0L, 0, 1, 0}, + {"myisam_sort_buffer_size", OPT_MYISAM_SORT_BUFFER_SIZE, + "The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE.", + (gptr*) &myisam_sort_buffer_size, (gptr*) &myisam_sort_buffer_size, 0, + GET_ULONG, REQUIRED_ARG, 8192*1024, 4, ~0L, 0, 1, 0}, + {"net_buffer_length", OPT_NET_BUFFER_LENGTH, + "Buffer for TCP/IP and socket communication.", (gptr*) &net_buffer_length, + (gptr*) &net_buffer_length, 0, GET_ULONG, REQUIRED_ARG, 16384, 1024, + 1024*1024L, MALLOC_OVERHEAD, 1024, 0}, + {"net_retry_count", OPT_NET_RETRY_COUNT, + "If a read on a communication port is interrupted, retry this many times before giving up.", + (gptr*) &mysqld_net_retry_count, (gptr*) &mysqld_net_retry_count, 0, + GET_ULONG, REQUIRED_ARG, MYSQLD_NET_RETRY_COUNT, 1, ~0L, 0, 1, 0}, + {"net_read_timeout", OPT_NET_READ_TIMEOUT, + "Number of seconds to wait for more data from a connection before aborting the read.", + (gptr*) &net_read_timeout, (gptr*) &net_read_timeout, 0, GET_ULONG, + REQUIRED_ARG, NET_READ_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0}, + {"net_write_timeout", OPT_NET_WRITE_TIMEOUT, + "Number of seconds to wait for a block to be written to a connection before aborting the write.", + (gptr*) &net_write_timeout, (gptr*) &net_write_timeout, 0, GET_ULONG, + REQUIRED_ARG, NET_WRITE_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0}, + {"open_files_limit", OPT_OPEN_FILES_LIMIT, + "If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of files.", + (gptr*) &open_files_limit, (gptr*) &open_files_limit, 0, GET_ULONG, + REQUIRED_ARG, 0, 0, 65535, 0, 1, 0}, + {"query_buffer_size", OPT_QUERY_BUFFER_SIZE, + "The initial allocation of the query buffer.", (gptr*) &query_buff_size, + (gptr*) &query_buff_size, 0, GET_ULONG, REQUIRED_ARG, 0, MALLOC_OVERHEAD, + (long) ~0, MALLOC_OVERHEAD, IO_SIZE, 0}, #ifdef HAVE_QUERY_CACHE - { "query_cache_limit", (long*) &query_cache_limit, - 1024*1024L, 0, ULONG_MAX, 0, 1}, - { "query_cache_size", (long*) &query_cache_size, - 0, 0, ULONG_MAX, 0, 1}, - { "query_cache_startup_type",(long*) &query_cache_startup_type, - 1, 0, 2, 0, 1}, + {"query_cache_limit", OPT_QUERY_CACHE_LIMIT, + "Don't cache results that are bigger than this.", + (gptr*) &query_cache_limit, (gptr*) &query_cache_limit, 0, GET_ULONG, + REQUIRED_ARG, 1024*1024L, 0, ULONG_MAX, 0, 1, 0}, #endif /*HAVE_QUERY_CACHE*/ - { "record_buffer", (long*) &my_default_record_cache_size, - 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE }, - { "record_rnd_buffer", (long*) &record_rnd_cache_size, - 0, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE }, - { "relay_log_space_limit", (long*) &relay_log_space_limit, 0L, 0L,ULONG_MAX, - 0, 1}, - { "slave_net_timeout", (long*) &slave_net_timeout, - SLAVE_NET_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 }, - { "slow_launch_time", (long*) &slow_launch_time, - 2L, 0L, LONG_TIMEOUT, 0, 1 }, - { "sort_buffer", (long*) &sortbuff_size, - MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*2, ~0L, MALLOC_OVERHEAD, 1 }, - { "table_cache", (long*) &table_cache_size, - 64, 1, 16384, 0, 1 }, - { "thread_concurrency", (long*) &concurrency, - DEFAULT_CONCURRENCY, 1, 512, 0, 1 }, - { "thread_cache_size", (long*) &thread_cache_size, - 0, 0, 16384, 0, 1 }, - { "tmp_table_size", (long*) &tmp_table_size, - 32*1024*1024L, 1024, ~0L, 0, 1 }, - { "thread_stack", (long*) &thread_stack, - DEFAULT_THREAD_STACK, 1024*32, ~0L, 0, 1024 }, - { "wait_timeout", (long*) &net_wait_timeout, - NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1 }, - { NullS, (long*) 0, 0, 0, 0, 0, 0} + {"query_cache_size", OPT_QUERY_CACHE_SIZE, + "The memory allocated to store results from old queries.", + (gptr*) &query_cache_size, (gptr*) &query_cache_size, 0, GET_ULONG, + REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1, 0}, +#ifdef HAVE_QUERY_CACHE + {"query_cache_startup_type", OPT_QUERY_CACHE_STARTUP_TYPE, + "0 = OFF = Don't cache or retrieve results. 1 = ON = Cache all results except SELECT SQL_NO_CACHE ... queries. 2 = DEMAND = Cache only SELECT SQL_CACHE ... queries.", + (gptr*) &query_cache_startup_type, (gptr*) &query_cache_startup_type, 0, + GET_ULONG, REQUIRED_ARG, 1, 0, 2, 0, 1, 0}, +#endif /*HAVE_QUERY_CACHE*/ + {"record_buffer", OPT_RECORD_BUFFER, + "Each thread that does a sequential scan allocates a buffer of this size for each table it scans. If you do many sequential scans, you may want to increase this value.", + (gptr*) &my_default_record_cache_size, + (gptr*) &my_default_record_cache_size, 0, GET_ULONG, REQUIRED_ARG, + 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE, 0}, + {"record_rnd_buffer", OPT_RECORD_RND_BUFFER, + "When reading rows in sorted order after a sort, the rows are read through this buffer to avoid a disk seeks. If not set, then it's set to the value of record_buffer.", + (gptr*) &record_rnd_cache_size, (gptr*) &record_rnd_cache_size, 0, + GET_ULONG, REQUIRED_ARG, 0, IO_SIZE*2+MALLOC_OVERHEAD, + ~0L, MALLOC_OVERHEAD, IO_SIZE, 0}, + {"relay_log_space_limit", OPT_RELAY_LOG_SPACE_LIMIT, + "Undocumented", (gptr*) &relay_log_space_limit, + (gptr*) &relay_log_space_limit, 0, GET_ULONG, REQUIRED_ARG, 0L, 0L, + ULONG_MAX, 0, 1, 0}, + {"slave_net_timeout", OPT_SLAVE_NET_TIMEOUT, + "Number of seconds to wait for more data from a master/slave connection before aborting the read.", + (gptr*) &slave_net_timeout, (gptr*) &slave_net_timeout, 0, + GET_ULONG, REQUIRED_ARG, SLAVE_NET_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0}, + {"slow_launch_time", OPT_SLOW_LAUNCH_TIME, + "If creating the thread takes longer than this value (in seconds), the Slow_launch_threads counter will be incremented.", + (gptr*) &slow_launch_time, (gptr*) &slow_launch_time, 0, GET_ULONG, + REQUIRED_ARG, 2L, 0L, LONG_TIMEOUT, 0, 1, 0}, + {"sort_buffer", OPT_SORT_BUFFER, + "Each thread that needs to do a sort allocates a buffer of this size.", + (gptr*) &sortbuff_size, (gptr*) &sortbuff_size, 0, GET_ULONG, REQUIRED_ARG, + MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*2, ~0L, MALLOC_OVERHEAD, + 1, 0}, + {"table_cache", OPT_TABLE_CACHE, + "The number of open tables for all threads.", (gptr*) &table_cache_size, + (gptr*) &table_cache_size, 0, GET_ULONG, REQUIRED_ARG, 64, 1, 16384, 0, 1, + 0}, + {"thread_concurrency", OPT_THREAD_CONCURRENCY, + "Permits the application to give the threads system a hint for the desired number of threads that should be run at the same time.", + (gptr*) &concurrency, (gptr*) &concurrency, 0, GET_ULONG, REQUIRED_ARG, + DEFAULT_CONCURRENCY, 1, 512, 0, 1, 0}, + {"thread_cache_size", OPT_THREAD_CACHE_SIZE, + "How many threads we should keep in a cache for reuse.", + (gptr*) &thread_cache_size, (gptr*) &thread_cache_size, 0, GET_ULONG, + REQUIRED_ARG, 0, 0, 16384, 0, 1, 0}, + {"tmp_table_size", OPT_TMP_TABLE_SIZE, + "If an in-memory temporary table exceeds this size, MySQL will automatically convert it to an on-disk MyISAM table.", + (gptr*) &tmp_table_size, (gptr*) &tmp_table_size, 0, GET_ULONG, + REQUIRED_ARG, 32*1024*1024L, 1024, ~0L, 0, 1, 0}, + {"thread_stack", OPT_THREAD_STACK, + "The stack size for each thread.", (gptr*) &thread_stack, + (gptr*) &thread_stack, 0, GET_ULONG, REQUIRED_ARG,DEFAULT_THREAD_STACK, + 1024*32, ~0L, 0, 1024, 0}, + {"wait_timeout", OPT_WAIT_TIMEOUT, + "The number of seconds the server waits for activity on a connection before closing it", + (gptr*) &net_wait_timeout, (gptr*) &net_wait_timeout, 0, GET_ULONG, + REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0}, + {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; - struct show_var_st init_vars[]= { {"back_log", (char*) &back_log, SHOW_LONG}, {"basedir", mysql_home, SHOW_CHAR}, @@ -3276,12 +3733,12 @@ struct show_var_st status_vars[]= { {"Com_show_grants", (char*) (com_stat+(uint) SQLCOM_SHOW_GRANTS),SHOW_LONG}, {"Com_show_keys", (char*) (com_stat+(uint) SQLCOM_SHOW_KEYS),SHOW_LONG}, {"Com_show_logs", (char*) (com_stat+(uint) SQLCOM_SHOW_LOGS),SHOW_LONG}, - {"Com_show_master_stat", (char*) (com_stat+(uint) SQLCOM_SHOW_MASTER_STAT),SHOW_LONG}, + {"Com_show_master_status", (char*) (com_stat+(uint) SQLCOM_SHOW_MASTER_STAT),SHOW_LONG}, {"Com_show_new_master", (char*) (com_stat+(uint) SQLCOM_SHOW_NEW_MASTER),SHOW_LONG}, {"Com_show_open_tables", (char*) (com_stat+(uint) SQLCOM_SHOW_OPEN_TABLES),SHOW_LONG}, {"Com_show_processlist", (char*) (com_stat+(uint) SQLCOM_SHOW_PROCESSLIST),SHOW_LONG}, {"Com_show_slave_hosts", (char*) (com_stat+(uint) SQLCOM_SHOW_SLAVE_HOSTS),SHOW_LONG}, - {"Com_show_slave_stat", (char*) (com_stat+(uint) SQLCOM_SHOW_SLAVE_STAT),SHOW_LONG}, + {"Com_show_slave_status", (char*) (com_stat+(uint) SQLCOM_SHOW_SLAVE_STAT),SHOW_LONG}, {"Com_show_status", (char*) (com_stat+(uint) SQLCOM_SHOW_STATUS),SHOW_LONG}, {"Com_show_tables", (char*) (com_stat+(uint) SQLCOM_SHOW_TABLES),SHOW_LONG}, {"Com_show_variables", (char*) (com_stat+(uint) SQLCOM_SHOW_VARIABLES),SHOW_LONG}, @@ -3349,29 +3806,29 @@ struct show_var_st status_vars[]= { {"Sort_rows", (char*) &filesort_rows, SHOW_LONG}, {"Sort_scan", (char*) &filesort_scan_count, SHOW_LONG}, #ifdef HAVE_OPENSSL - {"ssl_accepts", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT}, - {"ssl_finished_accepts", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_GOOD}, - {"ssl_finished_connects", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT_GOOD}, - {"ssl_accept_renegotiates", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE}, - {"ssl_connect_renegotiates", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT_RENEGOTIATE}, - {"ssl_callback_cache_hits", (char*) 0, SHOW_SSL_CTX_SESS_CB_HITS}, - {"ssl_session_cache_hits", (char*) 0, SHOW_SSL_CTX_SESS_HITS}, - {"ssl_session_cache_misses", (char*) 0, SHOW_SSL_CTX_SESS_MISSES}, - {"ssl_session_cache_timeouts", (char*) 0, SHOW_SSL_CTX_SESS_TIMEOUTS}, - {"ssl_used_session_cache_entries",(char*) 0, SHOW_SSL_CTX_SESS_NUMBER}, - {"ssl_client_connects", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT}, - {"ssl_session_cache_overflows", (char*) 0, SHOW_SSL_CTX_SESS_CACHE_FULL}, - {"ssl_session_cache_size", (char*) 0, SHOW_SSL_CTX_SESS_GET_CACHE_SIZE}, - {"ssl_session_cache_mode", (char*) 0, SHOW_SSL_CTX_GET_SESSION_CACHE_MODE}, - {"ssl_sessions_reused", (char*) 0, SHOW_SSL_SESSION_REUSED}, - {"ssl_ctx_verify_mode", (char*) 0, SHOW_SSL_CTX_GET_VERIFY_MODE}, - {"ssl_ctx_verify_depth", (char*) 0, SHOW_SSL_CTX_GET_VERIFY_DEPTH}, - {"ssl_verify_mode", (char*) 0, SHOW_SSL_GET_VERIFY_MODE}, - {"ssl_verify_depth", (char*) 0, SHOW_SSL_GET_VERIFY_DEPTH}, - {"ssl_version", (char*) 0, SHOW_SSL_GET_VERSION}, - {"ssl_cipher", (char*) 0, SHOW_SSL_GET_CIPHER}, - {"ssl_cipher_list", (char*) 0, SHOW_SSL_GET_CIPHER_LIST}, - {"ssl_default_timeout", (char*) 0, SHOW_SSL_GET_DEFAULT_TIMEOUT}, + {"Ssl_accepts", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT}, + {"Ssl_finished_accepts", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_GOOD}, + {"Ssl_finished_connects", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT_GOOD}, + {"Ssl_accept_renegotiates", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE}, + {"Ssl_connect_renegotiates", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT_RENEGOTIATE}, + {"Ssl_callback_cache_hits", (char*) 0, SHOW_SSL_CTX_SESS_CB_HITS}, + {"Ssl_session_cache_hits", (char*) 0, SHOW_SSL_CTX_SESS_HITS}, + {"Ssl_session_cache_misses", (char*) 0, SHOW_SSL_CTX_SESS_MISSES}, + {"Ssl_session_cache_timeouts", (char*) 0, SHOW_SSL_CTX_SESS_TIMEOUTS}, + {"Ssl_used_session_cache_entries",(char*) 0, SHOW_SSL_CTX_SESS_NUMBER}, + {"Ssl_client_connects", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT}, + {"Ssl_session_cache_overflows", (char*) 0, SHOW_SSL_CTX_SESS_CACHE_FULL}, + {"Ssl_session_cache_size", (char*) 0, SHOW_SSL_CTX_SESS_GET_CACHE_SIZE}, + {"Ssl_session_cache_mode", (char*) 0, SHOW_SSL_CTX_GET_SESSION_CACHE_MODE}, + {"Ssl_sessions_reused", (char*) 0, SHOW_SSL_SESSION_REUSED}, + {"Ssl_ctx_verify_mode", (char*) 0, SHOW_SSL_CTX_GET_VERIFY_MODE}, + {"Ssl_ctx_verify_depth", (char*) 0, SHOW_SSL_CTX_GET_VERIFY_DEPTH}, + {"Ssl_verify_mode", (char*) 0, SHOW_SSL_GET_VERIFY_MODE}, + {"Ssl_verify_depth", (char*) 0, SHOW_SSL_GET_VERIFY_DEPTH}, + {"Ssl_version", (char*) 0, SHOW_SSL_GET_VERSION}, + {"Ssl_cipher", (char*) 0, SHOW_SSL_GET_CIPHER}, + {"Ssl_cipher_list", (char*) 0, SHOW_SSL_GET_CIPHER_LIST}, + {"Ssl_default_timeout", (char*) 0, SHOW_SSL_GET_DEFAULT_TIMEOUT}, #endif /* HAVE_OPENSSL */ {"Table_locks_immediate", (char*) &locks_immediate, SHOW_LONG}, {"Table_locks_waited", (char*) &locks_waited, SHOW_LONG}, @@ -3405,167 +3862,28 @@ and you are welcome to modify and redistribute it under the GPL license\n\ Starts the MySQL server\n"); printf("Usage: %s [OPTIONS]\n", my_progname); - puts("\n\ - --ansi Use ANSI SQL syntax instead of MySQL syntax\n\ - -b, --basedir=path Path to installation directory. All paths are\n\ - usually resolved relative to this\n\ - --big-tables Allow big result sets by saving all temporary sets\n\ - on file (Solves most 'table full' errors)\n\ - --bind-address=IP Ip address to bind to\n\ - --bootstrap Used by mysql installation scripts\n\ - --character-sets-dir=...\n\ - Directory where character sets are\n\ - --chroot=path Chroot mysqld daemon during startup\n\ - --core-file Write core on errors\n\ - -h, --datadir=path Path to the database root"); -#ifndef DBUG_OFF - printf("\ - -#, --debug[=...] Debug log. Default is '%s'\n",default_dbug_option); -#ifdef SAFEMALLOC - puts("\ - --skip-safemalloc Don't use the memory allocation checking"); -#endif -#endif - puts("\ - --default-character-set=charset\n\ - Set the default character set\n\ - --default-table-type=type\n\ - Set the default table type for tables\n\ - --delay-key-write-for-all-tables\n\ - Don't flush key buffers between writes for any MyISAM\n\ - table\n"); -#ifdef HAVE_OPENSSL - puts("\ - --des-key-file Load keys for des_encrypt() and des_encrypt\n\ - from given file"); -#endif /* HAVE_OPENSSL */ - puts("\ - --enable-locking Enable system locking\n\ - --enable-pstack Print a symbolic stack trace on failure\n\ - -T, --exit-info Used for debugging; Use at your own risk!\n\ - --flush Flush tables to disk between SQL commands\n\ - -?, --help Display this help and exit\n\ - --init-file=file Read SQL commands from this file at startup\n\ - -L, --language=... Client error messages in given language. May be\n\ - given as a full path\n\ - --local-infile=[1|0] Enable/disable LOAD DATA LOCAL INFILE\n\ - -l, --log[=file] Log connections and queries to file\n\ - --log-bin[=file] Log queries in new binary format (for replication)\n\ - --log-bin-index=file File that holds the names for last binary log files\n\ - --log-update[=file] Log updates to file.# where # is a unique number\n\ - if not given.\n\ - --log-isam[=file] Log all MyISAM changes to file\n\ - --log-long-format Log some extra information to update log\n\ - --low-priority-updates INSERT/DELETE/UPDATE has lower priority than selects\n\ - --log-slow-queries=[file]\n\ - Log slow queries to this log file. Defaults logging\n\ - to hostname-slow.log\n\ - --pid-file=path Pid file used by safe_mysqld\n\ - --myisam-recover[=option[,option...]] where options is one of DEAULT,\n\ - BACKUP or FORCE.\n\ - --memlock Lock mysqld in memory\n\ - -n, --new Use very new possible 'unsafe' functions\n\ - -o, --old-protocol Use the old (3.20) protocol\n\ - -P, --port=... Port number to use for connection\n"); -#ifdef ONE_THREAD - puts("\ - --one-thread Only use one thread (for debugging under Linux)\n"); -#endif - puts("\ - -O, --set-variable var=option\n\ - Give a variable an value. --help lists variables\n\ - --safe-mode Skip some optimize stages (for testing)\n\ - --safe-show-database Don't show databases for which the user has no\n\ - privileges\n\ - --safe-user-create Don't allow new user creation by the user who has\n\ - no write privileges to the mysql.user table\n\ - --skip-concurrent-insert\n\ - Don't use concurrent insert with MyISAM\n\ - --skip-delay-key-write\n\ - Ignore the delay_key_write option for all tables\n\ - --skip-grant-tables Start without grant tables. This gives all users\n\ - FULL ACCESS to all tables!\n\ - --skip-host-cache Don't cache host names\n\ - --skip-locking Don't use system locking. To use isamchk one has\n\ - to shut down the server.\n\ - --skip-name-resolve Don't resolve hostnames.\n\ - All hostnames are IP's or 'localhost'\n\ - --skip-networking Don't allow connection with TCP/IP.\n\ - --skip-new Don't use new, possible wrong routines.\n"); - /* We have to break the string here because of VC++ limits */ - puts("\ - --skip-stack-trace Don't print a stack trace on failure\n\ - --skip-symlink Don't allow symlinking of tables\n\ - --skip-show-database Don't allow 'SHOW DATABASE' commands\n\ - --skip-thread-priority\n\ - Don't give threads different priorities.\n\ - --socket=... Socket file to use for connection\n\ - -t, --tmpdir=path Path for temporary files\n\ - --sql-mode=option[,option[,option...]] where option can be one of:\n\ - REAL_AS_FLOAT, PIPES_AS_CONCAT, ANSI_QUOTES,\n\ - IGNORE_SPACE, SERIALIZE, ONLY_FULL_GROUP_BY,\n\ - NO_UNSIGNED_SUBTRACTION.\n\ - --transaction-isolation\n\ - Default transaction isolation level\n\ - --temp-pool Use a pool of temporary files\n\ - -u, --user=user_name Run mysqld daemon as user\n\ - -V, --version output version information and exit\n\ - -W, --warnings Log some not critical warnings to the log file\n"); #ifdef __WIN__ puts("NT and Win32 specific options:\n\ --console Don't remove the console window\n\ --install Install the default service (NT)\n\ --install-manual Install the default service started manually (NT)\n\ + --install service_name Install an optional service (NT)\n\ + --install-manual service_name Install an optional service started manually (NT)\n\ --remove Remove the default service from the service list (NT)\n\ - --enable-named-pipe Enable the named pipe (NT)\n\ - --standalone Dummy option to start as a standalone program (NT)\ + --remove service_name Remove the service_name from the service list (NT)\n\ + --enable-named-pipe Only to be used for the default server (NT)\n\ + --standalone Dummy option to start as a standalone server (NT)\ "); -#ifdef USE_SYMDIR - puts("--use-symbolic-links Enable symbolic link support"); -#endif puts(""); #endif -#ifdef HAVE_BERKELEY_DB - puts("\ - --bdb-home= directory Berkeley home direcory\n\ - --bdb-lock-detect=# Berkeley lock detect\n\ - (DEFAULT, OLDEST, RANDOM or YOUNGEST, # sec)\n\ - --bdb-logdir=directory Berkeley DB log file directory\n\ - --bdb-no-sync Don't synchronously flush logs\n\ - --bdb-no-recover Don't try to recover Berkeley DB tables on start\n\ - --bdb-shared-data Start Berkeley DB in multi-process mode\n\ - --bdb-tmpdir=directory Berkeley DB tempfile name\n\ - --skip-bdb Don't use berkeley db (will save memory)\n\ -"); -#endif /* HAVE_BERKELEY_DB */ -#ifdef HAVE_INNOBASE_DB - puts("\ - --innodb_data_home_dir=dir The common part for Innodb table spaces\n\ - --innodb_data_file_path=dir Path to individual files and their sizes\n\ - --innodb_flush_method=# With which method to flush data\n\ - --innodb_flush_log_at_trx_commit[=#]\n\ - Set to 0 if you don't want to flush logs\n\ - --innodb_log_arch_dir=dir Where full logs should be archived\n\ - --innodb_log_archive[=#] Set to 1 if you want to have logs archived\n\ - --innodb_log_group_home_dir=dir Path to innodb log files.\n\ - --skip-innodb Don't use Innodb (will save memory)\n\ -"); -#endif /* HAVE_INNOBASE_DB */ print_defaults("my",load_default_groups); puts(""); - -#ifdef HAVE_OPENSSL - puts("\ - --ssl Use SSL for connection (automatically set with other flags\n\ - --ssl-key X509 key in PEM format (implies --ssl)\n\ - --ssl-cert X509 cert in PEM format (implies --ssl)\n\ - --ssl-ca CA file in PEM format (check OpenSSL docs, implies --ssl)\n\ - --ssl-capath CA directory (check OpenSSL docs, implies --ssl)\n\ - --ssl-cipher SSL cipher to use (implies --ssl)"); -#endif - fix_paths(); set_ports(); + + my_print_help(my_long_options); + my_print_variables(my_long_options); + printf("\ To see what values a running MySQL server is using, type\n\ 'mysqladmin variables' instead of 'mysqld --help'.\n\ @@ -3598,17 +3916,11 @@ The default values (after parsing the command line arguments) are:\n\n"); puts("\nsystem locking is not in use"); if (opt_noacl) puts("\nGrant tables are not used. All users have full access rights"); - printf("\nPossible variables for option --set-variable (-O) are:\n"); - for (uint i=0 ; changeable_vars[i].name ; i++) - printf("%-20s current value: %lu\n", - changeable_vars[i].name, - (ulong) *changeable_vars[i].varptr); } static void set_options(void) { - set_all_changeable_vars( changeable_vars ); #if !defined( my_pthread_setprio ) && !defined( HAVE_PTHREAD_SETSCHEDPARAM ) opt_specialflag |= SPECIAL_NO_PRIOR; #endif @@ -3638,628 +3950,444 @@ static void set_options(void) my_bind_addr = htonl( INADDR_ANY ); } - /* Initiates DEBUG - but no debugging here ! */ -static void get_options(int argc,char **argv) +static my_bool +get_one_option(int optid, const struct my_option *opt __attribute__((unused)), + char *argument) { - int c,option_index=0; - - myisam_delay_key_write=1; // Allow use of this -#ifndef HAVE_purify - my_use_symdir=1; // Use internal symbolic links -#else - /* Symlinks gives too many warnings with purify */ - my_disable_symlinks=1; - my_use_symdir=0; - have_symlink=SHOW_OPTION_DISABLED; -#endif - - optind = 0; // setup in case getopt() was called previously - while ((c=getopt_long(argc,argv,"ab:C:h:#::T::?l::L:O:P:sS::t:u:noVvWI?", - long_options, &option_index)) != EOF) - { - switch(c) { - case '#': + switch(optid) { + case '#': #ifndef DBUG_OFF - DBUG_PUSH(optarg ? optarg : default_dbug_option); -#endif - opt_endinfo=1; /* unireg: memory allocation */ - break; - case 'W': - opt_warnings=1; - break; - case 'a': - opt_sql_mode = (MODE_REAL_AS_FLOAT | MODE_PIPES_AS_CONCAT | - MODE_ANSI_QUOTES | MODE_IGNORE_SPACE | MODE_SERIALIZABLE - | MODE_ONLY_FULL_GROUP_BY); - default_tx_isolation= ISO_SERIALIZABLE; - break; - case 'b': - strmake(mysql_home,optarg,sizeof(mysql_home)-1); - break; - case 'l': - opt_log=1; - opt_logname=optarg; // Use hostname.log if null - break; - case 'h': - strmake(mysql_real_data_home,optarg, sizeof(mysql_real_data_home)-1); - break; - case 'L': - strmake(language, optarg, sizeof(language)-1); - break; - case 'n': - opt_specialflag|= SPECIAL_NEW_FUNC; - break; - case 'o': - protocol_version=PROTOCOL_VERSION-1; - break; - case 'O': - if (set_changeable_var(optarg, changeable_vars)) - { - use_help(); - exit(1); - } - break; - case 'P': - mysql_port= (unsigned int) atoi(optarg); - break; - case OPT_LOCAL_INFILE: - opt_local_infile= test(!optarg || atoi(optarg) != 0); - break; - case OPT_SLAVE_SKIP_ERRORS: - init_slave_skip_errors(optarg); - break; - case OPT_SAFEMALLOC_MEM_LIMIT: + DBUG_PUSH(argument ? argument : default_dbug_option); +#endif + opt_endinfo=1; /* unireg: memory allocation */ + break; + case 'a': + opt_sql_mode = (MODE_REAL_AS_FLOAT | MODE_PIPES_AS_CONCAT | + MODE_ANSI_QUOTES | MODE_IGNORE_SPACE | MODE_SERIALIZABLE + | MODE_ONLY_FULL_GROUP_BY); + default_tx_isolation= ISO_SERIALIZABLE; + break; + case 'b': + strmake(mysql_home,argument,sizeof(mysql_home)-1); + break; + case 'l': + opt_log=1; + break; + case 'h': + strmake(mysql_real_data_home,argument, sizeof(mysql_real_data_home)-1); + break; + case 'L': + strmake(language, argument, sizeof(language)-1); + break; + case 'n': + opt_specialflag|= SPECIAL_NEW_FUNC; + break; + case 'o': + protocol_version=PROTOCOL_VERSION-1; + break; + case OPT_SLAVE_SKIP_ERRORS: + init_slave_skip_errors(argument); + break; + case OPT_SAFEMALLOC_MEM_LIMIT: #if !defined(DBUG_OFF) && defined(SAFEMALLOC) - safemalloc_mem_limit = atoi(optarg); + safemalloc_mem_limit = atoi(argument); #endif - break; - case OPT_RPL_RECOVERY_RANK: - rpl_recovery_rank=atoi(optarg); - break; - case OPT_SLAVE_LOAD_TMPDIR: - slave_load_tmpdir = my_strdup(optarg, MYF(MY_FAE)); - break; - case OPT_OLD_RPL_COMPAT: - opt_old_rpl_compat = 1; - break; - case OPT_SHOW_SLAVE_AUTH_INFO: - opt_show_slave_auth_info = 1; - break; - case OPT_SOCKET: - mysql_unix_port= optarg; - break; - case 'r': - mysqld_chroot=optarg; - break; -#ifdef USE_SYMDIR - case 's': - my_use_symdir=1; /* Use internal symbolic links */ - break; -#endif - case 't': - mysql_tmpdir=optarg; - break; - case OPT_TEMP_POOL: - use_temp_pool=1; - break; - case 'u': - mysqld_user=optarg; - break; - case 'v': - case 'V': - print_version(); - exit(0); - case 'I': - case '?': - usage(); - exit(0); - case 'T': - test_flags= optarg ? (uint) atoi(optarg) : 0; - opt_endinfo=1; - break; - case (int) OPT_BIG_TABLES: - thd_startup_options|=OPTION_BIG_TABLES; - break; - case (int) OPT_ISAM_LOG: - opt_myisam_log=1; - if (optarg) - myisam_log_filename=optarg; - break; - case (int) OPT_UPDATE_LOG: - opt_update_log=1; - opt_update_logname=optarg; // Use hostname.# if null - break; - case (int) OPT_RELAY_LOG_INDEX: - opt_relaylog_index_name = optarg; - break; - case (int) OPT_RELAY_LOG: - x_free(opt_relay_logname); - if (optarg && optarg[0]) - opt_relay_logname=my_strdup(optarg,MYF(0)); - break; - case (int) OPT_BIN_LOG_INDEX: - opt_binlog_index_name = optarg; - break; - case (int) OPT_BIN_LOG: - opt_bin_log=1; - x_free(opt_bin_logname); - if (optarg && optarg[0]) - opt_bin_logname=my_strdup(optarg,MYF(0)); - break; - // needs to be handled (as no-op) in non-debugging mode for test suite - case (int)OPT_DISCONNECT_SLAVE_EVENT_COUNT: -#ifndef DBUG_OFF - disconnect_slave_event_count = atoi(optarg); -#endif - break; - case (int)OPT_ABORT_SLAVE_EVENT_COUNT: -#ifndef DBUG_OFF - abort_slave_event_count = atoi(optarg); -#endif - break; - case (int)OPT_SPORADIC_BINLOG_DUMP_FAIL: -#ifndef DBUG_OFF - opt_sporadic_binlog_dump_fail = 1; -#endif - break; - case (int)OPT_MAX_BINLOG_DUMP_EVENTS: -#ifndef DBUG_OFF - max_binlog_dump_events = atoi(optarg); -#endif - break; - - case (int) OPT_LOG_SLAVE_UPDATES: - opt_log_slave_updates = 1; - break; - - case (int) OPT_INIT_RPL_ROLE: + break; + case 'v': + case 'V': + print_version(); + exit(0); + case 'I': + case '?': + usage(); + exit(0); + case 'T': + test_flags= argument ? (uint) atoi(argument) : 0; + test_flags&= ~TEST_NO_THREADS; + opt_endinfo=1; + break; + case (int) OPT_BIG_TABLES: + thd_startup_options|=OPTION_BIG_TABLES; + break; + case (int) OPT_ISAM_LOG: + opt_myisam_log=1; + break; + case (int) OPT_UPDATE_LOG: + opt_update_log=1; + break; + case (int) OPT_BIN_LOG: + opt_bin_log=1; + break; + case (int) OPT_INIT_RPL_ROLE: { int role; - if ((role=find_type(optarg, &rpl_role_typelib, 2)) <= 0) + if ((role=find_type(argument, &rpl_role_typelib, 2)) <= 0) { - fprintf(stderr, "Unknown replication role: %s\n", optarg); + fprintf(stderr, "Unknown replication role: %s\n", argument); exit(1); } rpl_status = (role == 1) ? RPL_AUTH_MASTER : RPL_IDLE_SLAVE; break; } - case (int)OPT_REPLICATE_IGNORE_DB: + case (int)OPT_REPLICATE_IGNORE_DB: + { + i_string *db = new i_string(argument); + replicate_ignore_db.push_back(db); + break; + } + case (int)OPT_REPLICATE_DO_DB: + { + i_string *db = new i_string(argument); + replicate_do_db.push_back(db); + break; + } + case (int)OPT_REPLICATE_REWRITE_DB: + { + char* key = argument,*p, *val; + p = strstr(argument, "->"); + if (!p) { - i_string *db = new i_string(optarg); - replicate_ignore_db.push_back(db); - break; + fprintf(stderr, + "Bad syntax in replicate-rewrite-db - missing '->'!\n"); + exit(1); } - case (int)OPT_REPLICATE_DO_DB: + val = p--; + while (my_isspace(system_charset_info, *p) && p > argument) *p-- = 0; + if (p == argument) { - i_string *db = new i_string(optarg); - replicate_do_db.push_back(db); - break; + fprintf(stderr, + "Bad syntax in replicate-rewrite-db - empty FROM db!\n"); + exit(1); } - case (int)OPT_REPLICATE_REWRITE_DB: + *val = 0; + val += 2; + while (*val && my_isspace(system_charset_info, *val)) + *val++; + if (!*val) { - char* key = optarg,*p, *val; - p = strstr(optarg, "->"); - if (!p) - { - fprintf(stderr, - "Bad syntax in replicate-rewrite-db - missing '->'!\n"); - exit(1); - } - val = p--; - while(my_isspace(system_charset_info,*p) && p > optarg) *p-- = 0; - if(p == optarg) - { - fprintf(stderr, - "Bad syntax in replicate-rewrite-db - empty FROM db!\n"); - exit(1); - } - *val = 0; - val += 2; - while(*val && my_isspace(system_charset_info,*val)) *val++; - if (!*val) - { - fprintf(stderr, - "Bad syntax in replicate-rewrite-db - empty TO db!\n"); - exit(1); - } - - i_string_pair* db_pair = new i_string_pair(key, val); - replicate_rewrite_db.push_back(db_pair); - break; + fprintf(stderr, + "Bad syntax in replicate-rewrite-db - empty TO db!\n"); + exit(1); } - case (int)OPT_BINLOG_IGNORE_DB: - { - i_string *db = new i_string(optarg); - binlog_ignore_db.push_back(db); - break; - } - case (int)OPT_BINLOG_DO_DB: - { - i_string *db = new i_string(optarg); - binlog_do_db.push_back(db); - break; - } - case (int)OPT_REPLICATE_DO_TABLE: + i_string_pair* db_pair = new i_string_pair(key, val); + replicate_rewrite_db.push_back(db_pair); + break; + } + + case (int)OPT_BINLOG_IGNORE_DB: + { + i_string *db = new i_string(argument); + binlog_ignore_db.push_back(db); + break; + } + case (int)OPT_BINLOG_DO_DB: + { + i_string *db = new i_string(argument); + binlog_do_db.push_back(db); + break; + } + case (int)OPT_REPLICATE_DO_TABLE: + { + if (!do_table_inited) + init_table_rule_hash(&replicate_do_table, &do_table_inited); + if(add_table_rule(&replicate_do_table, argument)) { - if (!do_table_inited) - init_table_rule_hash(&replicate_do_table, &do_table_inited); - if(add_table_rule(&replicate_do_table, optarg)) - { - fprintf(stderr, "Could not add do table rule '%s'!\n", optarg); - exit(1); - } - table_rules_on = 1; - break; + fprintf(stderr, "Could not add do table rule '%s'!\n", argument); + exit(1); } - case (int)OPT_REPLICATE_WILD_DO_TABLE: + table_rules_on = 1; + break; + } + case (int)OPT_REPLICATE_WILD_DO_TABLE: + { + if (!wild_do_table_inited) + init_table_rule_array(&replicate_wild_do_table, + &wild_do_table_inited); + if(add_wild_table_rule(&replicate_wild_do_table, argument)) { - if (!wild_do_table_inited) - init_table_rule_array(&replicate_wild_do_table, - &wild_do_table_inited); - if(add_wild_table_rule(&replicate_wild_do_table, optarg)) - { - fprintf(stderr, "Could not add do table rule '%s'!\n", optarg); - exit(1); - } - table_rules_on = 1; - break; + fprintf(stderr, "Could not add do table rule '%s'!\n", argument); + exit(1); } - case (int)OPT_REPLICATE_WILD_IGNORE_TABLE: + table_rules_on = 1; + break; + } + case (int)OPT_REPLICATE_WILD_IGNORE_TABLE: + { + if (!wild_ignore_table_inited) + init_table_rule_array(&replicate_wild_ignore_table, + &wild_ignore_table_inited); + if(add_wild_table_rule(&replicate_wild_ignore_table, argument)) { - if (!wild_ignore_table_inited) - init_table_rule_array(&replicate_wild_ignore_table, - &wild_ignore_table_inited); - if(add_wild_table_rule(&replicate_wild_ignore_table, optarg)) - { - fprintf(stderr, "Could not add ignore table rule '%s'!\n", optarg); - exit(1); - } - table_rules_on = 1; - break; + fprintf(stderr, "Could not add ignore table rule '%s'!\n", argument); + exit(1); } - case (int)OPT_REPLICATE_IGNORE_TABLE: + table_rules_on = 1; + break; + } + case (int)OPT_REPLICATE_IGNORE_TABLE: + { + if (!ignore_table_inited) + init_table_rule_hash(&replicate_ignore_table, &ignore_table_inited); + if(add_table_rule(&replicate_ignore_table, argument)) { - if (!ignore_table_inited) - init_table_rule_hash(&replicate_ignore_table, &ignore_table_inited); - if(add_table_rule(&replicate_ignore_table, optarg)) - { - fprintf(stderr, "Could not add ignore table rule '%s'!\n", optarg); - exit(1); - } - table_rules_on = 1; - break; + fprintf(stderr, "Could not add ignore table rule '%s'!\n", argument); + exit(1); } - case (int) OPT_SQL_BIN_UPDATE_SAME: - opt_sql_bin_update = 1; - break; - case (int) OPT_SLOW_QUERY_LOG: - opt_slow_log=1; - opt_slow_logname=optarg; - break; - case (int)OPT_SKIP_SLAVE_START: - opt_skip_slave_start = 1; + table_rules_on = 1; break; - case (int) OPT_SKIP_NEW: - opt_specialflag|= SPECIAL_NO_NEW_FUNC; - myisam_delay_key_write=0; - myisam_concurrent_insert=0; - myisam_recover_options= HA_RECOVER_NONE; - my_disable_symlinks=1; - my_use_symdir=0; - have_symlink=SHOW_OPTION_DISABLED; - ha_open_options&= ~HA_OPEN_ABORT_IF_CRASHED; + } + case (int) OPT_SLOW_QUERY_LOG: + opt_slow_log=1; + break; + case (int)OPT_RECKLESS_SLAVE: + opt_reckless_slave = 1; + init_slave_skip_errors("all"); + break; + case (int) OPT_SKIP_NEW: + opt_specialflag|= SPECIAL_NO_NEW_FUNC; + myisam_delay_key_write=0; + myisam_concurrent_insert=0; + myisam_recover_options= HA_RECOVER_NONE; + my_disable_symlinks=1; + my_use_symdir=0; + have_symlink=SHOW_OPTION_DISABLED; + ha_open_options&= ~HA_OPEN_ABORT_IF_CRASHED; #ifdef HAVE_QUERY_CACHE - query_cache_size=0; -#endif - break; - case (int) OPT_SAFE: - opt_specialflag|= SPECIAL_SAFE_MODE; - myisam_delay_key_write=0; - myisam_recover_options= HA_RECOVER_NONE; // To be changed - ha_open_options&= ~HA_OPEN_ABORT_IF_CRASHED; - break; - case (int) OPT_SKIP_CONCURRENT_INSERT: - myisam_concurrent_insert=0; - break; - case (int) OPT_SKIP_PRIOR: - opt_specialflag|= SPECIAL_NO_PRIOR; - break; - case (int) OPT_SKIP_GRANT: - opt_noacl=1; - break; - case (int) OPT_SKIP_LOCK: - my_disable_locking=myisam_single_user= 1; - break; - case (int) OPT_SKIP_HOST_CACHE: - opt_specialflag|= SPECIAL_NO_HOST_CACHE; - break; - case (int) OPT_ENABLE_LOCK: - my_disable_locking=myisam_single_user=0; - break; - case (int) OPT_USE_LOCKING: - my_disable_locking=0; - break; - case (int) OPT_SKIP_RESOLVE: - opt_specialflag|=SPECIAL_NO_RESOLVE; - break; - case (int) OPT_LONG_FORMAT: - opt_specialflag|=SPECIAL_LONG_LOG_FORMAT; - break; - case (int) OPT_NO_MIX_TYPE: - opt_no_mix_types = 1; - break; - case (int) OPT_SKIP_NETWORKING: - opt_disable_networking=1; - mysql_port=0; - break; - case (int) OPT_SKIP_SHOW_DB: - opt_skip_show_db=1; - opt_specialflag|=SPECIAL_SKIP_SHOW_DB; - mysql_port=0; - break; - case (int) OPT_MEMLOCK: - locked_in_memory=1; - break; - case (int) OPT_ONE_THREAD: - test_flags |= TEST_NO_THREADS; - break; - case (int) OPT_WANT_CORE: - test_flags |= TEST_CORE_ON_SIGNAL; - break; - case (int) OPT_SKIP_STACK_TRACE: - test_flags|=TEST_NO_STACKTRACE; - break; - case (int) OPT_SKIP_SYMLINKS: - my_disable_symlinks=1; - my_use_symdir=0; - have_symlink=SHOW_OPTION_DISABLED; - break; - case (int) OPT_BIND_ADDRESS: - if (optarg && my_isdigit(system_charset_info,optarg[0])) - { - my_bind_addr = (ulong) inet_addr(optarg); - } + query_cache_size=0; +#endif + break; + case (int) OPT_SAFE: + opt_specialflag|= SPECIAL_SAFE_MODE; + myisam_delay_key_write=0; + myisam_recover_options= HA_RECOVER_NONE; // To be changed + ha_open_options&= ~HA_OPEN_ABORT_IF_CRASHED; + break; + case (int) OPT_SKIP_PRIOR: + opt_specialflag|= SPECIAL_NO_PRIOR; + break; + case (int) OPT_SKIP_LOCK: + my_disable_locking=myisam_single_user= 1; + break; + case (int) OPT_SKIP_HOST_CACHE: + opt_specialflag|= SPECIAL_NO_HOST_CACHE; + break; + case (int) OPT_ENABLE_LOCK: + my_disable_locking=myisam_single_user=0; + break; + case (int) OPT_USE_LOCKING: + my_disable_locking=0; + break; + case (int) OPT_SKIP_RESOLVE: + opt_specialflag|=SPECIAL_NO_RESOLVE; + break; + case (int) OPT_LONG_FORMAT: + opt_specialflag|=SPECIAL_LONG_LOG_FORMAT; + break; + case (int) OPT_SKIP_NETWORKING: + opt_disable_networking=1; + mysql_port=0; + break; + case (int) OPT_SKIP_SHOW_DB: + opt_skip_show_db=1; + opt_specialflag|=SPECIAL_SKIP_SHOW_DB; + mysql_port=0; + break; +#ifdef ONE_THREAD + case (int) OPT_ONE_THREAD: + test_flags |= TEST_NO_THREADS; +#endif + break; + case (int) OPT_WANT_CORE: + test_flags |= TEST_CORE_ON_SIGNAL; + break; + case (int) OPT_SKIP_STACK_TRACE: + test_flags|=TEST_NO_STACKTRACE; + break; + case (int) OPT_SKIP_SYMLINKS: + my_disable_symlinks=1; + my_use_symdir=0; + have_symlink=SHOW_OPTION_DISABLED; + break; + case (int) OPT_BIND_ADDRESS: + if (argument && my_isdigit(system_charset_info, argument[0])) + { + my_bind_addr = (ulong) inet_addr(argument); + } + else + { + struct hostent *ent; + if (!argument || !argument[0]) + ent=gethostbyname(argument); else { - struct hostent *ent; - if (!optarg || !optarg[0]) - ent=gethostbyname(optarg); - else + char myhostname[255]; + if (gethostname(myhostname,sizeof(myhostname)) < 0) { - char myhostname[255]; - if (gethostname(myhostname,sizeof(myhostname)) < 0) - { - sql_perror("Can't start server: cannot get my own hostname!"); - exit(1); - } - ent=gethostbyname(myhostname); - } - if (!ent) - { - sql_perror("Can't start server: cannot resolve hostname!"); + sql_perror("Can't start server: cannot get my own hostname!"); exit(1); } - my_bind_addr = (ulong) ((in_addr*)ent->h_addr_list[0])->s_addr; + ent=gethostbyname(myhostname); } - break; - case (int) OPT_PID_FILE: - strmake(pidfile_name, optarg, sizeof(pidfile_name)-1); - break; - case (int) OPT_INIT_FILE: - opt_init_file=optarg; - break; - case (int) OPT_HAVE_NAMED_PIPE: -#if __NT__ - opt_enable_named_pipe=1; -#endif - break; + if (!ent) + { + sql_perror("Can't start server: cannot resolve hostname!"); + exit(1); + } + my_bind_addr = (ulong) ((in_addr*)ent->h_addr_list[0])->s_addr; + } + break; + case (int) OPT_PID_FILE: + strmake(pidfile_name, argument, sizeof(pidfile_name)-1); + break; #ifdef __WIN__ - case (int) OPT_STANDALONE: /* Dummy option for NT */ - break; - case (int) OPT_CONSOLE: - opt_console=1; - break; + case (int) OPT_STANDALONE: /* Dummy option for NT */ + break; #endif - case (int) OPT_FLUSH: + case (int) OPT_FLUSH: #ifdef HAVE_ISAM - nisam_flush=1; -#endif - myisam_flush=1; - flush_time=0; // No auto flush - break; - case OPT_LOW_PRIORITY_UPDATES: - thd_startup_options|=OPTION_LOW_PRIORITY_UPDATES; - thr_upgraded_concurrent_insert_lock= TL_WRITE_LOW_PRIORITY; - low_priority_updates=1; - break; - case OPT_BOOTSTRAP: - opt_noacl=opt_bootstrap=1; - break; - case OPT_TABLE_TYPE: + nisam_flush=1; +#endif + myisam_flush=1; + flush_time=0; // No auto flush + break; + case OPT_LOW_PRIORITY_UPDATES: + thd_startup_options|=OPTION_LOW_PRIORITY_UPDATES; + thr_upgraded_concurrent_insert_lock= TL_WRITE_LOW_PRIORITY; + low_priority_updates=1; + break; + case OPT_BOOTSTRAP: + opt_noacl=opt_bootstrap=1; + break; + case OPT_TABLE_TYPE: { int type; - if ((type=find_type(optarg, &ha_table_typelib, 2)) <= 0) + if ((type=find_type(argument, &ha_table_typelib, 2)) <= 0) { - fprintf(stderr,"Unknown table type: %s\n",optarg); + fprintf(stderr,"Unknown table type: %s\n",argument); exit(1); } default_table_type= (enum db_type) type; break; } - case OPT_SERVER_ID: - server_id = atoi(optarg); - server_id_supplied = 1; - break; - case OPT_DELAY_KEY_WRITE: - ha_open_options|=HA_OPEN_DELAY_KEY_WRITE; - myisam_delay_key_write=1; - break; - case OPT_SKIP_DELAY_KEY_WRITE: - myisam_delay_key_write=0; - break; - case 'C': - strmake(default_charset, optarg, sizeof(default_charset)-1); - break; - case OPT_CHARSETS_DIR: - strmake(mysql_charsets_dir, optarg, sizeof(mysql_charsets_dir)-1); - charsets_dir = mysql_charsets_dir; - break; + case OPT_SERVER_ID: + server_id_supplied = 1; + break; + case OPT_DELAY_KEY_WRITE: + ha_open_options|=HA_OPEN_DELAY_KEY_WRITE; + myisam_delay_key_write=1; + break; + case 'C': + strmake(default_charset, argument, sizeof(default_charset)-1); + break; + case OPT_CHARSETS_DIR: + strmake(mysql_charsets_dir, argument, sizeof(mysql_charsets_dir)-1); + charsets_dir = mysql_charsets_dir; + break; #ifdef HAVE_OPENSSL - case OPT_SSL_SSL: - opt_use_ssl = 1; /* true */ - break; - case OPT_SSL_KEY: - opt_use_ssl = 1; /* true */ - my_free(opt_ssl_key, MYF(MY_ALLOW_ZERO_PTR)); - opt_ssl_key = my_strdup(optarg, MYF(0)); - break; - case OPT_SSL_CERT: - opt_use_ssl = 1; /* true */ - my_free(opt_ssl_cert, MYF(MY_ALLOW_ZERO_PTR)); - opt_ssl_cert = my_strdup(optarg, MYF(0)); - break; - case OPT_SSL_CA: - opt_use_ssl = 1; /* true */ - my_free(opt_ssl_ca, MYF(MY_ALLOW_ZERO_PTR)); - opt_ssl_ca = my_strdup(optarg, MYF(0)); - break; - case OPT_SSL_CAPATH: - opt_use_ssl = 1; /* true */ - my_free(opt_ssl_capath, MYF(MY_ALLOW_ZERO_PTR)); - opt_ssl_capath = my_strdup(optarg, MYF(0)); - break; - case OPT_SSL_CIPHER: - opt_use_ssl = 1; /* true */ - my_free(opt_ssl_cipher, MYF(MY_ALLOW_ZERO_PTR)); - opt_ssl_cipher = my_strdup(optarg, MYF(0)); - break; +#include "sslopt-case.h" #endif - case OPT_DES_KEY_FILE: + case OPT_DES_KEY_FILE: #ifdef HAVE_OPENSSL - des_key_file=optarg; + des_key_file=argument; #endif - break; - case OPT_TX_ISOLATION: + break; + case OPT_TX_ISOLATION: { int type; - if ((type=find_type(optarg, &tx_isolation_typelib, 2)) <= 0) + if ((type=find_type(argument, &tx_isolation_typelib, 2)) <= 0) { - fprintf(stderr,"Unknown transaction isolation type: %s\n",optarg); + fprintf(stderr,"Unknown transaction isolation type: %s\n",argument); exit(1); } default_tx_isolation= (enum_tx_isolation) (type-1); break; } #ifdef HAVE_BERKELEY_DB - case OPT_BDB_LOG: - berkeley_logdir=optarg; - break; - case OPT_BDB_HOME: - berkeley_home=optarg; - break; - case OPT_BDB_NOSYNC: - berkeley_env_flags|=DB_TXN_NOSYNC; - break; - case OPT_BDB_NO_RECOVER: - berkeley_init_flags&= ~(DB_RECOVER); - break; - case OPT_BDB_TMP: - berkeley_tmpdir=optarg; - break; - case OPT_BDB_LOCK: + case OPT_BDB_NOSYNC: + berkeley_env_flags|=DB_TXN_NOSYNC; + break; + case OPT_BDB_NO_RECOVER: + berkeley_init_flags&= ~(DB_RECOVER); + break; + case OPT_BDB_LOCK: { int type; - if ((type=find_type(optarg, &berkeley_lock_typelib, 2)) > 0) + if ((type=find_type(argument, &berkeley_lock_typelib, 2)) > 0) berkeley_lock_type=berkeley_lock_types[type-1]; else { - if (test_if_int(optarg,(uint) strlen(optarg))) - berkeley_lock_scan_time=atoi(optarg); + if (test_if_int(argument,(uint) strlen(argument))) + berkeley_lock_scan_time=atoi(argument); else { - fprintf(stderr,"Unknown lock type: %s\n",optarg); + fprintf(stderr,"Unknown lock type: %s\n",argument); exit(1); } } break; } - case OPT_BDB_SHARED: - berkeley_init_flags&= ~(DB_PRIVATE); - berkeley_shared_data=1; - break; + case OPT_BDB_SHARED: + berkeley_init_flags&= ~(DB_PRIVATE); + berkeley_shared_data=1; + break; #endif /* HAVE_BERKELEY_DB */ - case OPT_BDB_SKIP: + case OPT_BDB_SKIP: #ifdef HAVE_BERKELEY_DB - berkeley_skip=1; - have_berkeley_db=SHOW_OPTION_DISABLED; + berkeley_skip=1; + have_berkeley_db=SHOW_OPTION_DISABLED; #endif - break; - case OPT_INNODB_SKIP: + break; + case OPT_INNODB_SKIP: #ifdef HAVE_INNOBASE_DB - innodb_skip=1; - have_innodb=SHOW_OPTION_DISABLED; + innodb_skip=1; + have_innodb=SHOW_OPTION_DISABLED; #endif - break; - case OPT_INNODB_DATA_FILE_PATH: + break; + case OPT_INNODB_DATA_FILE_PATH: #ifdef HAVE_INNOBASE_DB - innobase_data_file_path=optarg; + innobase_data_file_path=argument; #endif - break; + break; #ifdef HAVE_INNOBASE_DB - case OPT_INNODB_DATA_HOME_DIR: - innobase_data_home_dir=optarg; - break; - case OPT_INNODB_LOG_GROUP_HOME_DIR: - innobase_log_group_home_dir=optarg; - break; - case OPT_INNODB_LOG_ARCH_DIR: - innobase_log_arch_dir=optarg; - break; - case OPT_INNODB_LOG_ARCHIVE: - innobase_log_archive= optarg ? test(atoi(optarg)) : 1; - break; - case OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT: - innobase_flush_log_at_trx_commit= optarg ? test(atoi(optarg)) : 1; - break; - case OPT_INNODB_FAST_SHUTDOWN: - innobase_fast_shutdown= optarg ? test(atoi(optarg)) : 1; - break; - case OPT_INNODB_FLUSH_METHOD: - innobase_unix_file_flush_method=optarg; - break; + case OPT_INNODB_LOG_ARCHIVE: + innobase_log_archive= argument ? test(atoi(argument)) : 1; + break; + case OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT: + innobase_flush_log_at_trx_commit= argument ? test(atoi(argument)) : 1; + break; + case OPT_INNODB_FAST_SHUTDOWN: + innobase_fast_shutdown= argument ? test(atoi(argument)) : 1; + break; #endif /* HAVE_INNOBASE_DB */ - case OPT_DO_PSTACK: - opt_do_pstack = 1; - break; - case OPT_MYISAM_RECOVER: + case OPT_MYISAM_RECOVER: { - if (!optarg || !optarg[0]) + if (!argument || !argument[0]) { myisam_recover_options= HA_RECOVER_DEFAULT; myisam_recover_options_str= myisam_recover_typelib.type_names[0]; } else { - myisam_recover_options_str=optarg; + myisam_recover_options_str=argument; if ((myisam_recover_options= - find_bit_type(optarg, &myisam_recover_typelib)) == ~(ulong) 0) + find_bit_type(argument, &myisam_recover_typelib)) == ~(ulong) 0) { - fprintf(stderr, "Unknown option to myisam-recover: %s\n",optarg); + fprintf(stderr, "Unknown option to myisam-recover: %s\n",argument); exit(1); } } ha_open_options|=HA_OPEN_ABORT_IF_CRASHED; break; } - case OPT_SQL_MODE: + case OPT_SQL_MODE: { - sql_mode_str = optarg; + sql_mode_str = argument; if ((opt_sql_mode = - find_bit_type(optarg, &sql_mode_typelib)) == ~(ulong) 0) + find_bit_type(argument, &sql_mode_typelib)) == ~(ulong) 0) { - fprintf(stderr, "Unknown option to sql-mode: %s\n", optarg); + fprintf(stderr, "Unknown option to sql-mode: %s\n", argument); exit(1); } default_tx_isolation= ((opt_sql_mode & MODE_SERIALIZABLE) ? @@ -4267,78 +4395,37 @@ static void get_options(int argc,char **argv) ISO_READ_COMMITTED); break; } - case OPT_MASTER_HOST: - master_host=optarg; - break; - case OPT_MASTER_USER: - master_user=optarg; - break; - case OPT_MASTER_PASSWORD: - master_password=optarg; - break; - case OPT_MASTER_INFO_FILE: - master_info_file=optarg; - break; - case OPT_RELAY_LOG_INFO_FILE: - relay_log_info_file=optarg; - break; - case OPT_MASTER_PORT: - master_port= atoi(optarg); - break; - case OPT_MASTER_SSL: - master_ssl=atoi(optarg); - break; - case OPT_MASTER_SSL_KEY: - master_ssl_key=optarg; - break; - case OPT_MASTER_SSL_CERT: - master_ssl_cert=optarg; - break; - case OPT_REPORT_HOST: - report_host=optarg; - break; - case OPT_REPORT_USER: - report_user=optarg; - break; - case OPT_REPORT_PASSWORD: - report_password=optarg; - break; - case OPT_REPORT_PORT: - report_port= atoi(optarg); - break; - case OPT_MASTER_CONNECT_RETRY: - master_connect_retry= atoi(optarg); - break; - case OPT_MASTER_RETRY_COUNT: - master_retry_count= atoi(optarg); - break; - case OPT_SAFE_SHOW_DB: - opt_safe_show_db=1; - break; - case OPT_SAFE_USER_CREATE: - opt_safe_user_create=1; - break; - case OPT_SKIP_SAFEMALLOC: + case OPT_MASTER_PASSWORD: + master_password=argument; + break; + case OPT_SKIP_SAFEMALLOC: #ifdef SAFEMALLOC - sf_malloc_quick=1; + sf_malloc_quick=1; #endif - break; - default: - fprintf(stderr,"%s: Unrecognized option: %c\n",my_progname,c); - use_help(); - exit(1); - } - } - // Skip empty arguments (from shell) - while (argc != optind && !argv[optind][0]) - optind++; - if (argc != optind) - { - fprintf(stderr,"%s: Too many parameters\n",my_progname); - use_help(); - exit(1); + break; } - optind = 0; // setup so that getopt_long() can be called again + return 0; +} + + /* Initiates DEBUG - but no debugging here ! */ + +static void get_options(int argc,char **argv) +{ + int ho_error; + + myisam_delay_key_write=1; // Allow use of this +#ifndef HAVE_purify + my_use_symdir=1; // Use internal symbolic links +#else + /* Symlinks gives too many warnings with purify */ + my_disable_symlinks=1; + my_use_symdir=0; + have_symlink=SHOW_OPTION_DISABLED; +#endif + + if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) + exit(ho_error); + fix_paths(); default_table_type_name=ha_table_typelib.type_names[default_table_type-1]; default_tx_isolation_name=tx_isolation_typelib.type_names[default_tx_isolation]; diff --git a/sql/nt_servc.cc b/sql/nt_servc.cc index 8c705a94f55..be2ceb9cb7a 100644 --- a/sql/nt_servc.cc +++ b/sql/nt_servc.cc @@ -479,3 +479,33 @@ If this condition persist, reboot the machine and try again\n"); return ret_value; } +/* ------------------------------------------------------------------------ + -------------------------------------------------------------------------- */ +BOOL NTService::IsService(LPCSTR ServiceName) +{ + BOOL ret_value=FALSE; + SC_HANDLE service, scm; + + if (scm = OpenSCManager(0, 0,SC_MANAGER_ENUMERATE_SERVICE)) + { + if ((service = OpenService(scm,ServiceName, SERVICE_ALL_ACCESS ))) + { + ret_value=TRUE; + CloseServiceHandle(service); + } + CloseServiceHandle(scm); + } + return ret_value; +} +/* ------------------------------------------------------------------------ + -------------------------------------------------------------------------- */ +BOOL NTService::got_service_option(char **argv, char *service_option) +{ + char *option = argv[1]; + + while (*option) + if (!strcmp(option++, service_option)) + return TRUE; + + return FALSE; +} diff --git a/sql/nt_servc.h b/sql/nt_servc.h index 40d1a8c03fa..ab3238e0f41 100644 --- a/sql/nt_servc.h +++ b/sql/nt_servc.h @@ -52,6 +52,8 @@ class NTService LPCSTR szAccountName=NULL,LPCSTR szPassword=NULL); BOOL SeekStatus(LPCSTR szInternName, int OperationType); BOOL Remove(LPCSTR szInternName); + BOOL IsService(LPCSTR ServiceName); + BOOL got_service_option(char **argv, char *service_option); void Stop(void); //to be called from app. to stop service diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index 3f16880c18e..112642d0a5f 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -608,6 +608,9 @@ int show_slave_hosts(THD* thd) int connect_to_master(THD *thd, MYSQL* mysql, MASTER_INFO* mi) { + if (!mi->host || !*mi->host) /* empty host */ + return 1; + if (!mc_mysql_connect(mysql, mi->host, mi->user, mi->password, 0, mi->port, 0, 0)) { diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 950ca4f6623..28e1042d02c 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -156,7 +156,7 @@ "%-.16s p-Bøíkaz nepøístupný pro u¾ivatele: '%-.32s@%-.64s' pro sloupec '%-.64s' v tabulce '%-.64s'", "Neplatn-Bý pøíkaz GRANT/REVOKE. Prosím, pøeètìte si v manuálu, jaká privilegia je mo¾né pou¾ít.", "Argument p-Bøíkazu GRANT u¾ivatel nebo stroj je pøíli¹ dlouhý", -"Tabulka '%-64s.%s' neexistuje", +"Tabulka '%-.64s.%s' neexistuje", "Neexistuje odpov-Bídající grant pro u¾ivatele '%-.32s' na stroji '%-.64s' pro tabulku '%-.64s'", "Pou-B¾itý pøíkaz není v této verzi MySQL povolen", "Va-B¹e syntaxe je nìjaká divná", @@ -203,7 +203,7 @@ "S-Bí»ová chyba pøi zápisu na master", "-B®ádný sloupec nemá vytvoøen fulltextový index", "Nemohu prov-Bést zadaný pøíkaz, proto¾e existují aktivní zamèené tabulky nebo aktivní transakce", -"Nezn-Bámá systémová promìnná '%-.64'", +"Nezn-Bámá systémová promìnná '%-.64s'", "Tabulka '%-.64s' je ozna-Bèena jako poru¹ená a mìla by být opravena", "Tabulka '%-.64s' je ozna-Bèena jako poru¹ená a poslední (automatická?) oprava se nezdaøila", "Warning: Some non-transactional changed tables couldn't be rolled back", @@ -236,4 +236,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index d87ed4ee629..b89a6f1f11c 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -197,7 +197,7 @@ "Netværksfejl ved skrivning til master", "Kan ikke finde en FULLTEXT nøgle som svarer til kolonne listen", "Kan ikke udføre den givne kommando fordi der findes aktive, låste tabeller eller fordi der udføres en transaktion", -"Ukendt systemvariabel '%-.64'", +"Ukendt systemvariabel '%-.64s'", "Tabellen '%-.64s' er markeret med fejl og bør repareres", "Tabellen '%-.64s' er markeret med fejl og sidste (automatiske?) REPAIR fejlede", "Advarsel: Visse data i tabeller der ikke understøtter transaktioner kunne ikke tilbagestilles", @@ -230,4 +230,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index c8b47cb3c19..dc3947a30f8 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -155,7 +155,7 @@ "%-.16s commando geweigerd voor gebruiker: '%-.32s@%-.64s' voor kolom '%-.64s' in tabel '%-.64s'", "Foutief GRANT/REVOKE commando. Raadpleeg de handleiding welke priveleges gebruikt kunnen worden.", "De host of gebruiker parameter voor GRANT is te lang", -"Tabel '%-64s.%s' bestaat niet", +"Tabel '%-.64s.%s' bestaat niet", "Deze toegang (GRANT) is niet toegekend voor gebruiker '%-.32s' op host '%-.64s' op tabel '%-.64s'", "Het used commando is niet toegestaan in deze MySQL versie", "Er is iets fout in de gebruikte syntax", @@ -202,7 +202,7 @@ "Net fout tijdens schrijven naar master", "Kan geen FULLTEXT index vinden passend bij de kolom lijst", "Kan het gegeven commando niet uitvoeren, want u heeft actieve gelockte tabellen of een actieve transactie", -"Onbekende systeem variabele '%-.64'", +"Onbekende systeem variabele '%-.64s'", "Tabel '%-.64s' staat als gecrashed gemarkeerd en dient te worden gerepareerd", "Tabel '%-.64s' staat als gecrashed gemarkeerd en de laatste (automatische?) reparatie poging mislukte", "Waarschuwing: Roll back mislukt voor sommige buiten transacties gewijzigde tabellen", @@ -235,4 +235,6 @@ "Kan de query niet uitvoeren vanwege een conflicterende read lock", "Het combineren van transactionele en niet-transactionele tabellen is uitgeschakeld.", "Optie '%s' tweemaal gebruikt in opdracht", -"Gebruiker '%-64s' heeft het maximale gebruik van de '%s' faciliteit overschreden (huidige waarde: %ld)", +"Gebruiker '%-.64s' heeft het maximale gebruik van de '%s' faciliteit overschreden (huidige waarde: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 5033449c266..b3d04954634 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -194,7 +194,7 @@ "Net error writing to master", "Can't find FULLTEXT index matching the column list", "Can't execute the given command because you have active locked tables or an active transaction", -"Unknown system variable '%-.64'", +"Unknown system variable '%-.64s'", "Table '%-.64s' is marked as crashed and should be repaired", "Table '%-.64s' is marked as crashed and last (automatic?) repair failed", "Warning: Some non-transactional changed tables couldn't be rolled back", @@ -227,4 +227,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 6a83468eae5..fe121a27d5d 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -199,7 +199,7 @@ "Net error writing to master", "Ei suutnud leida FULLTEXT indeksit, mis kattuks kasutatud tulpadega", "Ei suuda täita antud käsku kuna on aktiivseid lukke või käimasolev transaktsioon", -"Tundmatu süsteemne muutuja '%-.64'", +"Tundmatu süsteemne muutuja '%-.64s'", "Tabel '%-.64s' on märgitud vigaseks ja tuleb parandada", "Tabel '%-.64s' on märgitud vigaseks ja viimane (automaatne?) parandus ebaõnnestus", "Hoiatus: mõnesid transaktsioone mittetoetavaid tabeleid ei suudetud tagasi kerida", @@ -232,4 +232,6 @@ "Ei suuda täita päringut konfliktse luku tõttu", "Transaktsioone toetavate ning mittetoetavate tabelite kooskasutamine ei ole lubatud", "Määrangut '%s' on lauses kasutatud topelt", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index cf3e3e845e4..3c458f037fb 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -122,103 +122,103 @@ "Ligne trop grande. Le taille maximale d'une ligne, sauf les BLOBs, est %d. Changez le type de quelques colonnes en BLOB", "Débordement de la pile des tâches (Thread stack). Utilisées: %ld pour une pile de %ld. Essayez 'mysqld -O thread_stack=#' pour indiquer une plus grande valeur", "Dépendance croisée dans une clause OUTER JOIN. Vérifiez la condition ON", -"Column '%-.32s' is used with UNIQUE or INDEX but is not defined as NOT NULL", -"Can't load function '%-.64s'", -"Can't initialize function '%-.64s'; %-.80s", -"No paths allowed for shared library", -"Function '%-.64s' already exist", -"Can't open shared library '%-.64s' (errno: %d %s)", -"Can't find function '%-.64s' in library'", -"Function '%-.64s' is not defined", -"Host '%-.64s' is blocked because of many connection errors. Unblock with 'mysqladmin flush-hosts'", -"Host '%-.64s' is not allowed to connect to this MySQL server", -"You are using MySQL as an anonymous users and anonymous users are not allowed to change passwords", -"You must have privileges to update tables in the mysql database to be able to change passwords for others", -"Can't find any matching row in the user table", -"Rows matched: %ld Changed: %ld Warnings: %ld", -"Can't create a new thread (errno %d). If you are not out of available memory you can consult the manual for any possible OS dependent bug", +"La colonne '%-.32s' fait partie d'un index UNIQUE ou INDEX mais n'est pas définie comme NOT NULL" +"Imposible de charger la fonction '%-.64s'", +"Impossible d'initialiser la fonction '%-.64s'; %-.80s", +"Chemin interdit pour les bibliothèques partagées", +"La fonction '%-.64s' existe déjà", +"Impossible d'ouvrir la bibliothèque partagée '%-.64s' (errno: %d %s)", +"Impossible de trouver la fonction '%-.64s' dans la bibliothèque'", +"La fonction '%-.64s' n'est pas définie", +"L'hôte '%-.64s' est bloqué à cause d'un trop grand nombre d'erreur de connection. Débloquer le par 'mysqladmin flush-hosts'", +"Le hôte '%-.64s' n'est pas authorisé à se connecter à ce serveur MySQL", +"Vous utilisez un utilisateur anonyme et les utilisateurs anonymes ne sont pas autorisés à changer les mots de passe", +"Vous devez avoir le privilège update sur les tables de la base de donnée mysql pour pouvoir changer les mots de passe des autres", +"Impossible de trouver un enregistrement correspondant dans la table user", +"Enregistrements correspondants: %ld Modifiés: %ld Warnings: %ld", +"Impossible de créer une nouvelle tâche (errno %d). S'il reste de la mémoire libre, consultez le manual pour trouver un éventuel bug dépendant de l'OS", "Column count doesn't match value count at row %ld", -"Can't reopen table: '%-.64s', -"Invalid use of NULL value", -"Got error '%-.64s' from regexp", -"Mixing of GROUP columns (MIN(),MAX(),COUNT()...) with no GROUP columns is illegal if there is no GROUP BY clause", -"There is no such grant defined for user '%-.32s' on host '%-.64s'", -"%-.16s command denied to user: '%-.32s@%-.64s' for table '%-.64s'", -"%-.16s command denied to user: '%-.32s@%-.64s' for column '%-.64s' in table '%-.64s'", -"Illegal GRANT/REVOKE command. Please consult the manual which privleges can be used.", -"The host or user argument to GRANT is too long", -"Table '%-64s.%s' doesn't exist", -"There is no such grant defined for user '%-.32s' on host '%-.64s' on table '%-.64s'", -"The used command is not allowed with this MySQL version", -"Something is wrong in your syntax", -"Delayed insert thread couldn't get requested lock for table %-.64s", -"Too many delayed threads in use", -"Aborted connection %ld to db: '%-.64s' user: '%-.64s' (%s)", -"Got a packet bigger than 'max_allowed_packet'", -"Got a read error from the connection pipe", -"Got an error from fcntl()", -"Got packets out of order", -"Couldn't uncompress communication packet", -"Got an error reading communication packets" -"Got timeout reading communication packets", -"Got an error writing communication packets", -"Got timeout writing communication packets", -"Result string is longer than max_allowed_packet", -"The used table type doesn't support BLOB/TEXT columns", -"The used table type doesn't support AUTO_INCREMENT columns", -"INSERT DELAYED can't be used with table '%-.64s', because it is locked with LOCK TABLES", -"Incorrect column name '%-.100s'", -"The used table handler can't index column '%-.64s'", -"All tables in the MERGE table are not defined identically", -"Can't write, because of unique constraint, to table '%-.64s'", -"BLOB column '%-.64s' used in key specification without a key length", -"All parts of a PRIMARY KEY must be NOT NULL; If you need NULL in a key, use UNIQUE instead", -"Result consisted of more than one row", -"This table type requires a primary key", -"This version of MySQL is not compiled with RAID support", -"You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column", -"Key '%-.64s' doesn't exist in table '%-.64s'", -"Can't open table", -"The handler for the table doesn't support check/repair", -"You are not allowed to execute this command in a transaction", -"Got error %d during COMMIT", -"Got error %d during ROLLBACK", -"Got error %d during FLUSH_LOGS", -"Got error %d during CHECKPOINT", -"Aborted connection %ld to db: '%-.64s' user: '%-.32s' host: `%-.64s' (%-.64s)", -"The handler for the table does not support binary table dump", -"Binlog closed while trying to FLUSH MASTER", -"Failed rebuilding the index of dumped table '%-.64s'", -"Error from master: '%-.64s'", -"Net error reading from master", -"Net error writing to master", -"Can't find FULLTEXT index matching the column list", -"Can't execute the given command because you have active locked tables or an active transaction", -"Unknown system variable '%-.64'", -"Table '%-.64s' is marked as crashed and should be repaired", -"Table '%-.64s' is marked as crashed and last (automatic?) repair failed", -"Warning: Some non-transactional changed tables couldn't be rolled back", -"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again', -"This operation cannot be performed with a running slave, run SLAVE STOP first", -"This operation requires a running slave, configure slave and do SLAVE START", -"The server is not configured as slave, fix in config file or with CHANGE MASTER TO", -"Could not initialize master info structure, check permisions on master.info", -"Could not create slave thread, check system resources", -"User %-.64s has already more than 'max_user_connections' active connections", -"You may only use constant expressions with SET", -"Lock wait timeout exceeded", -"The total number of locks exceeds the lock table size", -"Update locks cannot be acquired during a READ UNCOMMITTED transaction", -"DROP DATABASE not allowed while thread is holding global read lock", -"CREATE DATABASE not allowed while thread is holding global read lock", -"Wrong arguments to %s", -"%-.32s@%-.64s is not allowed to create new users", -"Incorrect table definition; All MERGE tables must be in the same database", -"Deadlock found when trying to get lock; Try restarting transaction", -"The used table type doesn't support FULLTEXT indexes", -"Cannot add foreign key constraint", -"Cannot add a child row: a foreign key constraint fails", -"Cannot delete a parent row: a foreign key constraint fails", +"Impossible de réouvrir la table: '%-.64s', +"Utilisation incorrecte de la valeur NULL", +"Erreur '%-.64s' provenant de regexp", +"Mélanger les colonnes GROUP (MIN(),MAX(),COUNT()...) avec des colonnes normales est interdit s'il n'y a pas de clause GROUP BY", +"Un tel droit n'est pas défini pour l'utilisateur '%-.32s' sur l'hôte '%-.64s'", +"La commande '%-.16s' est interdite à l'utilisateur: '%-.32s@%-.64s' sur la table '%-.64s'", +"La commande '%-.16s' est interdite à l'utilisateur: '%-.32s@%-.64s' sur la colonne '%-.64s' de la table '%-.64s'", +"Commande GRANT/REVOKE incorrecte. Consultez le manuel.", +"L'hôte ou l'utilisateur donné en argument à GRANT est trop long", +"La table '%-64s.%s' n'existe pas", +"Un tel droit n'est pas défini pour l'utilisateur '%-.32s' sur l'hôte '%-.64s' sur la table '%-.64s'", +"Cette commande n'existe pas dans cette version de MySQL", +"Erreur de syntaxe", +"La tâche 'delayed insert' n'a pas pu obtenir le verrou démandé sur la table %-.64s", +"Trop de tâche 'delayed' en cours", +"Connection %ld avortée vers la bd: '%-.64s' utilisateur: '%-.64s' (%s)", +"Paquet plus grand que 'max_allowed_packet' reçu", +"Erreur de lecture reçue du pipe de connection", +"Erreur reçue de fcntl() ", +"Paquets reçus dans le désordre", +"Impossible de décompresser le paquet reçu", +"Erreur de lecture des paquets reçus" +"Timeout en lecture des paquets reçus", +"Erreur d'écriture des paquets envoyés", +"Timeout d'écriture des paquets envoyés", +"La chaîne résultat est plus grande que max_allowed_packet", +"Ce type de table ne supporte pas les colonnes BLOB/TEXT", +"Ce type de table ne supporte pas les colonnes AUTO_INCREMENT", +"INSERT DELAYED ne peut être utilisé avec la table '%-.64s', car elle est verrouée avec LOCK TABLES", +"Nom de colonne '%-.100s' incorrect", +"Le handler de la table ne peut indexé la colonne '%-.64s'", +"Toutes les tables de la table de type MERGE n'ont pas la même définition", +"Écriture impossible à cause d'un index UNIQUE sur la table '%-.64s'", +"La colonne '%-.64s' de type BLOB est utilisée dans une définition d'index sans longueur d'index", +"Toutes les parties d'un index PRIMARY KEY doivent être NOT NULL; Si vous avez besoin d'un NULL dans l'index, utilisez un index UNIQUE", +"Le résultat contient plus d'un enregistrement", +"Ce type de table nécessite une clé primaire (PRIMARY KEY)", +"Cette version de MySQL n'est pas compilée avec le support RAID", +"Vous êtes en mode 'safe update' et vous essayez de faire un UPDATE sans clause WHERE utilisant un index", +"L'index '%-.64s' n'existe pas sur la table '%-.64s'", +"Impossible d'ouvrir la table", +"Ce type de table ne supporte pas les check/repair", +"Vous n'êtes pas autorisé à exécute cette commande dans une transaction", +"Erreur %d lors du COMMIT", +"Erreur %d lors du ROLLBACK", +"Erreur %d lors du FLUSH_LOGS", +"Erreur %d lors du CHECKPOINT", +"Connection %ld avortée vers la bd: '%-.64s' utilisateur: '%-.32s' hôte: `%-.64s' (%-.64s)", +"Ce type de table ne supporte pas les copies binaires", +"Le 'binlog' a été fermé pendant l'exécution du FLUSH MASTER", +"La reconstruction de l'index de la table copiée '%-.64s' a échoué", +"Erreur reçue du maître: '%-.64s'", +"Erreur de lecture réseau reçue du maître", +"Erreur d'écriture réseau reçue du maître", +"Impossible de trouver un index FULLTEXT correspondant à cette liste de colonnes", +"Impossible d'exécuter la commande car vous avez des tables verrouillées ou une transaction active", +"Variable système '%-.64' inconnue", +"La table '%-.64s' est marquée 'crashed' et devrait être réparée", +"La table '%-.64s' est marquée 'crashed' et le dernier 'repair' a échoué", +"Attention: certaines tables ne supportant pas les transactions ont été changées et elles ne pourront pas être restituées", +"Cette transaction à commandes multiples nécessite plus de 'max_binlog_cache_size' octets de stockage, augmentez cette variable de mysqld et réessayez', +"Cette opération ne peut être réalisée avec un esclave actif, faites SLAVE STOP d'abord", +"Cette opération nécessite un esclave actif, configurez les esclaves et faites SLAVE START", +"Le server n'est pas configuré comme un esclave, changez le fichier de configuration ou utilisez CHANGE MASTER TO", +"Impossible d'initialiser les structures d'information de maître, vérifiez les permissions sur master.info", +"Impossible de créer une tâche esclave, vérifiez les ressources système", +"L'utilisateur %-.64s possède déjà plus de 'max_user_connections' connections actives", +"Seules les expressions constantes sont autorisées avec SET", +"Timeout sur l'obtention du verrou", +"Le nombre total de verrou dépasse la taille de la table des verrous", +"Un verrou en update ne peut être acquit pendant une transaction READ UNCOMMITTED", +"DROP DATABASE n'est pas autorisée pendant qu'une tâche possède un verrou global en lecture", +"CREATE DATABASE n'est pas autorisée pendant qu'une tâche possède un verrou global en lecture", +"Mauvais arguments à %s", +"%-.32s@%-.64s n'est pas autorisé à créer de nouveaux utilisateurs", +"Définition de table incorrecte : toutes les tables MERGE doivent être dans la même base de donnée", +"Deadlock découvert en essayant d'obtenir les verrous : essayez de redémarrer la transaction", +"Le type de table utilisé ne supporte pas les index FULLTEXT", +"Impossible d'ajouter des contraintes d'index externe", +"Impossible d'ajouter un enregistrement fils : une constrainte externe l'empèche", +"Impossible de supprimer un enregistrement père : une constrainte externe l'empèche", "Error connecting to master: %-.128s", "Error running query on master: %-.128s", "Error when executing command %s: %-.128s", @@ -227,4 +227,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 19d46fabab8..753911d8736 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -197,7 +197,7 @@ "Netzfehler beim Schreiben zum Master", "Kann keinen FULLTEXT-Index finden der der Spaltenliste entspricht", "Kann das aktuelle Kommando wegen aktiver Tabellensperre oder aktiver Transaktion nicht ausführen", -"Unbekannte System-Variabel '%-.64'", +"Unbekannte System-Variabel '%-.64s'", "Tabelle '%-.64s' ist als defekt makiert und sollte repariert werden", "Tabelle '%-.64s' ist als defekt makiert und der letzte (automatische) Reparaturversuch schlug fehl.", "Warnung: Das Rollback konnte bei einigen Tabellen, die nicht mittels Transaktionen geändert wurden, nicht ausgeführt werden.", @@ -230,4 +230,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index f9b4f137f82..9d092d32021 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -194,7 +194,7 @@ "Net error writing to master", "Can't find FULLTEXT index matching the column list", "Can't execute the given command because you have active locked tables or an active transaction", -"Unknown system variable '%-.64'", +"Unknown system variable '%-.64s'", "Table '%-.64s' is marked as crashed and should be repaired", "Table '%-.64s' is marked as crashed and last (automatic?) repair failed", "Warning: Some non-transactional changed tables couldn't be rolled back", @@ -227,4 +227,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 38877371243..4a3305d0cb7 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -149,7 +149,7 @@ "%-.16s parancs a '%-.32s@%-.64s' felhasznalo szamara nem engedelyezett a '%-.64s' mezo eseten a '%-.64s' tablaban", "Ervenytelen GRANT/REVOKE parancs. Kerem, nezze meg a kezikonyvben, milyen jogok lehetsegesek", "A host vagy felhasznalo argumentuma tul hosszu a GRANT parancsban", -"A '%-64s.%s' tabla nem letezik", +"A '%-.64s.%s' tabla nem letezik", "A '%-.32s' felhasznalo szamara a '%-.64s' host '%-.64s' tablajaban ez a parancs nem engedelyezett", "A hasznalt parancs nem engedelyezett ebben a MySQL verzioban", "Szintaktikai hiba", @@ -196,7 +196,7 @@ "Net error writing to master", "Can't find FULLTEXT index matching the column list", "Can't execute the given command because you have active locked tables or an active transaction", -"Unknown system variable '%-.64'", +"Unknown system variable '%-.64s'", "Table '%-.64s' is marked as crashed and should be repaired", "Table '%-.64s' is marked as crashed and last (automatic?) repair failed", "Warning: Some non-transactional changed tables couldn't be rolled back", @@ -229,4 +229,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index e8cfd5a63a9..8384fc63de4 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -147,7 +147,7 @@ "Comando %-.16s negato per l'utente: '%-.32s@%-.64s' sulla colonna '%-.64s' della tabella '%-.64s'", "Comando GRANT/REVOKE illegale. Prego consultare il manuale per sapere quali privilegi possono essere usati.", "L'argomento host o utente per la GRANT e` troppo lungo", -"La tabella '%-64s.%s' non esiste", +"La tabella '%-.64s.%s' non esiste", "GRANT non definita per l'utente '%-.32s' dalla macchina '%-.64s' sulla tabella '%-.64s'", "Il comando utilizzato non e` supportato in questa versione di MySQL", "Errore di sintassi nella query SQL", @@ -194,7 +194,7 @@ "Errore di rete durante l'invio al master", "Impossibile trovare un indice FULLTEXT che corrisponda all'elenco delle colonne", "Impossibile eseguire il comando richiesto: tabelle sotto lock o transazione in atto", -"Variabile di sistema '%-.64' sconosciuta", +"Variabile di sistema '%-.64s' sconosciuta", "La tabella '%-.64s' e` segnalata come corrotta e deve essere riparata", "La tabella '%-.64s' e` segnalata come corrotta e l'ultima ricostruzione (automatica?) e` fallita", "Attenzione: Alcune delle modifiche alle tabelle non transazionali non possono essere ripristinate (roll back impossibile)", @@ -209,16 +209,16 @@ "E' scaduto il timeout per l'attesa del lock", "Il numero totale di lock e' maggiore della grandezza della tabella di lock", "I lock di aggiornamento non possono essere acquisiti durante una transazione 'READ UNCOMMITTED'", -"DROP DATABASE not allowed while thread is holding global read lock", -"CREATE DATABASE not allowed while thread is holding global read lock", -"Wrong arguments to %s", -"%-.32s@%-.64s is not allowed to create new users", -"Incorrect table definition; All MERGE tables must be in the same database", -"Deadlock found when trying to get lock; Try restarting transaction", -"The used table type doesn't support FULLTEXT indexes", -"Cannot add foreign key constraint", -"Cannot add a child row: a foreign key constraint fails", -"Cannot delete a parent row: a foreign key constraint fails", +"DROP DATABASE non e' permesso mentre il thread ha un lock globale di lettura", +"CREATE DATABASE non e' permesso mentre il thread ha un lock globale di lettura", +"Argomenti errati a %s", +"A %-.32s@%-.64s non e' permesso creare nuovi utenti", +"Definizione della tabella errata; tutte le tabelle di tipo MERGE devono essere nello stesso database", +"Trovato deadlock durante il lock; Provare a far ripartire la transazione", +"La tabella usata non supporta gli indici FULLTEXT", +"Impossibile aggiungere il vincolo di integrita' referenziale (foreign key constraint)", +"Impossibile aggiungere la riga: un vincolo d'integrita' referenziale non e' soddisfatto", +"Impossibile cancellare la riga: un vincolo d'integrita' referenziale non e' soddisfatto", "Error connecting to master: %-.128s", "Error running query on master: %-.128s", "Error when executing command %s: %-.128s", @@ -227,4 +227,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 98bc099954f..94428fcff4d 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -149,7 +149,7 @@ "¥³¥Þ¥ó¥É %-.16s ¤Ï ¥æ¡¼¥¶¡¼ '%-.32s@%-.64s'\n ¥«¥é¥à '%-.64s' ¥Æ¡¼¥Ö¥ë '%-.64s' ¤ËÂФ·¤Æµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó", "Illegal GRANT/REVOKE command. Please consult the manual which privleges can be used.", "The host or user argument to GRANT is too long", -"Table '%-64s.%s' doesn't exist", +"Table '%-.64s.%s' doesn't exist", "There is no such grant defined for user '%-.32s' on host '%-.64s' on table '%-.64s'", "The used command is not allowed with this MySQL version", "Something is wrong in your syntax", @@ -196,7 +196,7 @@ "Net error writing to master", "Can't find FULLTEXT index matching the column list", "Can't execute the given command because you have active locked tables or an active transaction", -"Unknown system variable '%-.64'", +"Unknown system variable '%-.64s'", "Table '%-.64s' is marked as crashed and should be repaired", "Table '%-.64s' is marked as crashed and last (automatic?) repair failed", "Warning: Some non-transactional changed tables couldn't be rolled back", @@ -229,4 +229,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index f6cc890cb39..e3c71032649 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -147,7 +147,7 @@ "'%-.16s' ¸í·ÉÀº ´ÙÀ½ »ç¿ëÀÚ¿¡°Ô °ÅºÎµÇ¾ú½À´Ï´Ù. : '%-.32s@%-.64s' for Ä®·³ '%-.64s' in Å×À̺í '%-.64s'", "À߸øµÈ GRANT/REVOKE ¸í·É. ¾î¶² ±Ç¸®¿Í ½ÂÀÎÀÌ »ç¿ëµÇ¾î Áú ¼ö ÀÖ´ÂÁö ¸Þ´º¾óÀ» º¸½Ã¿À.", "½ÂÀÎ(GRANT)À» À§ÇÏ¿© »ç¿ëÇÑ »ç¿ëÀÚ³ª È£½ºÆ®ÀÇ °ªµéÀÌ ³Ê¹« ±é´Ï´Ù.", -"Å×À̺í '%-64s.%s' ´Â Á¸ÀçÇÏÁö ¾Ê½À´Ï´Ù.", +"Å×À̺í '%-.64s.%s' ´Â Á¸ÀçÇÏÁö ¾Ê½À´Ï´Ù.", "»ç¿ëÀÚ '%-.32s'(È£½ºÆ® '%-.64s')´Â Å×À̺í '%-.64s'¸¦ »ç¿ëÇϱâ À§ÇÏ¿© Á¤ÀÇµÈ ½ÂÀÎÀº ¾ø½À´Ï´Ù. ", "»ç¿ëµÈ ¸í·ÉÀº ÇöÀçÀÇ MySQL ¹öÁ¯¿¡¼´Â ÀÌ¿ëµÇÁö ¾Ê½À´Ï´Ù.", "SQL ±¸¹®¿¡ ¿À·ù°¡ ÀÖ½À´Ï´Ù.", @@ -194,7 +194,7 @@ "Net error writing to master", "Can't find FULLTEXT index matching the column list", "Can't execute the given command because you have active locked tables or an active transaction", -"Unknown system variable '%-.64'", +"Unknown system variable '%-.64s'", "Table '%-.64s' is marked as crashed and should be repaired", "Table '%-.64s' is marked as crashed and last (automatic?) repair failed", "Warning: Some non-transactional changed tables couldn't be rolled back", @@ -227,4 +227,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index adffc27949f..167d39b4494 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -149,7 +149,7 @@ "%-.16s command denied to user: '%-.32s@%-.64s' for column '%-.64s' in table '%-.64s'", "Illegal GRANT/REVOKE command. Please consult the manual which privleges can be used.", "The host or user argument to GRANT is too long", -"Table '%-64s.%s' doesn't exist", +"Table '%-.64s.%s' doesn't exist", "There is no such grant defined for user '%-.32s' on host '%-.64s' on table '%-.64s'", "The used command is not allowed with this MySQL version", "Something is wrong in your syntax", @@ -196,7 +196,7 @@ "Net error writing to master", "Can't find FULLTEXT index matching the column list", "Can't execute the given command because you have active locked tables or an active transaction", -"Unknown system variable '%-.64'", +"Unknown system variable '%-.64s'", "Table '%-.64s' is marked as crashed and should be repaired", "Table '%-.64s' is marked as crashed and last (automatic?) repair failed", "Warning: Some non-transactional changed tables couldn't be rolled back", @@ -229,4 +229,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 09a1ea4684c..bc3f3005912 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -149,7 +149,7 @@ "%-.16s command denied to user: '%-.32s@%-.64s' for column '%-.64s' in table '%-.64s'", "Illegal GRANT/REVOKE command. Please consult the manual which privleges can be used.", "The host or user argument to GRANT is too long", -"Table '%-64s.%s' doesn't exist", +"Table '%-.64s.%s' doesn't exist", "There is no such grant defined for user '%-.32s' on host '%-.64s' on table '%-.64s'", "The used command is not allowed with this MySQL version", "Something is wrong in your syntax", @@ -196,7 +196,7 @@ "Net error writing to master", "Can't find FULLTEXT index matching the column list", "Can't execute the given command because you have active locked tables or an active transaction", -"Unknown system variable '%-.64'", +"Unknown system variable '%-.64s'", "Table '%-.64s' is marked as crashed and should be repaired", "Table '%-.64s' is marked as crashed and last (automatic?) repair failed", "Warning: Some non-transactional changed tables couldn't be rolled back", @@ -229,4 +229,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 12a9bd358b5..bd9d974cc82 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -151,7 +151,7 @@ "%-.16s command denied to user: '%-.32s@%-.64s' for column '%-.64s' in table '%-.64s'", "Illegal GRANT/REVOKE command. Please consult the manual which privleges can be used.", "The host or user argument to GRANT is too long", -"Table '%-64s.%s' doesn't exist", +"Table '%-.64s.%s' doesn't exist", "There is no such grant defined for user '%-.32s' on host '%-.64s' on table '%-.64s'", "The used command is not allowed with this MySQL version", "Something is wrong in your syntax", @@ -198,7 +198,7 @@ "Net error writing to master", "Can't find FULLTEXT index matching the column list", "Can't execute the given command because you have active locked tables or an active transaction", -"Unknown system variable '%-.64'", +"Unknown system variable '%-.64s'", "Table '%-.64s' is marked as crashed and should be repaired", "Table '%-.64s' is marked as crashed and last (automatic?) repair failed", "Warning: Some non-transactional changed tables couldn't be rolled back", @@ -231,4 +231,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index b7feb0a7b0d..36c425863cc 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -194,7 +194,7 @@ "Erro de rede na gravação do 'master'", "Não pode encontrar índice FULLTEXT que combine com a lista de colunas", "Não pode executar o comando dado porque você tem tabelas ativas travadas ou uma 'transaction' ativa", -"Variável de sistema '%-.64' desconhecida", +"Variável de sistema '%-.64s' desconhecida", "Tabela '%-.64s' está marcada como danificada e deve ser reparada", "Tabela '%-.64s' está marcada como danificada e a última reparação (automática?) falhou", "Aviso: Algumas tabelas não-transacionais alteradas não puderam ser reconstituídas ('rolled back')", @@ -227,4 +227,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 8e48cabfc39..262c2e3e955 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -198,7 +198,7 @@ "Net error writing to master", "Can't find FULLTEXT index matching the column list", "Can't execute the given command because you have active locked tables or an active transaction", -"Unknown system variable '%-.64'", +"Unknown system variable '%-.64s'", "Table '%-.64s' is marked as crashed and should be repaired", "Table '%-.64s' is marked as crashed and last (automatic?) repair failed", "Warning: Some non-transactional changed tables couldn't be rolled back", @@ -231,4 +231,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 8ed33ec21a0..140434757c2 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -197,7 +197,7 @@ "óÅÔÅ×ÁÑ ÏÛÉÂËÁ ÐÒÉ ÐÉÓÁÎÉÉ ÍÁÓÔÅÒÕ", "FULLTEXT ÉÎÄÅËÓ, ÓÏÏÔ×ÅÔÓÔ×ÕÀÝÉÊ ÚÁÄÁÎÎÏÍÕ ÓÐÉÓËÕ ÓÔÏÌÂÃÏ×, ÎÅ ÎÁÊÄÅÎ", "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ ËÏÍÍÁÎÄÕ ÉÚ-ÚÁ ÁËÔÉ×ÎÙÈ locked ÔÁÂÌÉà ÉÌÉ ÁËÔÉ×ÎÏÊ ÔÒÁÎÚÁËÃÉÉ", -"îÅÉÚ×ÅÓÔÎÁÑ ÓÉÓÔÅÍÎÁÑ ÐÅÒÅÍÅÎÎÁÑ '%-.64'", +"îÅÉÚ×ÅÓÔÎÁÑ ÓÉÓÔÅÍÎÁÑ ÐÅÒÅÍÅÎÎÁÑ '%-.64s'", "ôÁÂÌÉÃÁ '%-.64s' ÐÏÍÅÞÅÎÁ ËÁË ÉÓÐÏÒÞÅÎÎÁÑ É ÄÏÌÖÎÁ ÂÙÔØ ÉÓÐÒÁ×ÌÅÎÁ", "ôÁÂÌÉÃÁ '%-.64s' ÐÏÍÅÞÅÎÁ ËÁË ÉÓÐÏÒÞÅÎÎÁÑ É ÐÏÓÌÅÄÎÑÑ ÐÏÐÙÔËÁ ÉÓÐÒÁ×ÌÅÎÉÑ (Á×ÔÏÍÁÔÉÞÅÓËÁÑ?) ÎÅ ÕÄÁÌÁÓØ", "ðÒÅÄÕÐÒÅÖÄÅÎÉÅ: ÎÅËÏÔÏÒÙÅ ÎÅÔÒÁÎÚÁËÃÉÏÎÎÙÅ ÔÁÂÌÉÃÙ ÎÅ ÐÏÄÞÉÎÑÀÔÓÑ ROLLBACK", @@ -230,4 +230,6 @@ "îÅ×ÏÚÍÏÖÎÏ ×ÙÐÏÌÎÉÔØ ÚÁÐÒÏÓ ÉÚ-ÚÁ ËÏÎÆÌÉËÔÎÏÊ ÂÌÏËÉÒÏ×ËÉ ÞÔÅÎÉÑ", "ïÄÎÏ×ÒÅÍÅÎÎÏÅ ÉÓÐÏÌØÚÏ×ÁÎÉÅ transactional É non-transactional ÔÁÂÌÉà ÏÔËÌÀÞÅÎÏ", "ïÐÃÉÑ '%s' ÉÓÐÏÌØÚÏ×ÁÎÁ Ä×ÁÖÄÙ", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 105860f0e4b..1b9ffe755f1 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -233,4 +233,6 @@ "Ne mogu da izvršim upit zbog toga što imate zakljuèavanja èitanja podataka u konfliktu", "Mešanje tabela koje podržavaju transakcije i onih koje ne podržavaju transakcije je iskljuèeno", "Opcija '%s' je upotrebljena dva puta u istom iskazu", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 06503cdf69e..70fd615e5f2 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -155,7 +155,7 @@ "%-.16s command denied to user: '%-.32s@%-.64s' for column '%-.64s' in table '%-.64s'", "Illegal GRANT/REVOKE command. Please consult the manual which privleges can be used.", "The host or user argument to GRANT is too long", -"Table '%-64s.%s' doesn't exist", +"Table '%-.64s.%s' doesn't exist", "There is no such grant defined for user '%-.32s' on host '%-.64s' on table '%-.64s'", "The used command is not allowed with this MySQL version", "Something is wrong in your syntax", @@ -202,7 +202,7 @@ "Net error writing to master", "Can't find FULLTEXT index matching the column list", "Can't execute the given command because you have active locked tables or an active transaction", -"Unknown system variable '%-.64'", +"Unknown system variable '%-.64s'", "Table '%-.64s' is marked as crashed and should be repaired", "Table '%-.64s' is marked as crashed and last (automatic?) repair failed", "Warning: Some non-transactional changed tables couldn't be rolled back", @@ -235,4 +235,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 4240581c5b8..fa02414902e 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -148,7 +148,7 @@ "%-.16s comando negado para usuario: '%-.32s@%-.64s' para columna '%-.64s' en la tabla '%-.64s'", "Ilegal comando GRANT/REVOKE. Por favor consulte el manual para cuales permisos pueden ser usados.", "El argumento para servidor o usuario para GRANT es demasiado grande", -"Tabla '%-64s.%s' no existe", +"Tabla '%-.64s.%s' no existe", "No existe tal permiso definido para usuario '%-.32s' en el servidor '%-.64s' en la tabla '%-.64s'", "El comando usado no es permitido con esta versión de MySQL", "Algo está equivocado en su sintax", @@ -195,7 +195,7 @@ "Error de red escribiendo para el master", "No puedo encontrar índice FULLTEXT correspondiendo a la lista de columnas", "No puedo ejecutar el comando dado porque tienes tablas bloqueadas o una transición activa", -"Desconocida variable de sistema '%-.64'", +"Desconocida variable de sistema '%-.64s'", "Tabla '%-.64s' está marcada como crashed y debe ser reparada", "Tabla '%-.64s' está marcada como crashed y la última reparación (automactica?) falló", "Aviso: Algunas tablas no transancionales no pueden tener rolled back", @@ -228,4 +228,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index e774f4a2c5c..0198a722662 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -61,7 +61,7 @@ "Kommandot har både sum functions och enkla funktioner", "Antalet kolumner motsvarar inte antalet värden", "Kolumn namn '%-.64s' är för långt", -"Kolumn namn '%-64s finns flera gånger", +"Kolumn namn '%-.64s finns flera gånger", "Nyckel namn '%-.64s' finns flera gånger", "Dubbel nyckel '%-.64s' för nyckel: %d", "Felaktigt kolumn typ för kolumn: '%-.64s'", @@ -147,7 +147,7 @@ "%-.16s ej tillåtet för '%-.32s@%-.64s'\n för kolumn '%-.64s' i tabell '%-.64s'", "Felaktigt GRANT privilegium använt", "Felaktigt maskinnamn eller användarnamn använt med GRANT", -"Det finns ingen tabell som heter '%-64s.%s'" +"Det finns ingen tabell som heter '%-.64s.%s'" "Det finns inget privilegium definierat för användare '%-.32s' på '%-.64s' för tabell '%-.64s'", "Du kan inte använda detta kommando med denna MySQL version", "Du har något fel i din syntax", @@ -194,7 +194,7 @@ "Fick nätverksfel vid skrivning till master", "Hittar inte ett FULLTEXT index i kolumnlistan", "Kan inte exekvera kommandot emedan du har en låst tabell eller an aktiv transaktion", -"Okänd system variabel '%-.64'", +"Okänd system variabel '%-.64s'", "Tabell '%-.64s' är crashad och bör repareras med REPAIR TABLE", "Tabell '%-.64s' är crashad och senast (automatiska?) reparation misslyckades", "Warning: Några icke transaktionella tabeller kunde inte återställas vid ROLLBACK", @@ -227,4 +227,6 @@ "Kan inte utföra kommandot emedan du har ett READ lås", "Blandning av transaktionella och icke-transaktionella tabeller är inaktiverat", "Option '%s' användes två gånger", -"Användare '%-64s' har överskridit '%s' (nuvarande värde: %ld)", +"Användare '%-.64s' har överskridit '%s' (nuvarande värde: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index c4c89433331..2354f0a9687 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -199,7 +199,7 @@ "íÅÒÅÖÅ×Á ÐÏÍÉÌËÁ ÚÁÐÉÓÕ ÄÏ ÇÏÌÏ×ÎÏÇÏ", "îÅ ÍÏÖÕ ÚÎÁÊÔÉ FULLTEXT ¦ÎÄÅËÓ, ÝÏ ×¦ÄÐÏצÄÁ¤ ÐÅÒÅ̦ËÕ ÓÔÏ×Âæ×", "îÅ ÍÏÖÕ ×ÉËÏÎÁÔÉ ÐÏÄÁÎÕ ËÏÍÁÎÄÕ ÔÏÍÕ, ÝÏ ÔÁÂÌÉÃÑ ÚÁÂÌÏËÏ×ÁÎÁ ÁÂÏ ×ÉËÏÎÕ¤ÔØÓÑ ÔÒÁÎÚÁËæÑ", -"îÅצÄÏÍÁ ÓÉÓÔÅÍÎÁ ÚͦÎÎÁ '%-.64'", +"îÅצÄÏÍÁ ÓÉÓÔÅÍÎÁ ÚͦÎÎÁ '%-.64s'", "ôÁÂÌÉÃÀ '%-.64s' ÍÁÒËÏ×ÁÎÏ ÑË Ú¦ÐÓÏ×ÁÎÕ ÔÁ §§ ÐÏÔÒ¦ÂÎÏ ×¦ÄÎÏ×ÉÔÉ", "ôÁÂÌÉÃÀ '%-.64s' ÍÁÒËÏ×ÁÎÏ ÑË Ú¦ÐÓÏ×ÁÎÕ ÔÁ ÏÓÔÁÎΤ (Á×ÔÏÍÁÔÉÞÎÅ?) צÄÎÏ×ÌÅÎÎÑ ÎÅ ×ÄÁÌÏÓÑ", "úÁÓÔÅÒÅÖÅÎÎÑ: äÅÑ˦ ÎÅÔÒÁÎÚÁËæÊΦ ÚͦÎÉ ÔÁÂÌÉÃØ ÎÅ ÍÏÖÎÁ ÂÕÄÅ ÐÏ×ÅÒÎÕÔÉ", @@ -232,4 +232,6 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", -"User '%-64s' has exceeded the '%s' resource (current value: %ld)", +"User '%-.64s' has exceeded the '%s' resource (current value: %ld)", +"Wrong foreign key definition for '%-.64s': %s", +"Key reference and table reference doesn't match", diff --git a/sql/slave.cc b/sql/slave.cc index 8461b72f4c6..2673644b65a 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -48,12 +48,10 @@ ulong relay_log_space_limit = 0; /* TODO: fix variables to access ulonglong // can re-use them on slave start // TODO: move the vars below under MASTER_INFO -#ifndef DBUG_OFF int disconnect_slave_event_count = 0, abort_slave_event_count = 0; static int events_till_disconnect = -1; int events_till_abort = -1; static int stuck_count = 0; -#endif typedef enum { SLAVE_THD_IO, SLAVE_THD_SQL} SLAVE_THD_TYPE; @@ -191,11 +189,22 @@ int init_relay_log_pos(RELAY_LOG_INFO* rli,const char* log, pos = rli->relay_log_pos; // already inited else rli->relay_log_pos = pos; - if (rli->relay_log.find_first_log(&rli->linfo,log)) + + // test to see if the previous run was with the skip of purging + // if yes, we do not purge when we restart + if (rli->relay_log.find_first_log(&rli->linfo,"")) { *errmsg="Could not find first log during relay log initialization"; goto err; } + if (strcmp(log,rli->linfo.log_file_name)) + rli->skip_log_purge=1; + + if (rli->relay_log.find_first_log(&rli->linfo,log)) + { + *errmsg="Could not find target log during relay log initialization"; + goto err; + } strnmov(rli->relay_log_name,rli->linfo.log_file_name, sizeof(rli->relay_log_name)); // to make end_io_cache(&rli->cache_buf) safe in all cases @@ -235,9 +244,10 @@ err: } /* called from get_options() in mysqld.cc on start-up */ -void init_slave_skip_errors(char* arg) + +void init_slave_skip_errors(const char* arg) { - char* p; + const char *p; my_bool last_was_digit = 0; if (bitmap_init(&slave_error_mask,MAX_SLAVE_ERROR,0)) { @@ -264,8 +274,11 @@ void init_slave_skip_errors(char* arg) } } -// we assume we have a run lock on rli and that the both slave thread -// are not running +/* + We assume we have a run lock on rli and that the both slave thread + are not running +*/ + int purge_relay_logs(RELAY_LOG_INFO* rli, bool just_reset, const char** errmsg) { DBUG_ENTER("purge_relay_logs"); @@ -503,7 +516,7 @@ void init_table_rule_hash(HASH* h, bool* h_inited) void init_table_rule_array(DYNAMIC_ARRAY* a, bool* a_inited) { - init_dynamic_array(a, sizeof(TABLE_RULE_ENT*), TABLE_RULE_ARR_SIZE, + my_init_dynamic_array(a, sizeof(TABLE_RULE_ENT*), TABLE_RULE_ARR_SIZE, TABLE_RULE_ARR_SIZE); *a_inited = 1; } @@ -1104,14 +1117,17 @@ static inline int add_relay_log(RELAY_LOG_INFO* rli,LOG_INFO* linfo) static bool wait_for_relay_log_space(RELAY_LOG_INFO* rli) { - bool slave_killed; + bool slave_killed=0; MASTER_INFO* mi = rli->mi; const char* save_proc_info; THD* thd = mi->io_thd; + DBUG_ENTER("wait_for_relay_log_space"); + pthread_mutex_lock(&rli->log_space_lock); save_proc_info = thd->proc_info; thd->proc_info = "Waiting for relay log space to free"; + while (rli->log_space_limit < rli->log_space_total && !(slave_killed=io_slave_killed(thd,mi))) { @@ -1557,9 +1573,6 @@ command"); static ulong read_event(MYSQL* mysql, MASTER_INFO *mi) { ulong len = packet_error; - // for convinience lets think we start by - // being in the interrupted state :-) - int read_errno = EINTR; // my_real_read() will time us out // we check if we were told to die, and if not, try reading again @@ -1568,27 +1581,21 @@ static ulong read_event(MYSQL* mysql, MASTER_INFO *mi) return packet_error; #endif - while (!abort_loop && !mi->abort_slave && len == packet_error && - read_errno == EINTR ) - { - len = mc_net_safe_read(mysql); - read_errno = errno; - } - if (abort_loop || mi->abort_slave) - return packet_error; + len = mc_net_safe_read(mysql); + if (len == packet_error || (long) len < 1) { - sql_print_error("Error reading packet from server: %s (read_errno %d,\ + sql_print_error("Error reading packet from server: %s (\ server_errno=%d)", - mc_mysql_error(mysql), read_errno, mc_mysql_errno(mysql)); + mc_mysql_error(mysql), mc_mysql_errno(mysql)); return packet_error; } if (len == 1) { sql_print_error("Slave: received 0 length packet from server, apparent\ - master shutdown: %s (%d)", - mc_mysql_error(mysql), read_errno); + master shutdown: %s", + mc_mysql_error(mysql)); return packet_error; } @@ -2498,6 +2505,15 @@ Log_event* next_event(RELAY_LOG_INFO* rli) return ev; } DBUG_ASSERT(thd==rli->sql_thd); + if (opt_reckless_slave) + cur_log->error = 0; + if ( cur_log->error < 0) + { + errmsg = "slave SQL thread aborted because of I/O error"; + goto err; + } + + if (!cur_log->error) /* EOF */ { /* @@ -2560,6 +2576,7 @@ Log_event* next_event(RELAY_LOG_INFO* rli) goto err; } rli->relay_log_pos = 4; + rli->pending=0; strnmov(rli->relay_log_name,rli->linfo.log_file_name, sizeof(rli->relay_log_name)); flush_relay_log_info(rli); @@ -2606,12 +2623,12 @@ event(errno=%d,cur_log->error=%d)", my_errno,cur_log->error); // set read position to the beginning of the event my_b_seek(cur_log,rli->relay_log_pos+rli->pending); - // no need to hog the mutex while we sleep - pthread_mutex_unlock(&rli->data_lock); - safe_sleep(rli->sql_thd,1,(CHECK_KILLED_FUNC)sql_slave_killed, - (void*)rli); - pthread_mutex_lock(&rli->data_lock); + /* otherwise, we have had a partial read */ + /* TODO; see if there is a way to do this without this goto */ + errmsg = "Aborting slave SQL thread because of partial event read"; + goto err; } + } if (!errmsg && was_killed) errmsg = "slave SQL thread was killed"; diff --git a/sql/slave.h b/sql/slave.h index 354fc46e99d..16735891815 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -30,7 +30,7 @@ extern bool use_slave_mask; extern char* slave_load_tmpdir; extern my_string master_info_file,relay_log_info_file; extern my_string opt_relay_logname, opt_relaylog_index_name; -extern bool opt_skip_slave_start; +extern bool opt_skip_slave_start, opt_reckless_slave; extern ulong relay_log_space_limit; struct st_master_info; @@ -160,6 +160,7 @@ typedef struct st_relay_log_info st_relay_log_info():info_fd(-1),cur_log_fd(-1),inited(0), cur_log_init_count(0), + abort_slave(0),slave_running(0), log_pos_current(0),abort_pos_wait(0), skip_log_purge(0) { @@ -280,7 +281,8 @@ typedef struct st_master_info bool ignore_stop_event; - st_master_info():fd(-1), io_thd(0), inited(0), old_format(0) + st_master_info():fd(-1), io_thd(0), inited(0), old_format(0),abort_slave(0), + slave_running(0) { host[0] = 0; user[0] = 0; password[0] = 0; bzero(&file,sizeof(file)); @@ -331,7 +333,7 @@ typedef struct st_table_rule_ent #define SLAVE_FORCE_ALL 4 int init_slave(); -void init_slave_skip_errors(char* arg); +void init_slave_skip_errors(const char* arg); int flush_master_info(MASTER_INFO* mi); int flush_relay_log_info(RELAY_LOG_INFO* rli); int register_slave_on_master(MYSQL* mysql); @@ -413,9 +415,7 @@ extern bool do_table_inited, ignore_table_inited, wild_do_table_inited, wild_ignore_table_inited; extern bool table_rules_on; -#ifndef DBUG_OFF extern int disconnect_slave_event_count, abort_slave_event_count ; -#endif // the master variables are defaults read from my.cnf or command line extern uint master_port, master_connect_retry, report_port; diff --git a/sql/spatial.h b/sql/spatial.h index 09e8722a85e..2daa8e856c9 100644 --- a/sql/spatial.h +++ b/sql/spatial.h @@ -3,8 +3,8 @@ #include "gstream.h" -const int POINT_DATA_SIZE = 8+8; -const int WKB_HEADER_SIZE = 1+4; +const uint POINT_DATA_SIZE = 8+8; +const uint WKB_HEADER_SIZE = 1+4; struct stPoint2D { diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index f8f13c35e35..724af69bdca 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -58,7 +58,8 @@ class ACL_USER :public ACL_ACCESS { public: acl_host_and_ip host; - uint hostname_length, questions, updates; + uint hostname_length; + USER_RESOURCES user_resource; char *user,*password; ulong salt[2]; #ifdef HAVE_OPENSSL @@ -110,6 +111,32 @@ static void update_hostname(acl_host_and_ip *host, const char *hostname); static bool compare_hostname(const acl_host_and_ip *host, const char *hostname, const char *ip); +extern char uc_update_queries[SQLCOM_END]; + +static void init_update_queries(void) +{ + uc_update_queries[SQLCOM_CREATE_TABLE]=1; + uc_update_queries[SQLCOM_CREATE_INDEX]=1; + uc_update_queries[SQLCOM_ALTER_TABLE]=1; + uc_update_queries[SQLCOM_UPDATE]=1; + uc_update_queries[SQLCOM_INSERT]=1; + uc_update_queries[SQLCOM_INSERT_SELECT]=1; + uc_update_queries[SQLCOM_DELETE]=1; + uc_update_queries[SQLCOM_TRUNCATE]=1; + uc_update_queries[SQLCOM_DROP_TABLE]=1; + uc_update_queries[SQLCOM_LOAD]=1; + uc_update_queries[SQLCOM_CREATE_DB]=1; + uc_update_queries[SQLCOM_DROP_DB]=1; + uc_update_queries[SQLCOM_REPLACE]=1; + uc_update_queries[SQLCOM_REPLACE_SELECT]=1; + uc_update_queries[SQLCOM_RENAME_TABLE]=1; + uc_update_queries[SQLCOM_BACKUP_TABLE]=1; + uc_update_queries[SQLCOM_RESTORE_TABLE]=1; + uc_update_queries[SQLCOM_DELETE_MULTI]=1; + uc_update_queries[SQLCOM_DROP_INDEX]=1; + uc_update_queries[SQLCOM_MULTI_UPDATE]=1; +} + int acl_init(bool dont_read_acl_tables) { THD *thd; @@ -163,7 +190,7 @@ int acl_init(bool dont_read_acl_tables) init_sql_alloc(&mem,1024,0); init_read_record(&read_record_info,thd,table= tables[0].table,NULL,1,0); - VOID(init_dynamic_array(&acl_hosts,sizeof(ACL_HOST),20,50)); + VOID(my_init_dynamic_array(&acl_hosts,sizeof(ACL_HOST),20,50)); while (!(read_record_info.read_record(&read_record_info))) { ACL_HOST host; @@ -187,7 +214,7 @@ int acl_init(bool dont_read_acl_tables) freeze_size(&acl_hosts); init_read_record(&read_record_info,thd,table=tables[1].table,NULL,1,0); - VOID(init_dynamic_array(&acl_users,sizeof(ACL_USER),50,100)); + VOID(my_init_dynamic_array(&acl_users,sizeof(ACL_USER),50,100)); if (table->field[2]->field_length == 8 && protocol_version == PROTOCOL_VERSION) { @@ -247,14 +274,16 @@ int acl_init(bool dont_read_acl_tables) { /* Table has new MySQL usage limits */ char *ptr = get_field(&mem, table, 21); - user.questions=atoi(ptr); + user.user_resource.questions=atoi(ptr); ptr = get_field(&mem, table, 22); - user.updates=atoi(ptr); - if (user.questions) + user.user_resource.updates=atoi(ptr); + ptr = get_field(&mem, table, 23); + user.user_resource.connections=atoi(ptr); + if (user.user_resource.questions || user.user_resource.updates || user.user_resource.connections) mqh_used=1; } else - user.questions=user.updates=0; + bzero(&(user.user_resource),sizeof(user.user_resource)); #ifndef TO_BE_REMOVED if (table->fields <= 13) { // Without grant @@ -273,7 +302,7 @@ int acl_init(bool dont_read_acl_tables) freeze_size(&acl_users); init_read_record(&read_record_info,thd,table=tables[2].table,NULL,1,0); - VOID(init_dynamic_array(&acl_dbs,sizeof(ACL_DB),50,100)); + VOID(my_init_dynamic_array(&acl_dbs,sizeof(ACL_DB),50,100)); while (!(read_record_info.read_record(&read_record_info))) { ACL_DB db; @@ -299,6 +328,7 @@ int acl_init(bool dont_read_acl_tables) init_check_host(); mysql_unlock_tables(thd, lock); + init_update_queries(); thd->version--; // Force close to free memory close_thread_tables(thd); delete thd; @@ -442,13 +472,13 @@ static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b) uint acl_getroot(THD *thd, const char *host, const char *ip, const char *user, const char *password,const char *message,char **priv_user, - bool old_ver, uint *max_questions) + bool old_ver, USER_RESOURCES *mqh) { uint user_access=NO_ACCESS; *priv_user=(char*) user; char *ptr=0; - *max_questions=0; + bzero(mqh,sizeof(USER_RESOURCES)); if (!initialized) return (uint) ~NO_ACCESS; // If no data allow anything /* purecov: tested */ VOID(pthread_mutex_lock(&acl_cache->lock)); @@ -556,7 +586,7 @@ uint acl_getroot(THD *thd, const char *host, const char *ip, const char *user, #else /* HAVE_OPENSSL */ user_access=acl_user->access; #endif /* HAVE_OPENSSL */ - *max_questions=acl_user->questions; + *mqh=acl_user->user_resource; if (!acl_user->user) *priv_user=(char*) ""; // Change to anonymous user /* purecov: inspected */ break; @@ -590,7 +620,7 @@ static void acl_update_user(const char *user, const char *host, const char *ssl_cipher, const char *x509_issuer, const char *x509_subject, - unsigned int mqh, + USER_RESOURCES *mqh, uint privileges) { for (uint i=0 ; i < acl_users.elements ; i++) @@ -604,8 +634,8 @@ static void acl_update_user(const char *user, const char *host, acl_user->host.hostname && !strcmp(host,acl_user->host.hostname)) { acl_user->access=privileges; - acl_user->questions=mqh; -#ifdef HAVE_OPENSSL + acl_user->user_resource=*mqh; +#ifdef HAVE_OPENSSL acl_user->ssl_type=ssl_type; acl_user->ssl_cipher=ssl_cipher; acl_user->x509_issuer=x509_issuer; @@ -634,7 +664,7 @@ static void acl_insert_user(const char *user, const char *host, const char *ssl_cipher, const char *x509_issuer, const char *x509_subject, - unsigned int mqh, + USER_RESOURCES *mqh, uint privileges) { ACL_USER acl_user; @@ -642,7 +672,7 @@ static void acl_insert_user(const char *user, const char *host, update_hostname(&acl_user.host,strdup_root(&mem,host)); acl_user.password=0; acl_user.access=privileges; - acl_user.questions=mqh; + acl_user.user_resource = *mqh; acl_user.sort=get_sort(2,acl_user.host.hostname,acl_user.user); acl_user.hostname_length=(uint) strlen(acl_user.host.hostname); #ifdef HAVE_OPENSSL @@ -847,7 +877,7 @@ int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr) static void init_check_host(void) { DBUG_ENTER("init_check_host"); - VOID(init_dynamic_array(&acl_wild_hosts,sizeof(struct acl_host_and_ip), + VOID(my_init_dynamic_array(&acl_wild_hosts,sizeof(struct acl_host_and_ip), acl_users.elements,1)); VOID(hash_init(&acl_check_hosts,system_charset_info,acl_users.elements,0,0, (hash_get_key) check_get_key,0,HASH_CASE_INSENSITIVE)); @@ -1153,12 +1183,17 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, char *password,empty_string[1]; DBUG_ENTER("replace_user_table"); + password=empty_string; + empty_string[0]=0; + if (combo.password.str && combo.password.str[0]) - password=combo.password.str; - else { - password=empty_string; - empty_string[0]=0; + if (combo.password.length != HASH_PASSWORD_LENGTH) + { + my_error(ER_PASSWORD_NO_MATCH,MYF(0)); + DBUG_RETURN(-1); + } + password=combo.password.str; } table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); @@ -1236,10 +1271,16 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, } } #endif /* HAVE_OPENSSL */ - if (table->fields >= 23 && thd->lex.mqh) + if (table->fields >= 23) { - table->field[21]->store((longlong) thd->lex.mqh); - mqh_used=1; + USER_RESOURCES mqh = thd->lex.mqh; + if (mqh.questions) + table->field[21]->store((longlong) mqh.questions); + if (mqh.updates) + table->field[22]->store((longlong) mqh.updates); + if (mqh.connections) + table->field[23]->store((longlong) mqh.connections); + mqh_used = mqh_used || mqh.questions || mqh.updates || mqh.connections; } if (old_row_exists) { @@ -1279,7 +1320,7 @@ end: thd->lex.ssl_cipher, thd->lex.x509_issuer, thd->lex.x509_subject, - thd->lex.mqh, + &thd->lex.mqh, rights); else acl_insert_user(combo.user.str,combo.host.str,password, @@ -1287,7 +1328,7 @@ end: thd->lex.ssl_cipher, thd->lex.x509_issuer, thd->lex.x509_subject, - thd->lex.mqh, + &thd->lex.mqh, rights); } table->file->index_end(); @@ -2701,11 +2742,25 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) #endif /* HAVE_OPENSSL */ if (want_access & GRANT_ACL) global.append(" WITH GRANT OPTION",18); - else if (acl_user->questions) + if (acl_user->user_resource.questions) { char buff[65], *p; // just as in int2str global.append(" WITH MAX_QUERIES_PER_HOUR = ",29); - p=int2str(acl_user->questions,buff,10); + p=int2str(acl_user->user_resource.questions,buff,10); + global.append(buff,p-buff); + } + if (acl_user->user_resource.updates) + { + char buff[65], *p; // just as in int2str + global.append(" WITH MAX_UPDATES_PER_HOUR = ",29); + p=int2str(acl_user->user_resource.updates,buff,10); + global.append(buff,p-buff); + } + if (acl_user->user_resource.connections) + { + char buff[65], *p; // just as in int2str + global.append(" WITH MAX_CONNECTIONS_PER_HOUR = ",33); + p=int2str(acl_user->user_resource.connections,buff,10); global.append(buff,p-buff); } thd->packet.length(0); @@ -2870,16 +2925,17 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) } -uint get_mqh(const char *user, const char *host) +void get_mqh(const char *user, const char *host, USER_CONN *uc) { - if (!initialized) return 0; - ACL_USER *acl_user; - acl_user= find_acl_user(host,user); - return (acl_user) ? acl_user->questions : 0; + if (initialized && (acl_user= find_acl_user(host,user))) + uc->user_resources= acl_user->user_resource; + else + bzero((char*) &uc->user_resources, sizeof(uc->user_resources)); } + /***************************************************************************** ** Instantiate used templates *****************************************************************************/ diff --git a/sql/sql_acl.h b/sql/sql_acl.h index f118ac17789..9ac3bc6ed74 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -61,7 +61,7 @@ uint acl_get(const char *host, const char *ip, const char *bin_ip, const char *user, const char *db); uint acl_getroot(THD *thd, const char *host, const char *ip, const char *user, const char *password,const char *scramble,char **priv_user, - bool old_ver, uint *max); + bool old_ver, USER_RESOURCES *max); bool acl_check_host(const char *host, const char *ip); bool change_password(THD *thd, const char *host, const char *user, char *password); @@ -82,4 +82,4 @@ bool check_grant_db(THD *thd,const char *db); uint get_table_grant(THD *thd, TABLE_LIST *table); uint get_column_grant(THD *thd, TABLE_LIST *table, Field *field); int mysql_show_grants(THD *thd, LEX_USER *user); -uint get_mqh(const char *user, const char *host); +void get_mqh(const char *user, const char *host, USER_CONN *uc); diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index cc3406d0f54..91d6b967929 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -90,21 +90,21 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result, (*param->item)->val() < 0) { net_printf(&thd->net, ER_WRONG_PARAMETERS_TO_PROCEDURE, proc_name); - return 0; + DBUG_RETURN(0); } pc->max_tree_elements = (uint) (*param->item)->val_int(); param = param->next; if (param->next) // no third parameter possible { net_printf(&thd->net, ER_WRONG_PARAMCOUNT_TO_PROCEDURE, proc_name); - return 0; + DBUG_RETURN(0); } // second parameter if ((*param->item)->type() != Item::INT_ITEM || (*param->item)->val() < 0) { net_printf(&thd->net, ER_WRONG_PARAMETERS_TO_PROCEDURE, proc_name); - return 0; + DBUG_RETURN(0); } pc->max_treemem = (uint) (*param->item)->val_int(); } @@ -112,7 +112,7 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result, (*param->item)->val() < 0) { net_printf(&thd->net, ER_WRONG_PARAMETERS_TO_PROCEDURE, proc_name); - return 0; + DBUG_RETURN(0); } // if only one parameter was given, it will be the value of max_tree_elements else @@ -148,21 +148,26 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result, if (item->result_type() == STRING_RESULT) *f_info++ = new field_str(item, pc); } - return pc; -} // proc_analyse_init + DBUG_RETURN(pc); +} -// return 1 if number, else return 0 -// store info about found number in info -// NOTE:It is expected, that elements of 'info' are all zero! +/* + Return 1 if number, else return 0 + store info about found number in info + NOTE:It is expected, that elements of 'info' are all zero! +*/ + bool test_if_number(NUM_INFO *info, const char *str, uint str_len) { const char *begin, *end = str + str_len; DBUG_ENTER("test_if_number"); - // MySQL removes any endspaces of a string, so we must take care only of - // spaces in front of a string + /* + MySQL removes any endspaces of a string, so we must take care only of + spaces in front of a string + */ for (; str != end && my_isspace(system_charset_info, *str); str++) ; if (str == end) return 0; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 5e3bf90c4a5..c9ef64b6da9 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -196,6 +196,7 @@ send_fields(THD *thd,List<Item> &list,uint flag) Item *item; char buff[80]; CONVERT *convert= (flag & 4) ? (CONVERT*) 0 : thd->convert_set; + DBUG_ENTER("send_fields"); String tmp((char*) buff,sizeof(buff),default_charset_info); String *res,*packet= &thd->packet; @@ -257,11 +258,11 @@ send_fields(THD *thd,List<Item> &list,uint flag) if (my_net_write(&thd->net, (char*) packet->ptr(),packet->length())) break; /* purecov: inspected */ } - send_eof(&thd->net); - return 0; + send_eof(&thd->net,1); + DBUG_RETURN(0); err: send_error(&thd->net,ER_OUT_OF_RESOURCES); /* purecov: inspected */ - return 1; /* purecov: inspected */ + DBUG_RETURN(1); /* purecov: inspected */ } @@ -2050,10 +2051,10 @@ static void mysql_rm_tmp_tables(void) /* -** CREATE INDEX and DROP INDEX are implemented by calling ALTER TABLE with -** the proper arguments. This isn't very fast but it should work for most -** cases. -** One should normally create all indexes with CREATE TABLE or ALTER TABLE. + CREATE INDEX and DROP INDEX are implemented by calling ALTER TABLE with + the proper arguments. This isn't very fast but it should work for most + cases. + One should normally create all indexes with CREATE TABLE or ALTER TABLE. */ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys) @@ -2065,6 +2066,7 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys) DBUG_ENTER("mysql_create_index"); bzero((char*) &create_info,sizeof(create_info)); create_info.db_type=DB_TYPE_DEFAULT; + create_info.table_charset=default_charset_info; DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name, &create_info, table_list, fields, keys, drop, alter, (ORDER*)0, FALSE, @@ -2081,6 +2083,7 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop) DBUG_ENTER("mysql_drop_index"); bzero((char*) &create_info,sizeof(create_info)); create_info.db_type=DB_TYPE_DEFAULT; + create_info.table_charset=default_charset_info; DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name, &create_info, table_list, fields, keys, drop, alter, (ORDER*)0, FALSE, diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index d7549732798..c739b43debb 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -1072,7 +1072,7 @@ void Query_cache::invalidate(CHANGED_TABLE_LIST *tables_used) DUMP(this); for ( ; tables_used; tables_used=tables_used->next) { - invalidate_table(tables_used->key, tables_used->key_length); + invalidate_table((byte*) tables_used->key, tables_used->key_length); DBUG_PRINT("qcache", (" db %s, table %s", tables_used->key, tables_used->table_name)); } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index d5d5c8fa6f9..bcea9d23d14 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -147,7 +147,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), /* Initialize sub structures */ bzero((char*) &mem_root,sizeof(mem_root)); bzero((char*) &transaction.mem_root,sizeof(transaction.mem_root)); - user_connect=(UC *)0; + user_connect=(USER_CONN *)0; hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0, (hash_get_key) get_var_key, (void (*)(void*)) free_var,0); diff --git a/sql/sql_class.h b/sql/sql_class.h index 5dc761ff811..814e0e6fa9a 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -69,11 +69,13 @@ class MYSQL_LOG { char log_file_name[FN_REFLEN],index_file_name[FN_REFLEN]; bool write_error,inited; uint file_id; // current file sequence number for load data infile - // binary logging - bool no_rotate; // for binlog - if log name can never change - // we should not try to rotate it or write any rotation events - // the user should use FLUSH MASTER instead of FLUSH LOGS for - // purging + /* + For binlog - if log name can never change + we should not try to rotate it or write any rotation events + the user should use FLUSH MASTER instead of FLUSH LOGS for + purging + */ + bool no_rotate; enum cache_type io_cache_type; bool need_start_event; pthread_cond_t update_cond; @@ -182,7 +184,7 @@ typedef struct st_copy_info { ha_rows copied; ha_rows error; enum enum_duplicates handle_duplicates; - int escape_char; + int escape_char, errorno; } COPY_INFO; @@ -215,19 +217,40 @@ public: class Key :public Sql_alloc { public: - enum Keytype { PRIMARY, UNIQUE, MULTIPLE, FULLTEXT, SPATIAL }; + enum Keytype { PRIMARY, UNIQUE, MULTIPLE, FULLTEXT, SPATIAL, FOREIGN_KEY}; enum Keytype type; enum ha_key_alg algorithm; List<key_part_spec> columns; - const char *Name; + const char *name; - Key(enum Keytype type_par, enum ha_key_alg alg_par, const char *name_arg, List<key_part_spec> &cols) - :type(type_par), algorithm(alg_par), columns(cols), Name(name_arg) + Key(enum Keytype type_par, const char *name_arg, enum ha_key_alg alg_par, + List<key_part_spec> &cols) + :type(type_par), algorithm(alg_par), columns(cols), name(name_arg) {} ~Key() {} - const char *name() { return Name; } }; +class Table_ident; + +class foreign_key: public Key { +public: + enum fk_match_opt { FK_MATCH_UNDEF, FK_MATCH_FULL, + FK_MATCH_PARTIAL, FK_MATCH_SIMPLE}; + enum fk_option { FK_OPTION_UNDEF, FK_OPTION_RESTRICT, FK_OPTION_CASCADE, + FK_OPTION_SET_NULL, FK_OPTION_NO_ACTION, FK_OPTION_DEFAULT}; + + Table_ident *ref_table; + List<key_part_spec> ref_columns; + uint delete_opt, update_opt, match_opt; + foreign_key(const char *name_arg, List<key_part_spec> &cols, + Table_ident *table, List<key_part_spec> &ref_cols, + uint delete_opt_arg, uint update_opt_arg, uint match_opt_arg) + :Key(FOREIGN_KEY, name_arg, HA_KEY_ALG_UNDEF, cols), + ref_table(table), ref_columns(cols), + delete_opt(delete_opt_arg), update_opt(update_opt_arg), + match_opt(match_opt_arg) + {} +}; typedef struct st_mysql_lock { @@ -247,8 +270,8 @@ public: #include "sql_lex.h" /* Must be here */ -// needed to be able to have an I_List of char* strings.in mysqld.cc where we cannot use String -// because it is Sql_alloc'ed +/* Needed to be able to have an I_List of char* strings in mysqld.cc. */ + class i_string: public ilink { public: @@ -257,7 +280,7 @@ public: i_string(char* s) : ptr(s) {} }; -//needed for linked list of two strings for replicate-rewrite-db +/* needed for linked list of two strings for replicate-rewrite-db */ class i_string_pair: public ilink { public: @@ -275,39 +298,42 @@ class delayed_insert; #define THD_CHECK_SENTRY(thd) DBUG_ASSERT(thd->dbug_sentry == THD_SENTRY_MAGIC) -/* For each client connection we create a separate thread with THD serving as - a thread/connection descriptor */ +/* + For each client connection we create a separate thread with THD serving as + a thread/connection descriptor. +*/ class THD :public ilink { public: - NET net; // client connection descriptor - LEX lex; // parse tree descriptor - MEM_ROOT mem_root; // 1 command-life memory allocation pool - HASH user_vars; // hash for user variables - String packet; // dynamic string buffer used for network I/O - struct sockaddr_in remote; // client socket address - struct rand_struct rand; // used for authentication + NET net; // client connection descriptor + LEX lex; // parse tree descriptor + MEM_ROOT mem_root; // 1 command-life memory + HASH user_vars; // hash for user variables + String packet; // buffer used for network I/O + struct sockaddr_in remote; // client socket address + struct rand_struct rand; // used for authentication - /* query points to the current query, - thread_stack is a pointer to the stack frame of handle_one_connection(), - which is called first in the thread for handling a client - */ + /* + Query points to the current query, + thread_stack is a pointer to the stack frame of handle_one_connection(), + which is called first in the thread for handling a client + */ char *query,*thread_stack; /* host - host of the client user - user of the client, set to NULL until the user has been read from the connection - priv_user - not sure why we have it, but it is set to "boot" when we run - with --bootstrap + priv_user - The user privilege we are using. May be '' for anonymous user. db - currently selected database ip - client IP */ char *host,*user,*priv_user,*db,*ip; - /* proc_info points to a string that will show in the Info column of - SHOW PROCESSLIST output - host_or_ip points to host if host is available, otherwise points to ip - */ + /* + Proc_info points to a string that will show in the Info column of + SHOW PROCESSLIST output + host_or_ip points to host if host is available, otherwise points to ip + */ const char *proc_info, *host_or_ip; /* @@ -334,7 +360,8 @@ public: */ TABLE *open_tables,*temporary_tables, *handler_tables; // TODO: document the variables below - MYSQL_LOCK *lock,*locked_tables; + MYSQL_LOCK *lock; /* Current locks */ + MYSQL_LOCK *locked_tables; /* Tables locked with LOCK */ ULL *ull; #ifndef DBUG_OFF uint dbug_sentry; // watch out for memory corruption @@ -382,7 +409,7 @@ public: ha_rows select_limit,offset_limit,default_select_limit,cuted_fields, max_join_size, sent_row_count, examined_row_count; table_map used_tables; - UC *user_connect; + USER_CONN *user_connect; ulong query_id,version, inactive_timeout,options,thread_id; long dbug_thread_id; pthread_t real_id; @@ -538,7 +565,7 @@ public: #include "log_event.h" /* -** This is used to get result from a select + This is used to get result from a select */ class JOIN; @@ -666,6 +693,7 @@ class select_union :public select_result { TABLE *table; COPY_INFO info; uint save_time_stamp; + TMP_TABLE_PARAM *tmp_table_param; select_union(TABLE *table_par); ~select_union(); @@ -787,7 +815,6 @@ public: class multi_update : public select_result { TABLE_LIST *update_tables, *table_being_updated; -// Unique **tempfiles; COPY_INFO *infos; TABLE **tmp_tables; THD *thd; diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 032cbf3d6a3..3f619b70244 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -285,13 +285,20 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, */ if (!found_other_files) { - char tmp_path[FN_REFLEN]; + char tmp_path[FN_REFLEN], *pos; char *path=unpack_filename(tmp_path,org_path); #ifdef HAVE_READLINK - int linkcount = readlink(path,filePath,sizeof(filePath)-1); - if (linkcount > 0) // If the path was a symbolic link + int error; + + /* Remove end FN_LIBCHAR as this causes problem on Linux in readlink */ + pos=strend(path); + if (pos > path && pos[-1] == FN_LIBCHAR) + *--pos=0; + + if ((error=my_readlink(filePath, path, MYF(MY_WME))) < 0) + DBUG_RETURN(-1); + if (!error) { - *(filePath + linkcount) = '\0'; if (my_delete(path,MYF(!level ? MY_WME : 0))) { /* Don't give errors if we can't delete 'RAID' directory */ @@ -299,11 +306,13 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, DBUG_RETURN(deleted); DBUG_RETURN(-1); } - path=filePath; + /* Delete directory symbolic link pointed at */ + path= filePath; } #endif /* Remove last FN_LIBCHAR to not cause a problem on OS/2 */ - char *pos=strend(path); + pos=strend(path); + if (pos > path && pos[-1] == FN_LIBCHAR) *--pos=0; /* Don't give errors if we can't delete 'RAID' directory */ @@ -325,7 +334,7 @@ bool mysql_change_db(THD *thd,const char *name) uint db_access; DBUG_ENTER("mysql_change_db"); - if (!dbname || !(db_length=stripp_sp(dbname))) + if (!dbname || !(db_length=strip_sp(dbname))) { x_free(dbname); /* purecov: inspected */ send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: inspected */ diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index f5a5a684fc0..48a738f9f6b 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -176,13 +176,15 @@ cleanup: } if (using_transactions && ha_autocommit_or_rollback(thd,error >= 0)) error=1; + if (deleted) + { + query_cache_invalidate3(thd, table_list, 1); + } if (thd->lock) { mysql_unlock_tables(thd, thd->lock); thd->lock=0; } - if (deleted) - query_cache_invalidate3(thd, table_list, 1); delete select; if (error >= 0) // Fatal error send_error(&thd->net,thd->killed ? ER_SERVER_SHUTDOWN: 0); @@ -355,6 +357,9 @@ void multi_delete::send_error(uint errcode,const char *err) if (!deleted) DBUG_VOID_RETURN; + /* Somthing alredy deleted consequently we have to invalidate cache */ + query_cache_invalidate3(thd, delete_tables, 1); + /* Below can happen when thread is killed early ... */ if (!table_being_deleted) table_being_deleted=delete_tables; @@ -470,7 +475,9 @@ bool multi_delete::send_eof() VOID(ha_autocommit_or_rollback(thd,error > 0)); } if (deleted) + { query_cache_invalidate3(thd, delete_tables, 1); + } ::send_ok(&thd->net,deleted); return 0; } @@ -509,8 +516,9 @@ int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK); bzero((char*) &create_info,sizeof(create_info)); create_info.auto_increment_value= table->file->auto_increment_value; - db_type table_type=table->db_type; + create_info.table_charset=default_charset_info; + db_type table_type=table->db_type; strmov(path,table->path); *table_ptr= table->next; // Unlink table from list close_temporary(table,0); @@ -520,7 +528,8 @@ int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) if ((error= (int) !(open_temporary_table(thd, path, table_list->db, table_list->real_name, 1)))) (void) rm_temporary_table(table_type, path); - /* Sasha: if we return here we will not have binloged the truncation and + /* + If we return here we will not have binloged the truncation and we will not send_ok() to the client. Yes, we do need better coverage testing, this bug has been here for a few months :-). */ @@ -550,6 +559,8 @@ int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) } bzero((char*) &create_info,sizeof(create_info)); + create_info.table_charset=default_charset_info; + *fn_ext(path)=0; // Remove the .frm extension error= ha_create_table(path,&create_info,1) ? -1 : 0; query_cache_invalidate3(thd, table_list, 0); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 69fc7c00955..1e00bb3f8c2 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -262,6 +262,8 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields, info.copied=values_list.elements; end_delayed_insert(thd); } + if (info.copied || info.deleted) + query_cache_invalidate3(thd, table_list, 1); } else { @@ -303,6 +305,10 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields, } if (using_transactions) error=ha_autocommit_or_rollback(thd,error); + if (info.copied || info.deleted) + { + query_cache_invalidate3(thd, table_list, 1); + } if (thd->lock) { mysql_unlock_tables(thd, thd->lock); @@ -310,8 +316,6 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields, } } thd->proc_info="end"; - if (info.copied || info.deleted) - query_cache_invalidate3(thd, table_list, 1); table->time_stamp=save_time_stamp; // Restore auto timestamp ptr table->next_number_field=0; thd->count_cuted_fields=0; @@ -443,6 +447,7 @@ int write_record(TABLE *table,COPY_INFO *info) err: if (key) my_afree(key); + info->errorno= error; table->file->print_error(error,MYF(0)); return 1; } @@ -1330,7 +1335,9 @@ void select_insert::send_error(uint errcode,const char *err) table->file->activate_all_index(thd); ha_rollback_stmt(thd); if (info.copied || info.deleted) + { query_cache_invalidate3(thd, table, 1); + } } @@ -1343,8 +1350,9 @@ bool select_insert::send_eof() if ((error2=ha_autocommit_or_rollback(thd,error)) && ! error) error=error2; if (info.copied || info.deleted) + { query_cache_invalidate3(thd, table, 1); - + } if (error) { table->file->print_error(error,MYF(0)); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index e53a2e7bda8..b7f0185709b 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -154,6 +154,7 @@ typedef struct st_lex { sql_exchange *exchange; List<key_part_spec> col_list; + List<key_part_spec> ref_list; List<Alter_drop> drop_list; List<Alter_column> alter_list; List<String> interval_list; @@ -167,7 +168,7 @@ typedef struct st_lex { SQL_LIST proc_list, auxilliary_table_list; TYPELIB *interval; create_field *last_field; - Item *default_value; + Item *default_value, *comment; CONVERT *convert_set; LEX_USER *grant_user; gptr yacc_yyss,yacc_yyvs; @@ -176,16 +177,18 @@ typedef struct st_lex { HA_CHECK_OPT check_opt; // check/repair options HA_CREATE_INFO create_info; LEX_MASTER_INFO mi; // used by CHANGE MASTER + USER_RESOURCES mqh; ulong thread_id,type; enum_sql_command sql_command; + thr_lock_type lock_option; enum lex_states next_state; enum enum_duplicates duplicates; enum enum_tx_isolation tx_isolation; enum enum_ha_read_modes ha_read_mode; enum ha_rkey_function ha_rkey_mode; enum enum_enable_or_disable alter_keys_onoff; - uint grant,grant_tot_col,which_columns, union_option, mqh; - thr_lock_type lock_option; + uint grant, grant_tot_col, which_columns, union_option; + uint fk_delete_opt, fk_update_opt, fk_match_option; bool drop_primary,drop_if_exists,local_file; bool in_comment,ignore_space,verbose,simple_alter, option_type, derived_tables; uint slave_thd_opt; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 469de136fbb..790994b897e 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -59,9 +59,9 @@ extern "C" pthread_mutex_t THR_LOCK_keycache; extern "C" int gethostname(char *name, int namelen); #endif -static int check_for_max_user_connections(UC *uc); +static int check_for_max_user_connections(USER_CONN *uc); static bool check_mqh(THD *thd); -static void decrease_user_connections(UC *uc); +static void decrease_user_connections(USER_CONN *uc); static bool check_db_used(THD *thd,TABLE_LIST *tables); static bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *tables); static bool check_dup(const char *db, const char *name, TABLE_LIST *tables); @@ -126,18 +126,19 @@ extern pthread_mutex_t LOCK_user_conn; static int get_or_create_user_conn(THD *thd, const char *user, const char *host, - uint max_questions) + USER_RESOURCES *mqh) { int return_val=0; - uint temp_len; + uint temp_len, user_len, host_len; char temp_user[USERNAME_LENGTH+HOSTNAME_LENGTH+2]; struct user_conn *uc; DBUG_ASSERT(user != 0); DBUG_ASSERT(host != 0); - temp_len= (uint) (strxnmov(temp_user, sizeof(temp_user)-1, user, "@", host, - NullS) - temp_user); + user_len=strlen(user); + host_len=strlen(host); + temp_len= (strmov(strmov(temp_user, user)+1, host) - temp_user)+1; (void) pthread_mutex_lock(&LOCK_user_conn); if (!(uc = (struct user_conn *) hash_search(&hash_user_connections, (byte*) temp_user, temp_len))) @@ -153,10 +154,14 @@ static int get_or_create_user_conn(THD *thd, const char *user, } uc->user=(char*) (uc+1); memcpy(uc->user,temp_user,temp_len+1); + uc->user_len= user_len; + uc->host=uc->user + uc->user_len + 1; uc->len = temp_len; - uc->connections = 1; - uc->questions=0; - uc->max_questions=max_questions; + uc->connections = 1; + uc->questions=uc->updates=uc->conn_per_hour=0; + uc->user_resources=*mqh; + if (max_user_connections && mqh->connections > max_user_connections) + uc->user_resources.connections = max_user_connections; uc->intime=thd->thr_create_time; if (hash_insert(&hash_user_connections, (byte*) uc)) { @@ -184,9 +189,9 @@ static bool check_user(THD *thd,enum_server_command command, const char *user, const char *passwd, const char *db, bool check_count) { NET *net= &thd->net; - uint max_questions=0; thd->db=0; thd->db_length=0; + USER_RESOURCES ur; if (!(thd->user = my_strdup(user, MYF(0)))) { @@ -197,7 +202,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user, passwd, thd->scramble, &thd->priv_user, protocol_version == 9 || !(thd->client_capabilities & - CLIENT_LONG_PASSWORD),&max_questions); + CLIENT_LONG_PASSWORD),&ur); DBUG_PRINT("info", ("Capabilities: %d packet_length: %d Host: '%s' User: '%s' Using password: %s Access: %u db: '%s'", thd->client_capabilities, thd->max_packet_length, @@ -237,9 +242,10 @@ static bool check_user(THD *thd,enum_server_command command, const char *user, db ? db : (char*) ""); thd->db_access=0; /* Don't allow user to connect if he has done too many queries */ - if ((max_questions || max_user_connections) && get_or_create_user_conn(thd,user,thd->host_or_ip,max_questions)) + if ((ur.questions || ur.updates || ur.connections) && + get_or_create_user_conn(thd,user,thd->host_or_ip,&ur)) return -1; - if (max_user_connections && thd->user_connect && + if (thd->user_connect && thd->user_connect->user_resources.connections && check_for_max_user_connections(thd->user_connect)) return -1; if (db && db[0]) @@ -254,6 +260,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user, return 0; // ok } + /* Check for maximum allowable user connections, if the mysqld server is started with corresponding variable that is greater then 0. @@ -280,32 +287,38 @@ void init_max_user_conn(void) } -static int check_for_max_user_connections(UC *uc) +static int check_for_max_user_connections(USER_CONN *uc) { int error=0; DBUG_ENTER("check_for_max_user_connections"); - if (max_user_connections <= (uint) uc->connections) + if (max_user_connections && ( max_user_connections <= (uint) uc->connections)) { net_printf(&(current_thd->net),ER_TOO_MANY_USER_CONNECTIONS, uc->user); error=1; goto end; } uc->connections++; - + if (uc->user_resources.connections && uc->conn_per_hour++ >= uc->user_resources.connections) + { + net_printf(¤t_thd->net, ER_USER_LIMIT_REACHED, uc->user, "max_connections", + (long) uc->user_resources.connections); + error=1; + goto end; + } end: DBUG_RETURN(error); } -static void decrease_user_connections(UC *uc) +static void decrease_user_connections(USER_CONN *uc) { - if (!max_user_connections) +/* if (!max_user_connections) return; +*/ DBUG_ENTER("decrease_user_connections"); - - if (!--uc->connections && !mqh_used) + if (!mqh_used && uc->connections && !--uc->connections) { /* Last connection for user; Delete it */ (void) pthread_mutex_lock(&LOCK_user_conn); @@ -326,70 +339,92 @@ void free_max_user_conn(void) Check if maximum queries per hour limit has been reached returns 0 if OK. - In theory we would need a mutex in the UC structure for this to be 100 % + In theory we would need a mutex in the USER_CONN structure for this to be 100 % safe, but as the worst scenario is that we would miss counting a couple of queries, this isn't critical. */ +char uc_update_queries[SQLCOM_END]; + static bool check_mqh(THD *thd) { bool error=0; DBUG_ENTER("check_mqh"); - UC *uc=thd->user_connect; + USER_CONN *uc=thd->user_connect; DBUG_ASSERT(uc != 0); + uint check_command = thd->lex.sql_command; + - bool my_start = thd->start_time != 0; - time_t check_time = (my_start) ? thd->start_time : time(NULL); - if (check_time - uc->intime >= 3600) + if (check_command < (uint) SQLCOM_END) { - (void) pthread_mutex_lock(&LOCK_user_conn); - uc->questions=1; - uc->intime=check_time; - (void) pthread_mutex_unlock(&LOCK_user_conn); + if (uc->user_resources.updates && uc_update_queries[check_command] && + ++(uc->updates) > uc->user_resources.updates) + { + net_printf(&thd->net, ER_USER_LIMIT_REACHED, uc->user, "max_updates", + (long) uc->user_resources.updates); + error=1; + goto end; + } } - else if (uc->max_questions && ++(uc->questions) > uc->max_questions) + else { - net_printf(&thd->net, ER_USER_LIMIT_REACHED, uc->user, "max_questions", - (long) uc->max_questions); - error=1; - goto end; + bool my_start = thd->start_time != 0; + time_t check_time = (my_start) ? thd->start_time : time(NULL); + + if (check_time - uc->intime >= 3600) + { + (void) pthread_mutex_lock(&LOCK_user_conn); + uc->questions=1; + uc->updates=0; + uc->conn_per_hour=0; + uc->intime=check_time; + (void) pthread_mutex_unlock(&LOCK_user_conn); + } + else if (uc->user_resources.questions && ++(uc->questions) > uc->user_resources.questions) + { + net_printf(&thd->net, ER_USER_LIMIT_REACHED, uc->user, "max_questions", + (long) uc->user_resources.questions); + error=1; + goto end; + } } - end: DBUG_RETURN(error); } -static void reset_mqh(THD *thd, LEX_USER *lu, uint mq) +static void reset_mqh(THD *thd, LEX_USER *lu, USER_RESOURCES *mqh, bool get_them=false) { (void) pthread_mutex_lock(&LOCK_user_conn); if (lu) // for GRANT { - UC *uc; + USER_CONN *uc; uint temp_len=lu->user.length+lu->host.length+2; char temp_user[USERNAME_LENGTH+HOSTNAME_LENGTH+2]; memcpy(temp_user,lu->user.str,lu->user.length); memcpy(temp_user+lu->user.length+1,lu->host.str,lu->host.length); - temp_user[lu->user.length]=temp_user[temp_len-1]=0; + temp_user[lu->user.length]='\0'; temp_user[temp_len-1]=0; if ((uc = (struct user_conn *) hash_search(&hash_user_connections, - (byte*) temp_user, temp_len))) + (byte*) temp_user, temp_len-1))) { uc->questions=0; - uc->max_questions=mq; + uc->user_resources=*mqh; + uc->updates=0; + uc->conn_per_hour=0; } } - else // for FLUSH PRIVILEGES + else // for FLUSH PRIVILEGES and FLUSH USER_RESOURCES { for (uint idx=0;idx < hash_user_connections.records; idx++) { - char user[USERNAME_LENGTH+1]; - char *where; - UC *uc=(struct user_conn *) hash_element(&hash_user_connections, idx); - where=strchr(uc->user,'@'); - strmake(user,uc->user,where - uc->user); - uc->max_questions=get_mqh(user,where+1); + USER_CONN *uc=(struct user_conn *) hash_element(&hash_user_connections, idx); + if (get_them) + get_mqh(uc->user,uc->host,uc); + uc->questions=0; + uc->updates=0; + uc->conn_per_hour=0; } } (void) pthread_mutex_unlock(&LOCK_user_conn); @@ -555,7 +590,7 @@ pthread_handler_decl(handle_one_connection,arg) #if !defined( __WIN__) && !defined(OS2) // Win32 calls this in pthread_create // The following calls needs to be done before we call DBUG_ macros - if (my_thread_init()) + if (!(test_flags & TEST_NO_THREADS) & my_thread_init()) { close_connection(&thd->net,ER_OUT_OF_RESOURCES); statistic_increment(aborted_connects,&LOCK_thread_count); @@ -710,7 +745,7 @@ pthread_handler_decl(handle_bootstrap,arg) thd->query= thd->memdup_w_gap(buff, length+1, thd->db_length+1); thd->query[length] = '\0'; thd->query_id=query_id++; - if (thd->user_connect && check_mqh(thd)) + if (mqh_used && thd->user_connect && check_mqh(thd)) { thd->net.error = 0; close_thread_tables(thd); // Free tables @@ -897,7 +932,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, char *save_user= thd->user; char *save_priv_user= thd->priv_user; char *save_db= thd->db; - UC *save_uc= thd->user_connect; + USER_CONN *save_uc= thd->user_connect; if ((uint) ((uchar*) db - net->read_pos) > packet_length) { // Check if protocol is ok @@ -951,7 +986,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, my_pthread_setprio(pthread_self(),QUERY_PRIOR); mysql_log.write(thd,command,"%s",thd->query); DBUG_PRINT("query",("%s",thd->query)); - if (thd->user_connect && check_mqh(thd)) + if (mqh_used && thd->user_connect && check_mqh(thd)) { error = TRUE; // Abort client net->error = 0; // Don't give abort message @@ -1010,7 +1045,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thread_safe_increment(com_stat[SQLCOM_CREATE_DB],&LOCK_thread_count); char *db=thd->strdup(packet); // null test to handle EOM - if (!db || !stripp_sp(db) || check_db_name(db)) + if (!db || !strip_sp(db) || check_db_name(db)) { net_printf(&thd->net,ER_WRONG_DB_NAME, db ? db : "NULL"); break; @@ -1026,7 +1061,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thread_safe_increment(com_stat[SQLCOM_DROP_DB],&LOCK_thread_count); char *db=thd->strdup(packet); // null test to handle EOM - if (!db || !stripp_sp(db) || check_db_name(db)) + if (!db || !strip_sp(db) || check_db_name(db)) { net_printf(&thd->net,ER_WRONG_DB_NAME, db ? db : "NULL"); break; @@ -1076,8 +1111,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd, send_error(net,0); else send_eof(net); - if (mqh_used) - reset_mqh(thd,(LEX_USER *) NULL, 0); break; } case COM_SHUTDOWN: @@ -1680,7 +1713,6 @@ mysql_execute_command(void) check_table_access(thd,SELECT_ACL | INSERT_ACL, tables)) goto error; /* purecov: inspected */ res = mysql_repair_table(thd, tables, &lex->check_opt); - query_cache_invalidate3(thd, tables, 0); break; } case SQLCOM_CHECK: @@ -1689,7 +1721,6 @@ mysql_execute_command(void) check_table_access(thd, SELECT_ACL | EXTRA_ACL , tables)) goto error; /* purecov: inspected */ res = mysql_check_table(thd, tables, &lex->check_opt); - query_cache_invalidate3(thd, tables, 0); break; } case SQLCOM_ANALYZE: @@ -1718,6 +1749,7 @@ mysql_execute_command(void) bzero((char*) &create_info,sizeof(create_info)); create_info.db_type=DB_TYPE_DEFAULT; create_info.row_type=ROW_TYPE_DEFAULT; + create_info.table_charset=default_charset_info; res= mysql_alter_table(thd, NullS, NullS, &create_info, tables, lex->create_list, lex->key_list, lex->drop_list, lex->alter_list, @@ -1772,6 +1804,7 @@ mysql_execute_command(void) tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege); if ((res=open_and_lock_tables(thd,tables))) break; + thd->select_limit=HA_POS_ERROR; if (!setup_fields(thd,tables,select_lex->item_list,1,0,0) && !setup_fields(thd,tables,lex->value_list,0,0,0) && ! thd->fatal_error && (result=new multi_update(thd,tables,select_lex->item_list,lex->duplicates, @@ -1939,6 +1972,7 @@ mysql_execute_command(void) } auxi->lock_type=walk->lock_type=TL_WRITE; auxi->table= (TABLE *) walk; // Remember corresponding table + (void)add_item_to_list(new Item_field(auxi->db,auxi->real_name,"*")); } tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege); if (add_item_to_list(new Item_null())) @@ -1952,8 +1986,9 @@ mysql_execute_command(void) /* Fix tables-to-be-deleted-from list to point at opened tables */ for (auxi=(TABLE_LIST*) aux_tables ; auxi ; auxi=auxi->next) auxi->table= ((TABLE_LIST*) auxi->table)->table; - if (!thd->fatal_error && (result=new multi_delete(thd,aux_tables, - lex->lock_option,table_count))) + if (!thd->fatal_error && (result= new multi_delete(thd,aux_tables, + lex->lock_option, + table_count))) { res=mysql_select(thd,tables,select_lex->item_list, select_lex->where, @@ -2198,7 +2233,8 @@ mysql_execute_command(void) } if (check_db_used(thd,tables) || end_active_trans(thd)) goto error; - if (grant_option && check_grant(thd,SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL,tables)) + if (check_table_access(thd, SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL , tables) + || (grant_option && check_grant(thd,SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL,tables))) goto error; thd->in_lock_tables=1; thd->options|= OPTION_TABLE_LOCK; @@ -2214,7 +2250,7 @@ mysql_execute_command(void) break; case SQLCOM_CREATE_DB: { - if (!stripp_sp(lex->name) || check_db_name(lex->name)) + if (!strip_sp(lex->name) || check_db_name(lex->name)) { net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name); break; @@ -2226,7 +2262,7 @@ mysql_execute_command(void) } case SQLCOM_DROP_DB: { - if (!stripp_sp(lex->name) || check_db_name(lex->name)) + if (!strip_sp(lex->name) || check_db_name(lex->name)) { net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name); break; @@ -2328,12 +2364,12 @@ mysql_execute_command(void) Query_log_event qinfo(thd, thd->query); mysql_bin_log.write(&qinfo); } - if (mqh_used && lex->mqh) + if (mqh_used && (lex->mqh.questions || lex->mqh.updates || lex->mqh.connections) && lex->sql_command == SQLCOM_GRANT) { List_iterator <LEX_USER> str_list(lex->users_list); LEX_USER *user; while ((user=str_list++)) - reset_mqh(thd,user,lex->mqh); + reset_mqh(thd,user,&(lex->mqh)); } } } @@ -2548,8 +2584,17 @@ check_table_access(THD *thd,uint want_access,TABLE_LIST *tables, } } else if (check_access(thd,want_access,tables->db,&tables->grant.privilege, + 0, no_errors | grant_option)) + { + if (grant_option) + { + if ( check_access(thd,want_access & (uint) ~TABLE_ACLS,tables->db,&tables->grant.privilege, 0, no_errors)) - return TRUE; // Access denied + return TRUE; + } + else + return TRUE; + } } if (grant_option) return check_grant(thd,want_access & ~EXTRA_ACL,org_tables, @@ -2721,7 +2766,7 @@ void mysql_init_multi_delete(LEX *lex) { lex->sql_command = SQLCOM_DELETE_MULTI; mysql_init_select(lex); - lex->select->select_limit=HA_POS_ERROR; + lex->select->select_limit=lex->thd->select_limit=HA_POS_ERROR; lex->auxilliary_table_list=lex->select_lex.table_list; lex->select->table_list.elements=0; lex->select->table_list.first=0; @@ -2740,8 +2785,15 @@ mysql_parse(THD *thd,char *inBuf,uint length) LEX *lex=lex_start(thd, (uchar*) inBuf, length); if (!yyparse() && ! thd->fatal_error) { - mysql_execute_command(); - query_cache_end_of_result(&thd->net); + if (mqh_used && thd->user_connect && check_mqh(thd)) + { + thd->net.error = 0; + } + else + { + mysql_execute_command(); + query_cache_end_of_result(&thd->net); + } } else query_cache_abort(&thd->net); @@ -2770,8 +2822,9 @@ link_in_list(SQL_LIST *list,byte *element,byte **next) bool add_field_to_list(char *field_name, enum_field_types type, char *length, char *decimals, - uint type_modifier, Item *default_value,char *change, - TYPELIB *interval) + uint type_modifier, + Item *default_value, Item *comment, + char *change, TYPELIB *interval) { register create_field *new_field; THD *thd=current_thd; @@ -2787,14 +2840,14 @@ bool add_field_to_list(char *field_name, enum_field_types type, if (type_modifier & PRI_KEY_FLAG) { lex->col_list.push_back(new key_part_spec(field_name,0)); - lex->key_list.push_back(new Key(Key::PRIMARY, HA_KEY_ALG_UNDEF, NullS, + lex->key_list.push_back(new Key(Key::PRIMARY, NullS, HA_KEY_ALG_UNDEF, lex->col_list)); lex->col_list.empty(); } if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG)) { lex->col_list.push_back(new key_part_spec(field_name,0)); - lex->key_list.push_back(new Key(Key::UNIQUE, HA_KEY_ALG_UNDEF, NullS, + lex->key_list.push_back(new Key(Key::UNIQUE, NullS, HA_KEY_ALG_UNDEF, lex->col_list)); lex->col_list.empty(); } @@ -2824,15 +2877,28 @@ bool add_field_to_list(char *field_name, enum_field_types type, new_field->change=change; new_field->interval=0; new_field->pack_length=0; + new_field->charset=0; // QQ: To be fixed + + if (!comment) + { + new_field->comment.str=0; + new_field->comment.length=0; + } + else + { + /* In this case comment is always of type Item_string */ + new_field->comment.str= (char*) comment->str_value.ptr(); + new_field->comment.length=comment->str_value.length(); + } if (length) if (!(new_field->length= (uint) atoi(length))) length=0; /* purecov: inspected */ uint sign_len=type_modifier & UNSIGNED_FLAG ? 0 : 1; if (new_field->length && new_field->decimals && - new_field->length < new_field->decimals+2 && + new_field->length < new_field->decimals+1 && new_field->decimals != NOT_FIXED_DEC) - new_field->length=new_field->decimals+2; /* purecov: inspected */ + new_field->length=new_field->decimals+1; /* purecov: inspected */ switch (type) { case FIELD_TYPE_TINY: @@ -2960,7 +3026,9 @@ bool add_field_to_list(char *field_name, enum_field_types type, new_field->interval=interval; new_field->length=0; for (const char **pos=interval->type_names; *pos ; pos++) - new_field->length+=(uint) strlen(*pos)+1; + { + new_field->length+=(uint) strip_sp((char*) *pos)+1; + } new_field->length--; set_if_smaller(new_field->length,MAX_FIELD_WIDTH-1); if (default_value) @@ -2981,10 +3049,10 @@ bool add_field_to_list(char *field_name, enum_field_types type, { new_field->interval=interval; new_field->pack_length=interval->count < 256 ? 1 : 2; // Should be safe - new_field->length=(uint) strlen(interval->type_names[0]); + new_field->length=(uint) strip_sp((char*) interval->type_names[0]); for (const char **pos=interval->type_names+1; *pos ; pos++) { - uint length=(uint) strlen(*pos); + uint length=(uint) strip_sp((char*) *pos); set_if_bigger(new_field->length,length); } set_if_smaller(new_field->length,MAX_FIELD_WIDTH-1); @@ -3287,6 +3355,8 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables) { acl_reload(); grant_reload(); + if (mqh_used) + reset_mqh(thd,(LEX_USER *) NULL, 0, true); } if (options & REFRESH_LOG) { @@ -3333,14 +3403,16 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables) result=load_des_key_file(des_key_file); } #endif - if (options & REFRESH_SLAVE) - { - LOCK_ACTIVE_MI; - if (reset_slave(active_mi)) - result=1; - UNLOCK_ACTIVE_MI; - } - return result; + if (options & REFRESH_SLAVE) + { + LOCK_ACTIVE_MI; + if (reset_slave(active_mi)) + result=1; + UNLOCK_ACTIVE_MI; + } + if (options & REFRESH_USER_RESOURCES) + reset_mqh(thd,(LEX_USER *) NULL, 0); + return result; } diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 398ff443ad4..b6c7c98a4cf 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -27,11 +27,9 @@ extern const char* any_db; -#ifndef DBUG_OFF int max_binlog_dump_events = 0; // unlimited bool opt_sporadic_binlog_dump_fail = 0; static int binlog_dump_count = 0; -#endif int check_binlog_magic(IO_CACHE* log, const char** errmsg) { diff --git a/sql/sql_repl.h b/sql/sql_repl.h index 360fd50a1e3..b15c72a0bde 100644 --- a/sql/sql_repl.h +++ b/sql/sql_repl.h @@ -21,10 +21,8 @@ extern uint32 server_id; extern bool server_id_supplied; extern I_List<i_string> binlog_do_db, binlog_ignore_db; -#ifndef DBUG_OFF extern int max_binlog_dump_events; extern bool opt_sporadic_binlog_dump_fail; -#endif #define KICK_SLAVE(thd) thd->awake(0 /* do not prepare to die*/); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index c539afb00c1..5e18299ef87 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1610,7 +1610,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, join_tab[i].table->map); } } - if (init_dynamic_array(keyuse,sizeof(KEYUSE),20,64)) + if (my_init_dynamic_array(keyuse,sizeof(KEYUSE),20,64)) return TRUE; /* fill keyuse with found key parts */ for (KEY_FIELD *field=key_fields ; field != end ; field++) @@ -2363,7 +2363,7 @@ make_simple_join(JOIN *join,TABLE *tmp_table) join->send_records=(ha_rows) 0; join->group=0; join->do_send_rows = 1; - join->row_limit=HA_POS_ERROR; + join->row_limit=join->thd->select_limit; join_tab->cache.buff=0; /* No cacheing */ join_tab->table=tmp_table; @@ -3824,6 +3824,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, key_part_info->null_offset= (uint) (field->null_ptr - (uchar*) table->record[0]); group->field->move_field((char*) ++group->buff); + ++group_buff; } else group->field->move_field((char*) group_buff); @@ -4018,6 +4019,7 @@ static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param, } MI_CREATE_INFO create_info; bzero((char*) &create_info,sizeof(create_info)); + if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) == OPTION_BIG_TABLES) create_info.data_file_length= ~(ulonglong) 0; @@ -4903,7 +4905,8 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), { /* Join over all rows in table; Return number of found rows */ join->select_options ^= OPTION_FOUND_ROWS; - join->send_records = jt->records; + jt->table->file->info(HA_STATUS_VARIABLE); + join->send_records = jt->table->file->records; } else { @@ -4941,10 +4944,9 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), join->procedure->end_group(); if (idx < (int) join->send_group_parts) { - int error; + int error=0; if (join->procedure) { - error=0; if (join->having && join->having->val_int() == 0) error= -1; // Didn't satisfy having else if (join->do_send_rows) @@ -4962,13 +4964,16 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), } if (join->having && join->having->val_int() == 0) error= -1; // Didn't satisfy having - else + else if (join->do_send_rows) error=join->result->send_data(*join->fields) ? 1 : 0; } if (error > 0) DBUG_RETURN(-1); /* purecov: inspected */ if (end_of_records) + { + join->send_records++; DBUG_RETURN(0); + } if (!error && ++join->send_records >= join->thd->select_limit && join->do_send_rows) { @@ -6992,6 +6997,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, /* Don't log this into the slow query log */ select_lex->options&= ~(QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED); + thd->offset_limit=0; if (thd->lex.select == select_lex) { field_list.push_back(new Item_empty_string("table",NAME_LEN)); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 849a803a622..995142d6566 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -432,6 +432,7 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, TABLE *table; handler *file; char tmp[MAX_FIELD_WIDTH]; + Item *item; CONVERT *convert=thd->convert_set; DBUG_ENTER("mysqld_show_fields"); DBUG_PRINT("enter",("db: %s table: %s",table_list->db, @@ -451,11 +452,14 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, field_list.push_back(new Item_empty_string("Type",40)); field_list.push_back(new Item_empty_string("Null",1)); field_list.push_back(new Item_empty_string("Key",3)); - field_list.push_back(new Item_empty_string("Default",NAME_LEN)); + field_list.push_back(item=new Item_empty_string("Default",NAME_LEN)); + item->maybe_null=1; field_list.push_back(new Item_empty_string("Extra",20)); if (verbose) + { field_list.push_back(new Item_empty_string("Privileges",80)); - + field_list.push_back(new Item_empty_string("Comment",255)); + } // Send first number of fields and records { char *pos; @@ -522,7 +526,7 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, if (verbose) { - /* Add grant options */ + /* Add grant options & comments */ col_access= get_column_grant(thd,table_list,field) & COL_ACLS; end=tmp; for (uint bitnr=0; col_access ; col_access>>=1,bitnr++) @@ -534,6 +538,7 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, } } net_store_data(packet,convert, tmp+1,end == tmp ? 0 : (uint) (end-tmp-1)); + net_store_data(packet, field->comment.str,field->comment.length); } if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length())) DBUG_RETURN(1); @@ -571,21 +576,34 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) { packet->length(0); net_store_data(packet,convert, table->table_name); - // a hack - we need to reserve some space for the length before - // we know what it is - let's assume that the length of create table - // statement will fit into 3 bytes ( 16 MB max :-) ) + /* + A hack - we need to reserve some space for the length before + we know what it is - let's assume that the length of create table + statement will fit into 3 bytes ( 16 MB max :-) ) + */ ulong store_len_offset = packet->length(); packet->length(store_len_offset + 4); if (store_create_info(thd, table, packet)) DBUG_RETURN(-1); ulong create_len = packet->length() - store_len_offset - 4; + /* + Just in case somebody manages to create a table + with *that* much stuff in the definition + */ if (create_len > 0x00ffffff) // better readable in HEX ... - DBUG_RETURN(1); // just in case somebody manages to create a table - // with *that* much stuff in the definition + { + /* + Just in case somebody manages to create a table + with *that* much stuff in the definition + */ + DBUG_RETURN(1); + } - // now we have to store the length in three bytes, even if it would fit - // into fewer, so we cannot use net_store_data() anymore, - // and do it ourselves + /* + Now we have to store the length in three bytes, even if it would fit + into fewer bytes, so we cannot use net_store_data() anymore, + and do it ourselves + */ char* p = (char*)packet->ptr() + store_len_offset; *p++ = (char) 253; // The client the length is stored using 3-bytes int3store(p, create_len); @@ -848,10 +866,10 @@ store_create_info(THD *thd, TABLE *table, String *packet) { // Not null by default type.set(tmp,sizeof(tmp),default_charset_info); field->val_str(&type,&type); - packet->append('\''); if (type.length()) - append_unescaped(packet, type.c_ptr()); - packet->append('\''); + append_unescaped(packet, type.ptr(), type.length()); + else + packet->append("''",2); } else if (field->maybe_null()) packet->append("NULL", 4); // Null as default @@ -860,7 +878,13 @@ store_create_info(THD *thd, TABLE *table, String *packet) } if (field->unireg_check == Field::NEXT_NUMBER) - packet->append(" auto_increment", 15 ); + packet->append(" auto_increment", 15 ); + + if (field->comment.length) + { + packet->append(" COMMENT ",9); + append_unescaped(packet, field->comment.str, field->comment.length); + } } KEY *key_info=table->key_info; @@ -890,8 +914,9 @@ store_create_info(THD *thd, TABLE *table, String *packet) append_identifier(thd,packet,key_info->name); // +BAR: send USING only in non-default case: non-spatial rtree - if((key_info->algorithm == HA_KEY_ALG_RTREE) && !(key_info->flags & HA_SPATIAL)) - packet->append(" USING RTREE",12); + if((key_info->algorithm == HA_KEY_ALG_RTREE) && + !(key_info->flags & HA_SPATIAL)) + packet->append(" USING RTREE",12); packet->append(" (", 2); @@ -972,9 +997,8 @@ store_create_info(THD *thd, TABLE *table, String *packet) table->file->append_create_info(packet); if (table->comment && table->comment[0]) { - packet->append(" COMMENT='", 10); - append_unescaped(packet, table->comment); - packet->append('\''); + packet->append(" COMMENT=", 9); + append_unescaped(packet, table->comment, strlen(table->comment)); } if (file->raid_type) { @@ -1156,7 +1180,8 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables) pthread_mutex_lock(&LOCK_status); for (i=0; variables[i].name; i++) { - if (!(wild && wild[0] && wild_compare(variables[i].name,wild))) + if (!(wild && wild[0] && wild_case_compare(system_charset_info, + variables[i].name,wild))) { packet2.length(0); net_store_data(&packet2,convert,variables[i].name); diff --git a/sql/sql_string.cc b/sql/sql_string.cc index b8e2ba7b536..9014ca430d9 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -40,19 +40,16 @@ extern void sql_element_free(void *ptr); bool String::real_alloc(uint32 arg_length) { arg_length=ALIGN_SIZE(arg_length+1); + str_length=0; if (Alloced_length < arg_length) { free(); if (!(Ptr=(char*) my_malloc(arg_length,MYF(MY_WME)))) - { - str_length=0; return TRUE; - } Alloced_length=arg_length; alloced=1; } Ptr[0]=0; - str_length=0; return FALSE; } diff --git a/sql/sql_string.h b/sql/sql_string.h index 5e5c9001590..e94981d22c3 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -213,16 +213,17 @@ public: uint32 numchars(); int charpos(int i,uint32 offset=0); -// added by Holyfoot for "geometry" needs int reserve(uint32 space_needed) { return realloc(str_length + space_needed); } int reserve(uint32 space_needed, uint32 grow_by); -// these append operations do NOT check alloced memory -// q_*** methods writes values of parameters itself -// qs_*** methods writes string representation of value + /* + The following append operations do NOT check alloced memory + q_*** methods writes values of parameters itself + qs_*** methods writes string representation of value + */ void q_append(const char &c) { Ptr[str_length++] = c; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index bdcb325774b..f4f4dd212bd 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -266,7 +266,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, DBUG_ENTER("mysql_create_table"); /* - ** Check for duplicate fields and check type of table to create + Check for duplicate fields and check type of table to create */ if (!fields.elements) @@ -398,35 +398,50 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, /* Create keys */ List_iterator<Key> key_iterator(keys); - uint key_parts=0,key_count=keys.elements; + uint key_parts=0, key_count=0, fk_key_count=0; List<Key> keys_in_order; // Add new keys here bool primary_key=0,unique_key=0; Key *key; uint tmp, key_number; - tmp=min(file->max_keys(), MAX_KEY); - if (key_count > tmp) - { - my_error(ER_TOO_MANY_KEYS,MYF(0),tmp); - DBUG_RETURN(-1); - } /* Calculate number of key segements */ while ((key=key_iterator++)) { + if (key->type == Key::FOREIGN_KEY) + { + fk_key_count++; + foreign_key *fk_key= (foreign_key*) key; + if (fk_key->ref_columns.elements && + fk_key->ref_columns.elements != fk_key->columns.elements) + { + my_error(ER_WRONG_FK_DEF, MYF(0), fk_key->name ? fk_key->name : + "foreign key without name", + ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF)); + DBUG_RETURN(-1); + } + continue; + } + key_count++; tmp=max(file->max_key_parts(),MAX_REF_PARTS); if (key->columns.elements > tmp) { my_error(ER_TOO_MANY_KEY_PARTS,MYF(0),tmp); DBUG_RETURN(-1); } - if (key->name() && strlen(key->name()) > NAME_LEN) + if (key->name && strlen(key->name) > NAME_LEN) { - my_error(ER_TOO_LONG_IDENT, MYF(0), key->name()); + my_error(ER_TOO_LONG_IDENT, MYF(0), key->name); DBUG_RETURN(-1); } key_parts+=key->columns.elements; } + tmp=min(file->max_keys(), MAX_KEY); + if (key_count > tmp) + { + my_error(ER_TOO_MANY_KEYS,MYF(0),tmp); + DBUG_RETURN(-1); + } key_info_buffer=key_info=(KEY*) sql_calloc(sizeof(KEY)*key_count); key_part_info=(KEY_PART_INFO*) sql_calloc(sizeof(KEY_PART_INFO)*key_parts); @@ -450,7 +465,10 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, case Key::SPATIAL: key_info->flags = HA_SPATIAL; break; - default: + case Key::FOREIGN_KEY: + key_number--; // Skip this key + continue; + default: key_info->flags = HA_NOSAME; } @@ -623,7 +641,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, key_name=primary_key_name; primary_key=1; } - else if (!(key_name = key->name())) + else if (!(key_name = key->name)) key_name=make_unique_key_name(sql_field->field_name, key_info_buffer,key_info); if (check_if_keyname_exists(key_name,key_info_buffer,key_info)) @@ -984,20 +1002,19 @@ static int prepare_for_repair(THD* thd, TABLE_LIST* table, else { - char from[FN_REFLEN],to[FN_REFLEN]; + char from[FN_REFLEN],tmp[FN_REFLEN]; char* db = thd->db ? thd->db : table->db; sprintf(from, "%s/%s/%s", mysql_real_data_home, db, table->name); fn_format(from, from, "", MI_NAME_DEXT, 4); - sprintf(to,"%s-%lx_%lx", from, current_pid, thd->thread_id); + sprintf(tmp,"%s-%lx_%lx", from, current_pid, thd->thread_id); - - my_rename(to, from, MYF(MY_WME)); + close_cached_table(thd,table->table); if (lock_and_wait_for_table_name(thd,table)) DBUG_RETURN(-1); - if (my_rename(from, to, MYF(MY_WME))) + if (my_rename(from, tmp, MYF(MY_WME))) { unlock_table_name(thd, table); DBUG_RETURN(send_check_errmsg(thd, table, "repair", @@ -1009,7 +1026,7 @@ static int prepare_for_repair(THD* thd, TABLE_LIST* table, DBUG_RETURN(send_check_errmsg(thd, table, "repair", "Failed generating table from .frm file")); } - if (my_rename(to, from, MYF(MY_WME))) + if (my_rename(tmp, from, MYF(MY_WME))) { unlock_table_name(thd, table); DBUG_RETURN(send_check_errmsg(thd, table, "repair", @@ -1170,8 +1187,12 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, if (fatal_error) table->table->version=0; // Force close of table else if (open_for_modify) + { remove_table_from_cache(thd, table->table->table_cache_key, table->table->real_name); + /* May be something modified consequently we have to invalidate cache */ + query_cache_invalidate3(thd, table->table, 0); + } close_thread_tables(thd); table->table=0; // For query cache if (my_net_write(&thd->net, (char*) packet->ptr(), @@ -1282,7 +1303,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, thd->proc_info="init"; table_name=table_list->real_name; db=table_list->db; - if (!new_db) + if (!new_db || !strcmp(new_db,db)) new_db=db; used_fields=create_info->used_fields; @@ -1336,10 +1357,10 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, /* In some simple cases we need not to recreate the table */ thd->proc_info="setup"; - if (simple_alter) + if (simple_alter && !table->tmp_table) { error=0; - if (new_name != table_name) + if (new_name != table_name || new_db != db) { thd->proc_info="rename"; VOID(pthread_mutex_lock(&LOCK_open)); @@ -1362,15 +1383,15 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, } if (!error) { - switch (keys_onoff) - { - case LEAVE_AS_IS: break; - case ENABLE: - error=table->file->activate_all_index(thd); - break; - case DISABLE: - table->file->deactivate_non_unique_index(HA_POS_ERROR); - break; + switch (keys_onoff) { + case LEAVE_AS_IS: + break; + case ENABLE: + error=table->file->activate_all_index(thd); + break; + case DISABLE: + table->file->deactivate_non_unique_index(HA_POS_ERROR); + break; } } if (!error) @@ -1395,7 +1416,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, List<Key> key_list; // Add new keys here /* - ** First collect all fields from table which isn't in drop_list + First collect all fields from table which isn't in drop_list */ create_field *def; @@ -1511,8 +1532,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, } /* - ** Collect all keys which isn't in drop list. Add only those - ** for which some fields exists. + Collect all keys which isn't in drop list. Add only those + for which some fields exists. */ List_iterator<Key> key_it(keys); @@ -1556,12 +1577,13 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, { if (cfield->change) { - if (!my_strcasecmp(system_charset_info,key_part_name, cfield->change)) + if (!my_strcasecmp(system_charset_info, key_part_name, + cfield->change)) break; } else if (!my_strcasecmp(system_charset_info, key_part_name, cfield->field_name)) - break; + break; } if (!cfield) continue; // Field is removed @@ -1583,16 +1605,19 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, (!my_strcasecmp(system_charset_info, key_name, "PRIMARY") ? Key::PRIMARY : Key::UNIQUE) : - (key_info->flags & HA_FULLTEXT ? - Key::FULLTEXT : Key::MULTIPLE)), + (key_info->flags & HA_FULLTEXT ? + Key::FULLTEXT : Key::MULTIPLE)), + key_name, key_info->algorithm, - key_name,key_parts)); + key_parts)); } - key_it.rewind(); { Key *key; while ((key=key_it++)) // Add new keys - key_list.push_back(key); + { + if (key->type != Key::FOREIGN_KEY) + key_list.push_back(key); + } } if (drop_list.elements) @@ -1764,15 +1789,15 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, goto err; } /* - ** Data is copied. Now we rename the old table to a temp name, - ** rename the new one to the old name, remove all entries from the old table - ** from the cash, free all locks, close the old table and remove it. + Data is copied. Now we rename the old table to a temp name, + rename the new one to the old name, remove all entries from the old table + from the cash, free all locks, close the old table and remove it. */ thd->proc_info="rename result table"; sprintf(old_name,"%s2-%lx-%lx", tmp_file_prefix, current_pid, thd->thread_id); - if (new_name != table_name) + if (new_name != table_name || new_db != db) { if (!access(new_name_buff,F_OK)) { @@ -1790,7 +1815,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, { /* Win32 and InnoDB can't drop a table that is in use, so we must - close all the original table at before doing the rename + close the original table at before doing the rename */ table_name=thd->strdup(table_name); // must be saved if (close_cached_table(thd,table)) diff --git a/sql/sql_union.cc b/sql/sql_union.cc index c8237f3ae9b..7f00ddad99f 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -132,7 +132,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) goto exit; } union_result->save_time_stamp=!describe; - + union_result->tmp_table_param=&tmp_table_param; for (sl= &lex->select_lex; sl; sl=sl->next) { lex->select=sl; @@ -253,7 +253,12 @@ bool select_union::send_data(List<Item> &values) return 0; } fill_record(table->field,values); - return write_record(table,&info) ? 1 : 0; + if ((write_record(table,&info))) + { + if (create_myisam_from_heap(table, tmp_table_param, info.errorno, 0)) + return 1; + } + return 0; } bool select_union::send_eof() diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 2a45798ddf8..8b65cba06a5 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -318,13 +318,15 @@ int mysql_update(THD *thd, } if (using_transactions && ha_autocommit_or_rollback(thd, error >= 0)) error=1; + if (updated) + { + query_cache_invalidate3(thd, table_list, 1); + } if (thd->lock) { mysql_unlock_tables(thd, thd->lock); thd->lock=0; } - if (updated) - query_cache_invalidate3(thd, table_list, 1); delete select; if (error >= 0) @@ -643,6 +645,10 @@ void multi_update::send_error(uint errcode,const char *err) /* If nothing updated return */ if (!updated) return; + + /* Somthing alredy updated consequently we have to invalidate cache */ + query_cache_invalidate3(thd, update_tables, 1); + /* Below can happen when thread is killed early ... */ if (!table_being_updated) table_being_updated=update_tables; @@ -789,8 +795,9 @@ bool multi_update::send_eof() sprintf(buff,ER(ER_UPDATE_INFO), (long) found, (long) updated, (long) thd->cuted_fields); if (updated) + { query_cache_invalidate3(thd, update_tables, 1); - + } ::send_ok(&thd->net, (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated, thd->insert_id_used ? thd->insert_id() : 0L,buff); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 61d97cb43f2..d9595e841b3 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -248,7 +248,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token RELAY_LOG_POS_SYM %token MATCH %token MAX_ROWS +%token MAX_CONNECTIONS_PER_HOUR %token MAX_QUERIES_PER_HOUR +%token MAX_UPDATES_PER_HOUR %token MEDIUM_SYM %token MERGE_SYM %token MIN_ROWS @@ -292,6 +294,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token RENAME %token REPEATABLE_SYM %token REQUIRE_SYM +%token RESOURCES %token RESTORE_SYM %token RESTRICT %token REVOKE @@ -302,6 +305,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token SET %token SERIALIZABLE_SYM %token SESSION_SYM +%token SIMPLE_SYM %token SHUTDOWN %token SPATIAL_SYM %token SQL_CACHE_SYM @@ -520,7 +524,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); opt_table_alias %type <table> - table_ident + table_ident references %type <simple_string> remember_name remember_end opt_len opt_ident opt_db text_or_password @@ -532,7 +536,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %type <num> type int_type real_type order_dir opt_field_spec set_option lock_option udf_type if_exists opt_local opt_table_options table_options - table_option opt_if_not_exists + table_option opt_if_not_exists delete_option %type <ulong_num> ULONG_NUM raid_types merge_insert_types @@ -600,7 +604,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); opt_precision opt_ignore opt_column opt_restrict grant revoke set lock unlock string_list field_options field_option field_opt_list opt_binary table_lock_list table_lock varchar - references opt_on_delete opt_on_delete_list opt_on_delete_item use + ref_list opt_on_delete opt_on_delete_list opt_on_delete_item use opt_delete_options opt_delete_option opt_outer table_list table_name opt_option opt_place opt_low_priority opt_attribute opt_attribute_list attribute column_list column_list_id @@ -612,7 +616,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); table_to_table_list table_to_table opt_table_list opt_as handler_rkey_function handler_read_or_scan single_multi table_wild_list table_wild_one opt_wild union union_list - precision union_option + precision union_option opt_on_delete_item END_OF_INPUT %type <NONE> @@ -636,7 +640,7 @@ query: thd->lex.sql_command = SQLCOM_EMPTY_QUERY; } } - | verb_clause END_OF_INPUT {} + | verb_clause END_OF_INPUT {}; verb_clause: alter @@ -674,7 +678,7 @@ verb_clause: | handler | unlock | update - | use + | use; /* change master */ @@ -684,12 +688,12 @@ change: LEX *lex = Lex; lex->sql_command = SQLCOM_CHANGE_MASTER; memset(&lex->mi, 0, sizeof(lex->mi)); - } master_defs + } master_defs; master_defs: master_def | - master_defs ',' master_def + master_defs ',' master_def; master_def: MASTER_HOST_SYM EQ TEXT_STRING @@ -735,7 +739,7 @@ master_def: RELAY_LOG_POS_SYM EQ ULONG_NUM { Lex->mi.relay_log_pos = $3; - } + }; /* create a table */ @@ -756,6 +760,7 @@ create: bzero((char*) &lex->create_info,sizeof(lex->create_info)); lex->create_info.options=$2 | $4; lex->create_info.db_type= default_table_type; + lex->create_info.table_charset=default_charset_info; } create2 @@ -774,7 +779,7 @@ create: { LEX *lex=Lex; - lex->key_list.push_back(new Key($2,$5,$4.str,lex->col_list)); + lex->key_list.push_back(new Key($2,$4.str, $5, lex->col_list)); lex->col_list.empty(); } | CREATE DATABASE opt_if_not_exists ident default_charset @@ -797,11 +802,11 @@ create: LEX *lex=Lex; lex->udf.returns=(Item_result) $7; lex->udf.dl=$9.str; - } + }; create2: '(' field_list ')' opt_create_table_options create3 {} - | opt_create_table_options create3 {} + | opt_create_table_options create3 {}; create3: /* empty */ {} @@ -811,34 +816,34 @@ create3: lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ; mysql_init_select(lex); } - select_options select_item_list opt_select_from union {} + select_options select_item_list opt_select_from union {}; opt_as: /* empty */ {} - | AS {} + | AS {}; opt_table_options: /* empty */ { $$= 0; } - | table_options { $$= $1;} + | table_options { $$= $1;}; table_options: table_option { $$=$1; } - | table_option table_options { $$= $1 | $2; } + | table_option table_options { $$= $1 | $2; }; table_option: - TEMPORARY { $$=HA_LEX_CREATE_TMP_TABLE; } + TEMPORARY { $$=HA_LEX_CREATE_TMP_TABLE; }; opt_if_not_exists: /* empty */ { $$= 0; } - | IF NOT EXISTS { $$=HA_LEX_CREATE_IF_NOT_EXISTS; } + | IF NOT EXISTS { $$=HA_LEX_CREATE_IF_NOT_EXISTS; }; opt_create_table_options: /* empty */ - | create_table_options + | create_table_options; create_table_options: create_table_option - | create_table_option create_table_options + | create_table_option create_table_options; create_table_option: TYPE_SYM EQ table_types { Lex->create_info.db_type= $3; } @@ -871,7 +876,7 @@ create_table_option: } | INSERT_METHOD EQ merge_insert_types { Lex->create_info.merge_insert_method= $3; Lex->create_info.used_fields|= HA_CREATE_USED_INSERT_METHOD;} | DATA_SYM DIRECTORY_SYM EQ TEXT_STRING { Lex->create_info.data_file_name= $4.str; } - | INDEX DIRECTORY_SYM EQ TEXT_STRING { Lex->create_info.index_file_name= $4.str; } + | INDEX DIRECTORY_SYM EQ TEXT_STRING { Lex->create_info.index_file_name= $4.str; }; table_types: ISAM_SYM { $$= DB_TYPE_ISAM; } @@ -879,40 +884,40 @@ table_types: | MERGE_SYM { $$= DB_TYPE_MRG_MYISAM; } | HEAP_SYM { $$= DB_TYPE_HEAP; } | BERKELEY_DB_SYM { $$= DB_TYPE_BERKELEY_DB; } - | INNOBASE_SYM { $$= DB_TYPE_INNODB; } + | INNOBASE_SYM { $$= DB_TYPE_INNODB; }; row_types: DEFAULT { $$= ROW_TYPE_DEFAULT; } | FIXED_SYM { $$= ROW_TYPE_FIXED; } | DYNAMIC_SYM { $$= ROW_TYPE_DYNAMIC; } - | COMPRESSED_SYM { $$= ROW_TYPE_COMPRESSED; } + | COMPRESSED_SYM { $$= ROW_TYPE_COMPRESSED; }; raid_types: RAID_STRIPED_SYM { $$= RAID_TYPE_0; } | RAID_0_SYM { $$= RAID_TYPE_0; } - | ULONG_NUM { $$=$1;} + | ULONG_NUM { $$=$1;}; merge_insert_types: NO_SYM { $$= MERGE_INSERT_DISABLED; } | FIRST_SYM { $$= MERGE_INSERT_TO_FIRST; } - | LAST_SYM { $$= MERGE_INSERT_TO_LAST; } + | LAST_SYM { $$= MERGE_INSERT_TO_LAST; }; opt_select_from: /* empty */ - | select_from select_lock_type + | select_from select_lock_type; udf_func_type: /* empty */ { $$ = UDFTYPE_FUNCTION; } - | AGGREGATE_SYM { $$ = UDFTYPE_AGGREGATE; } + | AGGREGATE_SYM { $$ = UDFTYPE_AGGREGATE; }; udf_type: STRING_SYM {$$ = (int) STRING_RESULT; } | REAL {$$ = (int) REAL_RESULT; } - | INT_SYM {$$ = (int) INT_RESULT; } + | INT_SYM {$$ = (int) INT_RESULT; }; field_list: field_list_item - | field_list ',' field_list_item + | field_list ',' field_list_item; field_list_item: @@ -924,28 +929,35 @@ field_list_item: | key_type opt_ident key_alg '(' key_list ')' { LEX *lex=Lex; - lex->key_list.push_back(new Key($1,$3,$2,lex->col_list)); + lex->key_list.push_back(new Key($1,$2, $3, lex->col_list)); lex->col_list.empty(); /* Alloced by sql_alloc */ } | opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references { - Lex->col_list.empty(); /* Alloced by sql_alloc */ + LEX *lex=Lex; + lex->key_list.push_back(new foreign_key($4, lex->col_list, + $8, + lex->ref_list, + lex->fk_delete_opt, + lex->fk_update_opt, + lex->fk_match_option)); + lex->col_list.empty(); /* Alloced by sql_alloc */ } | opt_constraint CHECK_SYM '(' expr ')' { Lex->col_list.empty(); /* Alloced by sql_alloc */ - } + }; opt_constraint: /* empty */ - | CONSTRAINT opt_ident + | CONSTRAINT opt_ident; field_spec: field_ident { LEX *lex=Lex; lex->length=lex->dec=0; lex->type=0; lex->interval=0; - lex->default_value=0; + lex->default_value=lex->comment=0; } type opt_attribute { @@ -953,10 +965,10 @@ field_spec: if (add_field_to_list($1.str, (enum enum_field_types) $3, lex->length,lex->dec,lex->type, - lex->default_value,lex->change, - lex->interval)) + lex->default_value, lex->comment, + lex->change,lex->interval)) YYABORT; - } + }; type: int_type opt_len field_options { Lex->length=$2; $$=$1; } @@ -1017,73 +1029,73 @@ type: LEX *lex=Lex; lex->interval=typelib(lex->interval_list); $$=FIELD_TYPE_SET; - } + }; char: CHAR_SYM {} | NCHAR_SYM {} - | NATIONAL_SYM CHAR_SYM {} + | NATIONAL_SYM CHAR_SYM {}; varchar: char VARYING {} | VARCHAR {} | NATIONAL_SYM VARCHAR {} - | NCHAR_SYM VARCHAR {} + | NCHAR_SYM VARCHAR {}; int_type: INT_SYM { $$=FIELD_TYPE_LONG; } | TINYINT { $$=FIELD_TYPE_TINY; } | SMALLINT { $$=FIELD_TYPE_SHORT; } | MEDIUMINT { $$=FIELD_TYPE_INT24; } - | BIGINT { $$=FIELD_TYPE_LONGLONG; } + | BIGINT { $$=FIELD_TYPE_LONGLONG; }; real_type: REAL { $$= current_thd->sql_mode & MODE_REAL_AS_FLOAT ? FIELD_TYPE_FLOAT : FIELD_TYPE_DOUBLE; } | DOUBLE_SYM { $$=FIELD_TYPE_DOUBLE; } - | DOUBLE_SYM PRECISION { $$=FIELD_TYPE_DOUBLE; } + | DOUBLE_SYM PRECISION { $$=FIELD_TYPE_DOUBLE; }; float_options: /* empty */ {} | '(' NUM ')' { Lex->length=$2.str; } - | precision {} + | precision {}; precision: '(' NUM ',' NUM ')' { LEX *lex=Lex; lex->length=$2.str; lex->dec=$4.str; - } + }; field_options: /* empty */ {} - | field_opt_list {} + | field_opt_list {}; field_opt_list: field_opt_list field_option {} - | field_option {} + | field_option {}; field_option: SIGNED_SYM {} | UNSIGNED { Lex->type|= UNSIGNED_FLAG;} - | ZEROFILL { Lex->type|= UNSIGNED_FLAG | ZEROFILL_FLAG; } + | ZEROFILL { Lex->type|= UNSIGNED_FLAG | ZEROFILL_FLAG; }; opt_len: /* empty */ { $$=(char*) 0; } /* use default length */ - | '(' NUM ')' { $$=$2.str; } + | '(' NUM ')' { $$=$2.str; }; opt_precision: /* empty */ {} - | precision {} + | precision {}; opt_attribute: /* empty */ {} - | opt_attribute_list {} + | opt_attribute_list {}; opt_attribute_list: opt_attribute_list attribute {} - | attribute + | attribute; attribute: NULL_SYM { Lex->type&= ~ NOT_NULL_FLAG; } @@ -1093,6 +1105,7 @@ attribute: | PRIMARY_SYM KEY_SYM { Lex->type|= PRI_KEY_FLAG | NOT_NULL_FLAG; } | UNIQUE_SYM { Lex->type|= UNIQUE_FLAG; } | UNIQUE_SYM KEY_SYM { Lex->type|= UNIQUE_KEY_FLAG; } + | COMMENT_SYM text_literal { Lex->comment= $2; }; opt_binary: /* empty */ { Lex->charset=default_charset_info; } @@ -1106,7 +1119,7 @@ opt_binary: YYABORT; } Lex->charset=cs; - } + }; default_charset: /* empty */ { Lex->charset-default_charset_info; } @@ -1119,36 +1132,50 @@ default_charset: YYABORT; } Lex->charset=cs; - } + }; references: - REFERENCES table_ident opt_on_delete {} - | REFERENCES table_ident '(' key_list ')' opt_on_delete - { - Lex->col_list.empty(); /* Alloced by sql_alloc */ - } + REFERENCES table_ident + { + LEX *lex=Lex; + lex->fk_delete_opt= lex->fk_update_opt= lex->fk_match_option= 0; + lex->ref_list.empty(); + } + opt_ref_list + { + $$=$2; + }; + +opt_ref_list: + /* empty */ opt_on_delete {} + | '(' ref_list ')' opt_on_delete {}; + +ref_list: + ref_list ',' ident { Lex->ref_list.push_back(new key_part_spec($3.str)); } + | ident { Lex->ref_list.push_back(new key_part_spec($1.str)); }; + opt_on_delete: /* empty */ {} - | opt_on_delete_list {} + | opt_on_delete_list {}; opt_on_delete_list: opt_on_delete_list opt_on_delete_item {} - | opt_on_delete_item {} - + | opt_on_delete_item {}; opt_on_delete_item: - ON DELETE_SYM delete_option {} - | ON UPDATE_SYM delete_option {} - | MATCH FULL {} - | MATCH PARTIAL {} + ON DELETE_SYM delete_option { Lex->fk_delete_opt= $3; } + | ON UPDATE_SYM delete_option { Lex->fk_update_opt= $3; } + | MATCH FULL { Lex->fk_match_option= foreign_key::FK_MATCH_FULL; } + | MATCH PARTIAL { Lex->fk_match_option= foreign_key::FK_MATCH_PARTIAL; } + | MATCH SIMPLE_SYM { Lex->fk_match_option= foreign_key::FK_MATCH_SIMPLE; }; delete_option: - RESTRICT {} - | CASCADE {} - | SET NULL_SYM {} - | NO_SYM ACTION {} - | SET DEFAULT {} + RESTRICT { $$= (int) foreign_key::FK_OPTION_RESTRICT; } + | CASCADE { $$= (int) foreign_key::FK_OPTION_CASCADE; } + | SET NULL_SYM { $$= (int) foreign_key::FK_OPTION_SET_NULL; } + | NO_SYM ACTION { $$= (int) foreign_key::FK_OPTION_NO_ACTION; } + | SET DEFAULT { $$= (int) foreign_key::FK_OPTION_DEFAULT; }; key_type: opt_constraint PRIMARY_SYM KEY_SYM { $$= Key::PRIMARY; } @@ -1158,47 +1185,46 @@ key_type: | SPATIAL_SYM { $$= Key::SPATIAL; } | SPATIAL_SYM key_or_index { $$= Key::SPATIAL; } | opt_constraint UNIQUE_SYM { $$= Key::UNIQUE; } - | opt_constraint UNIQUE_SYM key_or_index { $$= Key::UNIQUE; } + | opt_constraint UNIQUE_SYM key_or_index { $$= Key::UNIQUE; }; key_or_index: KEY_SYM {} - | INDEX {} + | INDEX {}; keys_or_index: KEYS {} | INDEX {} - | INDEXES {} + | INDEXES {}; opt_unique_or_fulltext: /* empty */ { $$= Key::MULTIPLE; } | UNIQUE_SYM { $$= Key::UNIQUE; } - | FULLTEXT_SYM { $$= Key::FULLTEXT; } - | SPATIAL_SYM { $$= Key::SPATIAL; } + | SPATIAL_SYM { $$= Key::SPATIAL; }; key_alg: /* empty */ { $$= HA_KEY_ALG_UNDEF; } - | USING opt_btree_or_rtree { $$= $2; } + | USING opt_btree_or_rtree { $$= $2; }; opt_btree_or_rtree: BTREE_SYM { $$= HA_KEY_ALG_BTREE; } | RTREE_SYM { $$= HA_KEY_ALG_RTREE; } - | HASH_SYM { $$= HA_KEY_ALG_HASH; } + | HASH_SYM { $$= HA_KEY_ALG_HASH; }; key_list: key_list ',' key_part order_dir { Lex->col_list.push_back($3); } - | key_part order_dir { Lex->col_list.push_back($1); } + | key_part order_dir { Lex->col_list.push_back($1); }; key_part: ident { $$=new key_part_spec($1.str); } - | ident '(' NUM ')' { $$=new key_part_spec($1.str,(uint) atoi($3.str)); } + | ident '(' NUM ')' { $$=new key_part_spec($1.str,(uint) atoi($3.str)); }; opt_ident: /* empty */ { $$=(char*) 0; } /* Defaultlength */ - | field_ident { $$=$1.str; } + | field_ident { $$=$1.str; }; string_list: text_string { Lex->interval_list.push_back($1); } - | string_list ',' text_string { Lex->interval_list.push_back($3); } + | string_list ',' text_string { Lex->interval_list.push_back($3); }; /* ** Alter table @@ -1225,17 +1251,18 @@ alter: bzero((char*) &lex->create_info,sizeof(lex->create_info)); lex->create_info.db_type= DB_TYPE_DEFAULT; lex->create_info.row_type= ROW_TYPE_NOT_USED; + lex->create_info.table_charset=default_charset_info; lex->alter_keys_onoff=LEAVE_AS_IS; lex->simple_alter=1; } - alter_list + alter_list; alter_list: | alter_list_item - | alter_list ',' alter_list_item + | alter_list ',' alter_list_item; add_column: - ADD opt_column { Lex->change=0; } + ADD opt_column { Lex->change=0; }; alter_list_item: add_column field_list_item opt_place { Lex->simple_alter=0; } @@ -1246,25 +1273,24 @@ alter_list_item: lex->change= $3.str; lex->simple_alter=0; } field_spec opt_place - | MODIFY_SYM opt_column field_ident - { - LEX *lex=Lex; - lex->length=lex->dec=0; lex->type=0; lex->interval=0; - lex->default_value=0; + | MODIFY_SYM opt_column field_ident + { + LEX *lex=Lex; + lex->length=lex->dec=0; lex->type=0; lex->interval=0; + lex->default_value=lex->comment=0; lex->simple_alter=0; - } - type opt_attribute - { - LEX *lex=Lex; - if (add_field_to_list($3.str, - (enum enum_field_types) $5, - lex->length,lex->dec,lex->type, - lex->default_value, $3.str, - lex->interval)) - YYABORT; - lex->simple_alter=0; - } - opt_place + } + type opt_attribute + { + LEX *lex=Lex; + if (add_field_to_list($3.str, + (enum enum_field_types) $5, + lex->length,lex->dec,lex->type, + lex->default_value, lex->comment, + $3.str, lex->interval)) + YYABORT; + } + opt_place | DROP opt_column field_ident opt_restrict { LEX *lex=Lex; @@ -1298,38 +1324,38 @@ alter_list_item: lex->alter_list.push_back(new Alter_column($3.str,(Item*) 0)); lex->simple_alter=0; } - | RENAME opt_to table_alias table_ident + | RENAME opt_to table_ident { LEX *lex=Lex; - lex->select->db=$4->db.str; - lex->name= $4->table.str; - lex->simple_alter=0; + lex->select->db=$3->db.str; + lex->name= $3->table.str; } | create_table_options { Lex->simple_alter=0; } - | order_clause { Lex->simple_alter=0; } + | order_clause { Lex->simple_alter=0; }; opt_column: /* empty */ {} - | COLUMN_SYM {} + | COLUMN_SYM {}; opt_ignore: /* empty */ { Lex->duplicates=DUP_ERROR; } - | IGNORE_SYM { Lex->duplicates=DUP_IGNORE; } + | IGNORE_SYM { Lex->duplicates=DUP_IGNORE; }; opt_restrict: /* empty */ {} | RESTRICT {} - | CASCADE {} + | CASCADE {}; opt_place: /* empty */ {} | AFTER_SYM ident { store_position_for_column($2.str); } - | FIRST_SYM { store_position_for_column(first_keyword); } + | FIRST_SYM { store_position_for_column(first_keyword); }; opt_to: /* empty */ {} | TO_SYM {} - | AS {} + | EQ {} + | AS {}; slave: SLAVE START_SYM slave_thread_opts @@ -1347,7 +1373,7 @@ slave: }; slave_thread_opts: slave_thread_opt - | slave_thread_opts ',' slave_thread_opt + | slave_thread_opts ',' slave_thread_opt; slave_thread_opt: /*empty*/ {} @@ -1358,7 +1384,7 @@ slave_thread_opt: | IO_THREAD { Lex->slave_thd_opt|=SLAVE_IO; - } + }; restore: RESTORE_SYM table_or_tables @@ -1368,7 +1394,7 @@ restore: table_list FROM TEXT_STRING { Lex->backup_dir = $6.str; - } + }; backup: BACKUP_SYM table_or_tables { @@ -1377,7 +1403,7 @@ backup: table_list TO_SYM TEXT_STRING { Lex->backup_dir = $6.str; - } + }; repair: REPAIR table_or_tables @@ -1386,20 +1412,20 @@ repair: lex->sql_command = SQLCOM_REPAIR; lex->check_opt.init(); } - table_list opt_mi_repair_type + table_list opt_mi_repair_type; opt_mi_repair_type: /* empty */ { Lex->check_opt.flags = T_MEDIUM; } - | mi_repair_types {} + | mi_repair_types {}; mi_repair_types: mi_repair_type {} - | mi_repair_type mi_repair_types {} + | mi_repair_type mi_repair_types {}; mi_repair_type: QUICK { Lex->check_opt.flags|= T_QUICK; } | EXTENDED_SYM { Lex->check_opt.flags|= T_EXTEND; } - | USE_FRM { Lex->check_opt.sql_flags|= TT_USEFRM; } + | USE_FRM { Lex->check_opt.sql_flags|= TT_USEFRM; }; analyze: ANALYZE_SYM table_or_tables @@ -1408,7 +1434,7 @@ analyze: lex->sql_command = SQLCOM_ANALYZE; lex->check_opt.init(); } - table_list opt_mi_check_type + table_list opt_mi_check_type; check: CHECK_SYM table_or_tables @@ -1417,22 +1443,22 @@ check: lex->sql_command = SQLCOM_CHECK; lex->check_opt.init(); } - table_list opt_mi_check_type + table_list opt_mi_check_type; opt_mi_check_type: /* empty */ { Lex->check_opt.flags = T_MEDIUM; } - | mi_check_types {} + | mi_check_types {}; mi_check_types: mi_check_type {} - | mi_check_type mi_check_types {} + | mi_check_type mi_check_types {}; mi_check_type: QUICK { Lex->check_opt.flags|= T_QUICK; } | FAST_SYM { Lex->check_opt.flags|= T_FAST; } | MEDIUM_SYM { Lex->check_opt.flags|= T_MEDIUM; } | EXTENDED_SYM { Lex->check_opt.flags|= T_EXTEND; } - | CHANGED { Lex->check_opt.flags|= T_CHECK_ONLY_CHANGED; } + | CHANGED { Lex->check_opt.flags|= T_CHECK_ONLY_CHANGED; }; optimize: OPTIMIZE table_or_tables @@ -1441,25 +1467,25 @@ optimize: lex->sql_command = SQLCOM_OPTIMIZE; lex->check_opt.init(); } - table_list opt_mi_check_type + table_list opt_mi_check_type; rename: RENAME table_or_tables { Lex->sql_command=SQLCOM_RENAME_TABLE; } - table_to_table_list + table_to_table_list; table_to_table_list: table_to_table - | table_to_table_list ',' table_to_table + | table_to_table_list ',' table_to_table; table_to_table: table_ident TO_SYM table_ident { if (!add_table_to_list($1,NULL,1,TL_IGNORE) || !add_table_to_list($3,NULL,1,TL_IGNORE)) YYABORT; - } + }; /* Select : retrieve data from table @@ -1467,12 +1493,12 @@ table_to_table: select: - select_init { Lex->sql_command=SQLCOM_SELECT; } + select_init { Lex->sql_command=SQLCOM_SELECT; }; select_init: SELECT_SYM select_part2 { Select->braces=false; } union | - '(' SELECT_SYM select_part2 ')' { Select->braces=true;} union_opt + '(' SELECT_SYM select_part2 ')' { Select->braces=true;} union_opt; select_part2: @@ -1481,25 +1507,25 @@ select_part2: lex->lock_option=TL_READ; mysql_init_select(lex); } - select_options select_item_list select_into select_lock_type + select_options select_item_list select_into select_lock_type; select_into: limit_clause {} | select_from | opt_into select_from - | select_from opt_into + | select_from opt_into; select_from: - FROM join_table_list where_clause group_clause having_clause opt_order_clause limit_clause procedure_clause + FROM join_table_list where_clause group_clause having_clause opt_order_clause limit_clause procedure_clause; select_options: /* empty*/ - | select_option_list + | select_option_list; select_option_list: select_option_list select_option - | select_option + | select_option; select_option: STRAIGHT_JOIN { Select->options|= SELECT_STRAIGHT_JOIN; } @@ -1511,14 +1537,14 @@ select_option: | SQL_CALC_FOUND_ROWS { if (Select != &Lex->select_lex) YYABORT; Select->options|= OPTION_FOUND_ROWS; } | SQL_NO_CACHE_SYM { if (Select != &Lex->select_lex) YYABORT; current_thd->safe_to_cache_query=0; } | SQL_CACHE_SYM { if (Select != &Lex->select_lex) YYABORT; Select->options |= OPTION_TO_QUERY_CACHE; } - | ALL {} + | ALL {}; select_lock_type: /* empty */ | FOR_SYM UPDATE_SYM { if (Select != &Lex->select_lex) YYABORT; Lex->lock_option= TL_WRITE; current_thd->safe_to_cache_query=0; } | LOCK_SYM IN_SYM SHARE_SYM MODE_SYM - { if (Select != &Lex->select_lex) YYABORT; Lex->lock_option= TL_READ_WITH_SHARED_LOCKS; current_thd->safe_to_cache_query=0; } + { if (Select != &Lex->select_lex) YYABORT; Lex->lock_option= TL_READ_WITH_SHARED_LOCKS; current_thd->safe_to_cache_query=0; }; select_item_list: select_item_list ',' select_item @@ -1527,7 +1553,7 @@ select_item_list: { if (add_item_to_list(new Item_field(NULL,NULL,"*"))) YYABORT; - } + }; select_item: @@ -1539,32 +1565,32 @@ select_item: $2->set_name($4.str); else if (!$2->name) $2->set_name($1,(uint) ($3 - $1)); - } + }; remember_name: - { $$=(char*) Lex->tok_start; } + { $$=(char*) Lex->tok_start; }; remember_end: - { $$=(char*) Lex->tok_end; } + { $$=(char*) Lex->tok_end; }; select_item2: table_wild { $$=$1; } /* table.* */ - | expr { $$=$1; } + | expr { $$=$1; }; select_alias: { $$.str=0;} | AS ident { $$=$2; } | AS TEXT_STRING { $$=$2; } | ident { $$=$1; } - | TEXT_STRING { $$=$1; } + | TEXT_STRING { $$=$1; }; optional_braces: /* empty */ {} - | '(' ')' {} + | '(' ')' {}; /* all possible expressions */ expr: expr_expr {$$ = $1; } - | simple_expr {$$ = $1; } + | simple_expr {$$ = $1; }; /* expressions that begin with 'expr' */ expr_expr: @@ -1604,7 +1630,7 @@ expr_expr: | expr '+' INTERVAL_SYM expr interval { $$= new Item_date_add_interval($1,$4,$5,0); } | expr '-' INTERVAL_SYM expr interval - { $$= new Item_date_add_interval($1,$4,$5,1); } + { $$= new Item_date_add_interval($1,$4,$5,1); }; /* expressions that begin with 'expr' that do NOT follow IN_SYM */ no_in_expr: @@ -1641,7 +1667,7 @@ no_in_expr: { $$= new Item_date_add_interval($1,$4,$5,0); } | no_in_expr '-' INTERVAL_SYM expr interval { $$= new Item_date_add_interval($1,$4,$5,1); } - | simple_expr + | simple_expr; /* expressions that begin with 'expr' that does NOT follow AND */ no_and_expr: @@ -1681,7 +1707,7 @@ no_and_expr: { $$= new Item_date_add_interval($1,$4,$5,0); } | no_and_expr '-' INTERVAL_SYM expr interval { $$= new Item_date_add_interval($1,$4,$5,1); } - | simple_expr + | simple_expr; simple_expr: simple_ident @@ -2014,11 +2040,11 @@ simple_expr: current_thd->safe_to_cache_query=0; } | EXTRACT_SYM '(' interval FROM expr ')' - { $$=new Item_extract( $3, $5); } + { $$=new Item_extract( $3, $5); }; udf_expr_list: /* empty */ { $$= NULL; } - | expr_list { $$= $1;} + | expr_list { $$= $1;}; sum_expr: AVG_SYM '(' in_sum_expr ')' @@ -2042,7 +2068,7 @@ sum_expr: | STD_SYM '(' in_sum_expr ')' { $$=new Item_sum_std($3); } | SUM_SYM '(' in_sum_expr ')' - { $$=new Item_sum_sum($3); } + { $$=new Item_sum_sum($3); }; in_sum_expr: { Select->in_sum_expr++; } @@ -2050,7 +2076,7 @@ in_sum_expr: { Select->in_sum_expr--; $$=$2; - } + }; cast_type: BINARY { $$=ITEM_CAST_BINARY; } @@ -2060,42 +2086,42 @@ cast_type: | UNSIGNED INT_SYM { $$=ITEM_CAST_UNSIGNED_INT; } | DATE_SYM { $$=ITEM_CAST_DATE; } | TIME_SYM { $$=ITEM_CAST_TIME; } - | DATETIME { $$=ITEM_CAST_DATETIME; } + | DATETIME { $$=ITEM_CAST_DATETIME; }; expr_list: { Select->expr_list.push_front(new List<Item>); } expr_list2 - { $$= Select->expr_list.pop(); } + { $$= Select->expr_list.pop(); }; expr_list2: expr { Select->expr_list.head()->push_back($1); } - | expr_list2 ',' expr { Select->expr_list.head()->push_back($3); } + | expr_list2 ',' expr { Select->expr_list.head()->push_back($3); }; ident_list_arg: ident_list { $$= $1; } - | '(' ident_list ')' { $$= $2; } + | '(' ident_list ')' { $$= $2; }; ident_list: { Select->expr_list.push_front(new List<Item>); } ident_list2 - { $$= Select->expr_list.pop(); } + { $$= Select->expr_list.pop(); }; ident_list2: simple_ident { Select->expr_list.head()->push_back($1); } - | ident_list2 ',' simple_ident { Select->expr_list.head()->push_back($3); } + | ident_list2 ',' simple_ident { Select->expr_list.head()->push_back($3); }; opt_expr: /* empty */ { $$= NULL; } - | expr { $$= $1; } + | expr { $$= $1; }; opt_else: /* empty */ { $$= NULL; } - | ELSE expr { $$= $2; } + | ELSE expr { $$= $2; }; when_list: { Select->when_list.push_front(new List<Item>); } when_list2 - { $$= Select->when_list.pop(); } + { $$= Select->when_list.pop(); }; when_list2: expr THEN_SYM expr @@ -2109,11 +2135,11 @@ when_list2: SELECT_LEX *sel=Select; sel->when_list.head()->push_back($3); sel->when_list.head()->push_back($5); - } + }; opt_pad: /* empty */ { $$=new Item_string(" ",1,default_charset_info); } - | expr { $$=$1; } + | expr { $$=$1; }; join_table_list: '(' join_table_list ')' { $$=$2; } @@ -2155,12 +2181,12 @@ join_table_list: | join_table_list NATURAL RIGHT opt_outer JOIN_SYM join_table { add_join_natural($6,$1); $1->outer_join|=JOIN_TYPE_RIGHT; $$=$1; } | join_table_list NATURAL JOIN_SYM join_table - { add_join_natural($1,$4); $$=$4; } + { add_join_natural($1,$4); $$=$4; }; normal_join: ',' {} | JOIN_SYM {} - | CROSS JOIN_SYM {} + | CROSS JOIN_SYM {}; join_table: { @@ -2176,14 +2202,14 @@ join_table: | '{' ident join_table LEFT OUTER JOIN_SYM join_table ON expr '}' { add_join_on($7,$9); $7->outer_join|=JOIN_TYPE_LEFT; $$=$7; } | '(' SELECT_SYM select_part3 ')' opt_table_alias - { - LEX *lex=Lex; - SELECT_LEX *select_to_execute= lex->select; - lex->select=lex->select->prev; - if (!($$=add_table_to_list(new Table_ident(select_to_execute), - $5,0,TL_UNLOCK))) - YYABORT; - } + { + LEX *lex=Lex; + SELECT_LEX *select_to_execute= lex->select; + lex->select=lex->select->prev; + if (!($$=add_table_to_list(new Table_ident(select_to_execute), + $5,0,TL_UNLOCK))) + YYABORT; + }; select_part3: { @@ -2204,7 +2230,7 @@ select_intoto: opt_outer: /* empty */ {} - | OUTER {} + | OUTER {}; opt_key_definition: /* empty */ {} @@ -2219,11 +2245,11 @@ opt_key_definition: SELECT_LEX *sel=Select; sel->ignore_index= *$2; sel->ignore_index_ptr= &sel->ignore_index; - } + }; key_usage_list: key_or_index { Select->interval_list.empty(); } '(' key_usage_list2 ')' - { $$= &Select->interval_list; } + { $$= &Select->interval_list; }; key_usage_list2: key_usage_list2 ',' ident @@ -2231,7 +2257,7 @@ key_usage_list2: | ident { Select->interval_list.push_back(new String((const char*) $1.str,$1.length,default_charset_info)); } | PRIMARY_SYM - { Select->interval_list.push_back(new String("PRIMARY",7,default_charset_info)); } + { Select->interval_list.push_back(new String("PRIMARY",7,default_charset_info)); }; using_list: ident @@ -2245,7 +2271,7 @@ using_list: SELECT_LEX *sel=Select; if (!($$= new Item_cond_and(new Item_func_eq(new Item_field(sel->db1,sel->table1,$3.str), new Item_field(sel->db2,sel->table2,$3.str)), $1))) YYABORT; - } + }; interval: DAY_HOUR_SYM { $$=INTERVAL_DAY_HOUR; } @@ -2260,22 +2286,22 @@ interval: | MONTH_SYM { $$=INTERVAL_MONTH; } | SECOND_SYM { $$=INTERVAL_SECOND; } | YEAR_MONTH_SYM { $$=INTERVAL_YEAR_MONTH; } - | YEAR_SYM { $$=INTERVAL_YEAR; } + | YEAR_SYM { $$=INTERVAL_YEAR; }; table_alias: /* empty */ | AS - | EQ + | EQ; opt_table_alias: /* empty */ { $$=0; } | table_alias ident - { $$= (LEX_STRING*) sql_memdup(&$2,sizeof(LEX_STRING)); } + { $$= (LEX_STRING*) sql_memdup(&$2,sizeof(LEX_STRING)); }; where_clause: /* empty */ { Select->where= 0; } - | WHERE expr { Select->where= $2; } + | WHERE expr { Select->where= $2; }; having_clause: /* empty */ @@ -2283,11 +2309,11 @@ having_clause: { SELECT_LEX *sel=Select; sel->having= $3; sel->create_refs=0; - } + }; opt_escape: ESCAPE_SYM TEXT_STRING { $$= $2.str; } - | /* empty */ { $$= (char*) "\\"; } + | /* empty */ { $$= (char*) "\\"; }; /* @@ -2296,13 +2322,13 @@ opt_escape: group_clause: /* empty */ - | GROUP BY group_list + | GROUP BY group_list; group_list: group_list ',' order_ident order_dir { if (add_group_to_list($3,(bool) $4)) YYABORT; } | order_ident order_dir - { if (add_group_to_list($1,(bool) $2)) YYABORT; } + { if (add_group_to_list($1,(bool) $2)) YYABORT; }; /* Order by statement in select @@ -2310,7 +2336,7 @@ group_list: opt_order_clause: /* empty */ - | order_clause + | order_clause; order_clause: ORDER_SYM BY @@ -2319,18 +2345,18 @@ order_clause: if (lex->sql_command == SQLCOM_MULTI_UPDATE) YYABORT; lex->select->sort_default=1; - } order_list + } order_list; order_list: order_list ',' order_ident order_dir { if (add_order_to_list($3,(bool) $4)) YYABORT; } | order_ident order_dir - { if (add_order_to_list($1,(bool) $2)) YYABORT; } + { if (add_order_to_list($1,(bool) $2)) YYABORT; }; order_dir: /* empty */ { $$ = 1; } | ASC { $$ =1; } - | DESC { $$ =0; } + | DESC { $$ =0; }; limit_clause: @@ -2345,7 +2371,7 @@ limit_clause: { SELECT_LEX *sel=Select; sel->select_limit= $4; sel->offset_limit=$2; - } + }; delete_limit_clause: /* empty */ @@ -2356,20 +2382,20 @@ delete_limit_clause: lex->select->select_limit= HA_POS_ERROR; } | LIMIT ulonglong_num - { Select->select_limit= (ha_rows) $2; } + { Select->select_limit= (ha_rows) $2; }; ULONG_NUM: NUM { $$= strtoul($1.str,NULL,10); } | ULONGLONG_NUM { $$= (ulong) strtoull($1.str,NULL,10); } | REAL_NUM { $$= strtoul($1.str,NULL,10); } - | FLOAT_NUM { $$= strtoul($1.str,NULL,10); } + | FLOAT_NUM { $$= strtoul($1.str,NULL,10); }; ulonglong_num: NUM { $$= (ulonglong) strtoul($1.str,NULL,10); } | ULONGLONG_NUM { $$= strtoull($1.str,NULL,10); } | LONG_NUM { $$= (ulonglong) strtoul($1.str,NULL,10); } | REAL_NUM { $$= strtoull($1.str,NULL,10); } - | FLOAT_NUM { $$= strtoull($1.str,NULL,10); } + | FLOAT_NUM { $$= strtoull($1.str,NULL,10); }; procedure_clause: /* empty */ @@ -2383,16 +2409,16 @@ procedure_clause: YYABORT; current_thd->safe_to_cache_query=0; } - '(' procedure_list ')' + '(' procedure_list ')'; procedure_list: /* empty */ {} - | procedure_list2 {} + | procedure_list2 {}; procedure_list2: procedure_list2 ',' procedure_item - | procedure_item + | procedure_item; procedure_item: remember_name expr @@ -2401,7 +2427,7 @@ procedure_item: YYABORT; if (!$2->name) $2->set_name($1,(uint) ((char*) Lex->tok_end - $1)); - } + }; opt_into: INTO OUTFILE TEXT_STRING @@ -2414,7 +2440,7 @@ opt_into: { if (!(Lex->exchange= new sql_exchange($3.str,1))) YYABORT; - } + }; /* DO statement @@ -2427,7 +2453,7 @@ do: DO_SYM if (!(lex->insert_list = new List_item)) YYABORT; } - values + values; /* Drop : delete tables or index */ @@ -2461,27 +2487,27 @@ drop: LEX *lex=Lex; lex->sql_command = SQLCOM_DROP_FUNCTION; lex->udf.name=$3.str; - } + }; table_list: table_name - | table_list ',' table_name + | table_list ',' table_name; table_name: table_ident - { if (!add_table_to_list($1,NULL,1)) YYABORT; } + { if (!add_table_to_list($1,NULL,1)) YYABORT; }; if_exists: /* empty */ { $$=0; } - | IF EXISTS { $$= 1; } + | IF EXISTS { $$= 1; }; /* ** Insert : add new data to table */ insert: - INSERT { Lex->sql_command = SQLCOM_INSERT; } insert_lock_option opt_ignore insert2 insert_field_spec + INSERT { Lex->sql_command = SQLCOM_INSERT; } insert_lock_option opt_ignore insert2 insert_field_spec; replace: REPLACE @@ -2490,21 +2516,21 @@ replace: lex->sql_command = SQLCOM_REPLACE; lex->duplicates= DUP_REPLACE; } - replace_lock_option insert2 insert_field_spec + replace_lock_option insert2 insert_field_spec; insert_lock_option: /* empty */ { Lex->lock_option= TL_WRITE_CONCURRENT_INSERT; } | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; } | DELAYED_SYM { Lex->lock_option= TL_WRITE_DELAYED; } - | HIGH_PRIORITY { Lex->lock_option= TL_WRITE; } + | HIGH_PRIORITY { Lex->lock_option= TL_WRITE; }; replace_lock_option: opt_low_priority {} - | DELAYED_SYM { Lex->lock_option= TL_WRITE_DELAYED; } + | DELAYED_SYM { Lex->lock_option= TL_WRITE_DELAYED; }; insert2: INTO insert_table {} - | insert_table {} + | insert_table {}; insert_table: table_name @@ -2513,7 +2539,7 @@ insert_table: lex->field_list.empty(); lex->many_values.empty(); lex->insert_list=0; - } + }; insert_field_spec: opt_field_spec insert_values {} @@ -2524,16 +2550,16 @@ insert_field_spec: lex->many_values.push_back(lex->insert_list)) YYABORT; } - ident_eq_list + ident_eq_list; opt_field_spec: /* empty */ { } | '(' fields ')' { } - | '(' ')' { } + | '(' ')' { }; fields: fields ',' insert_ident { Lex->field_list.push_back($3); } - | insert_ident { Lex->field_list.push_back($1); } + | insert_ident { Lex->field_list.push_back($1); }; insert_values: VALUES values_list {} @@ -2545,16 +2571,17 @@ insert_values: lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ; mysql_init_select(lex); } - select_options select_item_list select_from select_lock_type union {} + select_options select_item_list select_from select_lock_type + union {}; values_list: values_list ',' no_braces - | no_braces + | no_braces; ident_eq_list: ident_eq_list ',' ident_eq_value | - ident_eq_value + ident_eq_value; ident_eq_value: simple_ident equal expr @@ -2563,10 +2590,10 @@ ident_eq_value: if (lex->field_list.push_back($1) || lex->insert_list->push_back($3)) YYABORT; - } + }; equal: EQ {} - | SET_VAR {} + | SET_VAR {}; no_braces: '(' @@ -2579,11 +2606,11 @@ no_braces: LEX *lex=Lex; if (lex->many_values.push_back(lex->insert_list)) YYABORT; - } + }; opt_values: /* empty */ {} - | values + | values; values: values ',' expr @@ -2595,7 +2622,7 @@ values: { if (Lex->insert_list->push_back($1)) YYABORT; - } + }; /* Update rows in a table */ @@ -2608,7 +2635,7 @@ update: lex->select->order_list.first=0; lex->select->order_list.next= (byte**) &lex->select->order_list.first; } - opt_low_priority opt_ignore join_table_list SET update_list where_clause opt_order_clause delete_limit_clause + opt_low_priority opt_ignore join_table_list SET update_list where_clause opt_order_clause delete_limit_clause; update_list: update_list ',' simple_ident equal expr @@ -2620,11 +2647,11 @@ update_list: { if (add_item_to_list($1) || add_value_to_list($3)) YYABORT; - } + }; opt_low_priority: /* empty */ { Lex->lock_option= current_thd->update_lock_default; } - | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; } + | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; }; /* Delete rows from a table */ @@ -2638,7 +2665,7 @@ delete: lex->select->order_list.first=0; lex->select->order_list.next= (byte**) &lex->select->order_list.first; } - opt_delete_options single_multi {} + opt_delete_options single_multi {}; single_multi: FROM table_name where_clause opt_order_clause delete_limit_clause {} @@ -2647,11 +2674,11 @@ single_multi: FROM join_table_list where_clause | FROM table_wild_list { mysql_init_multi_delete(Lex); } - USING join_table_list where_clause + USING join_table_list where_clause; table_wild_list: table_wild_one {} - | table_wild_list ',' table_wild_one {} + | table_wild_list ',' table_wild_one {}; table_wild_one: ident opt_wild @@ -2663,20 +2690,20 @@ table_wild_one: { if (!add_table_to_list(new Table_ident($1,$3,0),NULL,1,TL_WRITE)) YYABORT; - } + }; opt_wild: /* empty */ {} - | '.' '*' {} + | '.' '*' {}; opt_delete_options: /* empty */ {} - | opt_delete_option opt_delete_options {} + | opt_delete_option opt_delete_options {}; opt_delete_option: QUICK { Select->options|= OPTION_QUICK; } - | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; } + | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; }; truncate: TRUNCATE_SYM opt_table_sym table_name @@ -2687,15 +2714,15 @@ truncate: lex->select->order_list.elements=0; lex->select->order_list.first=0; lex->select->order_list.next= (byte**) &lex->select->order_list.first; - lex->lock_option= current_thd->update_lock_default; } + lex->lock_option= current_thd->update_lock_default; }; opt_table_sym: /* empty */ - | TABLE_SYM + | TABLE_SYM; /* Show things */ -show: SHOW { Lex->wild=0;} show_param +show: SHOW { Lex->wild=0;} show_param; show_param: DATABASES wild @@ -2789,31 +2816,31 @@ show_param: | SLAVE STATUS_SYM { Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT; - } + }; opt_db: /* empty */ { $$= 0; } - | from_or_in ident { $$= $2.str; } + | from_or_in ident { $$= $2.str; }; wild: /* empty */ - | LIKE text_string { Lex->wild= $2; } + | LIKE text_string { Lex->wild= $2; }; opt_full: /* empty */ { Lex->verbose=0; } - | FULL { Lex->verbose=1; } + | FULL { Lex->verbose=1; }; from_or_in: FROM - | IN_SYM + | IN_SYM; binlog_in: /* empty */ { Lex->mi.log_file_name = 0; } - | IN_SYM TEXT_STRING { Lex->mi.log_file_name = $2.str; } + | IN_SYM TEXT_STRING { Lex->mi.log_file_name = $2.str; }; binlog_from: /* empty */ { Lex->mi.pos = 4; /* skip magic number */ } - | FROM ulonglong_num { Lex->mi.pos = $2; } + | FROM ulonglong_num { Lex->mi.pos = $2; }; /* A Oracle compatible synonym for show */ @@ -2828,17 +2855,19 @@ describe: YYABORT; } opt_describe_column - | describe_command select { Lex->select_lex.options|= SELECT_DESCRIBE; } + | describe_command select + { Lex->select_lex.options|= SELECT_DESCRIBE; }; describe_command: DESC - | DESCRIBE + | DESCRIBE; opt_describe_column: /* empty */ {} | text_string { Lex->wild= $1; } - | ident { Lex->wild= new String((const char*) $1.str,$1.length,default_charset_info); } + | ident + { Lex->wild= new String((const char*) $1.str,$1.length,default_charset_info); }; /* flush things */ @@ -2849,11 +2878,11 @@ flush: LEX *lex=Lex; lex->sql_command= SQLCOM_FLUSH; lex->type=0; } - flush_options + flush_options; flush_options: flush_options ',' flush_option - | flush_option + | flush_option; flush_option: table_or_tables { Lex->type|= REFRESH_TABLES; } opt_table_list @@ -2865,26 +2894,26 @@ flush_option: | STATUS_SYM { Lex->type|= REFRESH_STATUS; } | SLAVE { Lex->type|= REFRESH_SLAVE; } | MASTER_SYM { Lex->type|= REFRESH_MASTER; } - | DES_KEY_FILE { Lex->type|= REFRESH_DES_KEY_FILE; } + | DES_KEY_FILE { Lex->type|= REFRESH_DES_KEY_FILE; }; opt_table_list: /* empty */ {} - | table_list {} + | table_list {}; reset: RESET_SYM { LEX *lex=Lex; lex->sql_command= SQLCOM_RESET; lex->type=0; - } reset_options + } reset_options; reset_options: reset_options ',' reset_option - | reset_option + | reset_option; reset_option: SLAVE { Lex->type|= REFRESH_SLAVE; } | MASTER_SYM { Lex->type|= REFRESH_MASTER; } - | QUERY_SYM CACHE_SYM { Lex->type|= REFRESH_QUERY_CACHE;} + | QUERY_SYM CACHE_SYM { Lex->type|= REFRESH_QUERY_CACHE;}; purge: PURGE @@ -2896,7 +2925,7 @@ purge: MASTER_SYM LOGS_SYM TO_SYM TEXT_STRING { Lex->to_log = $6.str; - } + } ; /* kill threads */ @@ -2911,7 +2940,7 @@ kill: } lex->sql_command=SQLCOM_KILL; lex->thread_id= (ulong) $2->val_int(); - } + }; /* change database */ @@ -2919,7 +2948,7 @@ use: USE_SYM ident { LEX *lex=Lex; lex->sql_command=SQLCOM_CHANGE_DB; lex->select->db= $2.str; - } + }; /* import, export of files */ @@ -2950,30 +2979,30 @@ load: LOAD DATA_SYM load_data_lock opt_local INFILE TEXT_STRING LOAD DATA_SYM FROM MASTER_SYM { Lex->sql_command = SQLCOM_LOAD_MASTER_DATA; - } + }; opt_local: /* empty */ { $$=0;} - | LOCAL_SYM { $$=1;} + | LOCAL_SYM { $$=1;}; load_data_lock: /* empty */ { Lex->lock_option= current_thd->update_lock_default; } | CONCURRENT { Lex->lock_option= TL_WRITE_CONCURRENT_INSERT ; } - | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; } + | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; }; opt_duplicate: /* empty */ { Lex->duplicates=DUP_ERROR; } | REPLACE { Lex->duplicates=DUP_REPLACE; } - | IGNORE_SYM { Lex->duplicates=DUP_IGNORE; } + | IGNORE_SYM { Lex->duplicates=DUP_IGNORE; }; opt_field_term: /* empty */ - | COLUMNS field_term_list + | COLUMNS field_term_list; field_term_list: field_term_list field_term - | field_term + | field_term; field_term: TERMINATED BY text_string { Lex->exchange->field_term= $3;} @@ -2984,31 +3013,31 @@ field_term: lex->exchange->opt_enclosed=1; } | ENCLOSED BY text_string { Lex->exchange->enclosed= $3;} - | ESCAPED BY text_string { Lex->exchange->escaped= $3;} + | ESCAPED BY text_string { Lex->exchange->escaped= $3;}; opt_line_term: /* empty */ - | LINES line_term_list + | LINES line_term_list; line_term_list: line_term_list line_term - | line_term + | line_term; line_term: TERMINATED BY text_string { Lex->exchange->line_term= $3;} - | STARTING BY text_string { Lex->exchange->line_start= $3;} + | STARTING BY text_string { Lex->exchange->line_start= $3;}; opt_ignore_lines: /* empty */ | IGNORE_SYM NUM LINES - { Lex->exchange->skip_lines=atol($2.str); } + { Lex->exchange->skip_lines=atol($2.str); }; /* Common definitions */ text_literal: TEXT_STRING { $$ = new Item_string($1.str,$1.length,default_charset_info); } | text_literal TEXT_STRING - { ((Item_string*) $1)->append($2.str,$2.length); } + { ((Item_string*) $1)->append($2.str,$2.length); }; text_string: TEXT_STRING { $$= new String($1.str,$1.length,default_charset_info); } @@ -3016,7 +3045,7 @@ text_string: { Item *tmp = new Item_varbinary($1.str,$1.length,default_charset_info); $$= tmp ? tmp->val_str((String*) 0) : (String*) 0; - } + }; literal: text_literal { $$ = $1; } @@ -3030,7 +3059,7 @@ literal: | HEX_NUM { $$ = new Item_varbinary($1.str,$1.length,default_charset_info);} | DATE_SYM text_literal { $$ = $2; } | TIME_SYM text_literal { $$ = $2; } - | TIMESTAMP text_literal { $$ = $2; } + | TIMESTAMP text_literal { $$ = $2; }; /********************************************************************** ** Createing different items. @@ -3038,15 +3067,16 @@ literal: insert_ident: simple_ident { $$=$1; } - | table_wild { $$=$1; } + | table_wild { $$=$1; }; table_wild: ident '.' '*' { $$ = new Item_field(NullS,$1.str,"*"); } | ident '.' ident '.' '*' - { $$ = new Item_field((current_thd->client_capabilities & CLIENT_NO_SCHEMA ? NullS : $1.str),$3.str,"*"); } + { $$ = new Item_field((current_thd->client_capabilities & + CLIENT_NO_SCHEMA ? NullS : $1.str),$3.str,"*"); }; order_ident: - expr { $$=$1; } + expr { $$=$1; }; simple_ident: ident @@ -3068,18 +3098,19 @@ simple_ident: { SELECT_LEX *sel=Select; $$ = !sel->create_refs || sel->in_sum_expr > 0 ? (Item*) new Item_field((current_thd->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str) : (Item*) new Item_ref((current_thd->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str); - } + }; field_ident: ident { $$=$1;} | ident '.' ident { $$=$3;} /* Skipp schema name in create*/ - | '.' ident { $$=$2;} /* For Delphi */ + | '.' ident { $$=$2;} /* For Delphi */; table_ident: ident { $$=new Table_ident($1); } | ident '.' ident { $$=new Table_ident($1,$3,0);} - | '.' ident { $$=new Table_ident($2);} /* For Delphi */ + | '.' ident { $$=new Table_ident($2);} + /* For Delphi */; ident: IDENT { $$=$1; } @@ -3090,12 +3121,12 @@ ident: $$.length=$1.length; if ((lex=Lex)->next_state != STATE_END) lex->next_state=STATE_OPERATOR_OR_IDENT; - } + }; ident_or_text: ident { $$=$1;} | TEXT_STRING { $$=$1;} - | LEX_HOSTNAME { $$=$1;} + | LEX_HOSTNAME { $$=$1;}; user: ident_or_text @@ -3109,7 +3140,7 @@ user: if (!($$=(LEX_USER*) sql_alloc(sizeof(st_lex_user)))) YYABORT; $$->user = $1; $$->host=$3; - } + }; /* Keyword that we allow for identifiers */ @@ -3192,7 +3223,9 @@ keyword: | MASTER_USER_SYM {} | MASTER_PASSWORD_SYM {} | MASTER_CONNECT_RETRY_SYM {} + | MAX_CONNECTIONS_PER_HOUR {} | MAX_QUERIES_PER_HOUR {} + | MAX_UPDATES_PER_HOUR {} | MEDIUM_SYM {} | MERGE_SYM {} | MINUTE_SYM {} @@ -3209,6 +3242,7 @@ keyword: | OFF {} | OPEN_SYM {} | PACK_KEYS_SYM {} + | PARTIAL {} | PASSWORD {} | PREV_SYM {} | PROCESS {} @@ -3220,12 +3254,13 @@ keyword: | RAID_CHUNKSIZE {} | RAID_STRIPED_SYM {} | RAID_TYPE {} - | RELAY_LOG_FILE_SYM {} - | RELAY_LOG_POS_SYM {} + | RELAY_LOG_FILE_SYM {} + | RELAY_LOG_POS_SYM {} | RELOAD {} | REPAIR {} | REPEATABLE_SYM {} | RESET_SYM {} + | RESOURCES {} | RESTORE_SYM {} | ROLLBACK_SYM {} | ROWS_SYM {} @@ -3235,6 +3270,7 @@ keyword: | SERIALIZABLE_SYM {} | SESSION_SYM {} | SIGNED_SYM {} + | SIMPLE_SYM {} | SHARE_SYM {} | SHUTDOWN {} | SLAVE {} @@ -3259,7 +3295,7 @@ keyword: | USE_FRM {} | VARIABLES {} | WORK_SYM {} - | YEAR_SYM {} + | YEAR_SYM {}; /* Option functions */ @@ -3274,17 +3310,17 @@ set: lex->option_type=0; lex->option_list.empty(); } - option_value_list + option_value_list; opt_option: /* empty */ {} - | OPTION {} + | OPTION {}; option_value_list: option_value | GLOBAL_SYM { Lex->option_type=1; } option_value | LOCAL_SYM { Lex->option_type=0; } option_value - | option_value_list ',' option_value + | option_value_list ',' option_value; option_value: set_option equal NUM @@ -3410,13 +3446,13 @@ option_value: push_back(new Set_option(thd->lex.option_type, $1.str,$1.length, item)); - } + }; query_cache_type: NUM { current_thd->query_cache_type = set_zone(atoi($1.str),0,3); } | OFF { current_thd->query_cache_type = 0; } | ON { current_thd->query_cache_type = 1; } - | DEMAND_SYM { current_thd->query_cache_type = 2; } + | DEMAND_SYM { current_thd->query_cache_type = 2; }; text_or_password: TEXT_STRING { $$=$1.str;} @@ -3430,7 +3466,7 @@ text_or_password: make_scrambled_password(buff,$3.str); $$=buff; } - } + }; set_option: SQL_BIG_TABLES { $$= OPTION_BIG_TABLES; } @@ -3453,7 +3489,7 @@ set_option: | SQL_AUTO_IS_NULL { $$= OPTION_AUTO_IS_NULL; } | SQL_SAFE_UPDATES { $$= OPTION_SAFE_UPDATES; } | SQL_BUFFER_RESULT { $$= OPTION_BUFFER_RESULT; } - | SQL_QUOTE_SHOW_CREATE { $$= OPTION_QUOTE_SHOW_CREATE; } + | SQL_QUOTE_SHOW_CREATE { $$= OPTION_QUOTE_SHOW_CREATE; }; set_isolation: @@ -3470,16 +3506,16 @@ set_isolation: lex->thd->session_tx_isolation= lex->tx_isolation= $2; } | tx_isolation - { Lex->tx_isolation= $1; } + { Lex->tx_isolation= $1; }; tx_isolation: - TRANSACTION_SYM ISOLATION LEVEL_SYM isolation_types { $$=$4; } + TRANSACTION_SYM ISOLATION LEVEL_SYM isolation_types { $$=$4; }; isolation_types: READ_SYM UNCOMMITTED_SYM { $$= ISO_READ_UNCOMMITTED; } | READ_SYM COMMITTED_SYM { $$= ISO_READ_COMMITTED; } | REPEATABLE_SYM READ_SYM { $$= ISO_REPEATABLE_READ; } - | SERIALIZABLE_SYM { $$= ISO_SERIALIZABLE; } + | SERIALIZABLE_SYM { $$= ISO_SERIALIZABLE; }; /* Lock function */ @@ -3488,28 +3524,28 @@ lock: { Lex->sql_command=SQLCOM_LOCK_TABLES; } - table_lock_list + table_lock_list; table_or_tables: TABLE_SYM - | TABLES + | TABLES; table_lock_list: table_lock - | table_lock_list ',' table_lock + | table_lock_list ',' table_lock; table_lock: table_ident opt_table_alias lock_option - { if (!add_table_to_list($1,$2,0,(thr_lock_type) $3)) YYABORT; } + { if (!add_table_to_list($1,$2,0,(thr_lock_type) $3)) YYABORT; }; lock_option: READ_SYM { $$=TL_READ_NO_INSERT; } | WRITE_SYM { $$=current_thd->update_lock_default; } | LOW_PRIORITY WRITE_SYM { $$=TL_WRITE_LOW_PRIORITY; } - | READ_SYM LOCAL_SYM { $$= TL_READ; } + | READ_SYM LOCAL_SYM { $$= TL_READ; }; unlock: - UNLOCK_SYM table_or_tables { Lex->sql_command=SQLCOM_UNLOCK_TABLES; } + UNLOCK_SYM table_or_tables { Lex->sql_command=SQLCOM_UNLOCK_TABLES; }; /* @@ -3539,15 +3575,15 @@ handler: if (!add_table_to_list($2,0,0)) YYABORT; } - handler_read_or_scan where_clause limit_clause { } + handler_read_or_scan where_clause limit_clause { }; handler_read_or_scan: handler_scan_function { Lex->backup_dir= 0; } - | ident handler_rkey_function { Lex->backup_dir= $1.str; } + | ident handler_rkey_function { Lex->backup_dir= $1.str; }; handler_scan_function: FIRST_SYM { Lex->ha_read_mode = RFIRST; } - | NEXT_SYM { Lex->ha_read_mode = RNEXT; } + | NEXT_SYM { Lex->ha_read_mode = RNEXT; }; handler_rkey_function: FIRST_SYM { Lex->ha_read_mode = RFIRST; } @@ -3561,14 +3597,14 @@ handler_rkey_function: lex->ha_rkey_mode=$1; if (!(lex->insert_list = new List_item)) YYABORT; - } '(' values ')' { } + } '(' values ')' { }; handler_rkey_mode: EQ { $$=HA_READ_KEY_EXACT; } | GE { $$=HA_READ_KEY_OR_NEXT; } | LE { $$=HA_READ_KEY_OR_PREV; } | GT_SYM { $$=HA_READ_AFTER_KEY; } - | LT { $$=HA_READ_BEFORE_KEY; } + | LT { $$=HA_READ_BEFORE_KEY; }; /* GRANT / REVOKE */ @@ -3582,7 +3618,7 @@ revoke: lex->grant= lex->grant_tot_col=0; lex->select->db=0; } - grant_privileges ON opt_table FROM user_list + grant_privileges ON opt_table FROM user_list; grant: GRANT @@ -3595,19 +3631,19 @@ grant: lex->select->db=0; lex->ssl_type=SSL_TYPE_NONE; lex->ssl_cipher=lex->x509_subject=lex->x509_issuer=0; - lex->mqh=0; + bzero(&(lex->mqh),sizeof(lex->mqh)); } grant_privileges ON opt_table TO_SYM user_list - require_clause grant_options + require_clause grant_options; grant_privileges: grant_privilege_list {} | ALL PRIVILEGES { Lex->grant = UINT_MAX;} - | ALL { Lex->grant = UINT_MAX;} + | ALL { Lex->grant = UINT_MAX;}; grant_privilege_list: grant_privilege - | grant_privilege_list ',' grant_privilege + | grant_privilege_list ',' grant_privilege; grant_privilege: SELECT_SYM @@ -3630,10 +3666,10 @@ grant_privilege: | SHUTDOWN { Lex->grant |= SHUTDOWN_ACL;} | PROCESS { Lex->grant |= PROCESS_ACL;} | FILE_SYM { Lex->grant |= FILE_ACL;} - | GRANT OPTION { Lex->grant |= GRANT_ACL;} + | GRANT OPTION { Lex->grant |= GRANT_ACL;}; require_list: require_list_element AND require_list -| require_list_element +| require_list_element ; require_list_element: SUBJECT_SYM TEXT_STRING { @@ -3660,11 +3696,11 @@ require_list_element: SUBJECT_SYM TEXT_STRING LEX *lex=Lex; if (lex->ssl_cipher) { - net_printf(&lex->thd->net,ER_DUP_ARGUMENT, "CHIPER"); + net_printf(&lex->thd->net,ER_DUP_ARGUMENT, "CIPHER"); YYABORT; } lex->ssl_cipher=$2.str; - } + }; opt_table: '*' @@ -3710,12 +3746,12 @@ opt_table: YYABORT; if (lex->grant == UINT_MAX) lex->grant = TABLE_ACLS & ~GRANT_ACL; - } + }; user_list: grant_user { if (Lex->users_list.push_back($1)) YYABORT;} - | user_list ',' grant_user { if (Lex->users_list.push_back($3)) YYABORT;} + | user_list ',' grant_user { if (Lex->users_list.push_back($3)) YYABORT;}; grant_user: @@ -3736,7 +3772,7 @@ grant_user: | user IDENTIFIED_SYM BY PASSWORD TEXT_STRING { $$=$1; $1->password=$5 ; } | user - { $$=$1; $1->password.str=NullS; } + { $$=$1; $1->password.str=NullS; }; opt_column_list: @@ -3745,11 +3781,11 @@ opt_column_list: LEX *lex=Lex; lex->grant |= lex->which_columns; } - | '(' column_list ')' + | '(' column_list ')'; column_list: column_list ',' column_list_id - | column_list_id + | column_list_id; column_list_id: ident @@ -3769,7 +3805,7 @@ column_list_id: point->rights |= lex->which_columns; else lex->columns.push_back(new LEX_COLUMN (*new_str,lex->which_columns)); - } + }; require_clause: /* empty */ @@ -3784,35 +3820,43 @@ require_clause: /* empty */ | REQUIRE_SYM X509_SYM { Lex->ssl_type=SSL_TYPE_X509; - } + }; grant_options: /* empty */ {} - | WITH grant_option_list + | WITH grant_option_list; grant_option_list: grant_option_list grant_option {} - | grant_option {} + | grant_option {}; grant_option: GRANT OPTION { Lex->grant |= GRANT_ACL;} - | MAX_QUERIES_PER_HOUR EQ NUM + | MAX_QUERIES_PER_HOUR EQ ULONG_NUM + { + Lex->mqh.questions=$3; + } + | MAX_UPDATES_PER_HOUR EQ ULONG_NUM { - Lex->mqh=atoi($3.str); + Lex->mqh.updates=$3; + } + | MAX_CONNECTIONS_PER_HOUR EQ ULONG_NUM + { + Lex->mqh.connections=$3; } begin: - BEGIN_SYM { Lex->sql_command = SQLCOM_BEGIN;} opt_work + BEGIN_SYM { Lex->sql_command = SQLCOM_BEGIN;} opt_work; opt_work: /* empty */ {} - | WORK_SYM {} + | WORK_SYM {}; commit: - COMMIT_SYM { Lex->sql_command = SQLCOM_COMMIT;} + COMMIT_SYM { Lex->sql_command = SQLCOM_COMMIT;}; rollback: - ROLLBACK_SYM { Lex->sql_command = SQLCOM_ROLLBACK;} + ROLLBACK_SYM { Lex->sql_command = SQLCOM_ROLLBACK;}; /* @@ -3822,7 +3866,7 @@ rollback: union: /* empty */ {} - | union_list + | union_list; union_list: UNION_SYM union_option @@ -3838,14 +3882,14 @@ union_list: YYABORT; lex->select->linkage=UNION_TYPE; } - select_init + select_init; union_opt: union {} - | optional_order_or_limit {} + | optional_order_or_limit {}; optional_order_or_limit: - /* emty */ {} + /* empty */ {} | { LEX *lex=Lex; @@ -3855,8 +3899,10 @@ optional_order_or_limit: lex->select->linkage=NOT_A_SELECT; lex->select->select_limit=lex->thd->default_select_limit; } - opt_order_clause limit_clause + opt_order_clause limit_clause; union_option: /* empty */ {} - | ALL {Lex->union_option=1;} + | ALL {Lex->union_option=1;}; + + diff --git a/sql/structs.h b/sql/structs.h index 2250ea784f2..75280b34715 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -162,13 +162,16 @@ typedef struct st_lex_user { } LEX_USER; +typedef struct user_resources { + uint questions, updates, connections; +} USER_RESOURCES; + typedef struct user_conn { - char *user; - uint len, connections, questions, max_questions; + char *user, *host; + uint len, connections, conn_per_hour, updates, questions, user_len; + USER_RESOURCES user_resources; time_t intime; -} UC; - - +} USER_CONN; /* Bits in form->update */ #define REG_MAKE_DUPP 1 /* Make a copy of record when read */ #define REG_NEW_RECORD 2 /* Write a new record if not found */ diff --git a/sql/table.cc b/sql/table.cc index 05a5c5e6bd2..201b67032bf 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -47,19 +47,19 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, int j,error; uint rec_buff_length,n_length,int_length,records,key_parts,keys, interval_count,interval_parts,read_length,db_create_options; - uint key_info_length; + uint key_info_length, com_length; ulong pos; - char index_file[FN_REFLEN], *names,*keynames; + char index_file[FN_REFLEN], *names, *keynames, *comment_pos; uchar head[288],*disk_buff,new_field_pack_flag; my_string record; const char **int_array; - bool new_frm_ver,use_hash, null_field_first; + bool use_hash, null_field_first; File file; Field **field_ptr,*reg_field; KEY *keyinfo; KEY_PART_INFO *key_part; uchar *null_pos; - uint null_bit; + uint null_bit, new_frm_ver, field_pack_length; SQL_CRYPT *crypted=0; DBUG_ENTER("openfrm"); DBUG_PRINT("enter",("name: '%s' form: %lx",name,outparam)); @@ -95,10 +95,11 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, if (my_read(file,(byte*) head,64,MYF(MY_NABP))) goto err_not_open; if (head[0] != (uchar) 254 || head[1] != 1 || - (head[2] != FRM_VER && head[2] != FRM_VER+1)) + (head[2] < FRM_VER && head[2] > FRM_VER+2)) goto err_not_open; /* purecov: inspected */ new_field_pack_flag=head[27]; - new_frm_ver= (head[2] == FRM_VER+1); + new_frm_ver= (head[2] - FRM_VER); + field_pack_length= new_frm_ver < 2 ? 11 : 15; error=3; if (!(pos=get_form_pos(file,head,(TYPELIB*) 0))) @@ -116,6 +117,8 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, outparam->raid_type= head[41]; outparam->raid_chunks= head[42]; outparam->raid_chunksize= uint4korr(head+43); + if (!(outparam->table_charset=get_charset((uint) head[38],MYF(0)))) + outparam->table_charset=default_charset_info; null_field_first=1; } outparam->db_record_offset=1; @@ -153,10 +156,22 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, for (i=0 ; i < keys ; i++, keyinfo++) { - keyinfo->flags= ((uint) strpos[0]) ^ HA_NOSAME; - keyinfo->key_length= (uint) uint2korr(strpos+1); - keyinfo->key_parts= (uint) strpos[3]; - strpos+=4; + if (new_frm_ver == 2) + { + keyinfo->flags= (uint) uint2korr(strpos) ^ HA_NOSAME; + keyinfo->key_length= (uint) uint2korr(strpos+2); + keyinfo->key_parts= (uint) strpos[4]; + keyinfo->algorithm= (enum ha_key_alg) strpos[5]; + strpos+=8; + } + else + { + keyinfo->flags= ((uint) strpos[0]) ^ HA_NOSAME; + keyinfo->key_length= (uint) uint2korr(strpos+1); + keyinfo->key_parts= (uint) strpos[3]; + keyinfo->algorithm= HA_KEY_ALG_UNDEF; + strpos+=4; + } keyinfo->key_part= key_part; keyinfo->rec_per_key= rec_per_key; @@ -167,7 +182,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, key_part->offset= (uint) uint2korr(strpos+2)-1; key_part->key_type= (uint) uint2korr(strpos+5); // key_part->field= (Field*) 0; // Will be fixed later - if (new_frm_ver) + if (new_frm_ver >= 1) { key_part->key_part_flag= *(strpos+4); key_part->length= (uint) uint2korr(strpos+7); @@ -193,26 +208,6 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, } keynames=(char*) key_part; strpos+= (strmov(keynames, (char *) strpos) - keynames)+1; - /* Test if new 4.0 format */ - if ((uint) (strpos - disk_buff) < key_info_length) - { - /* Read key types */ - keyinfo=outparam->key_info; - for (i=0 ; i < keys ; i++, keyinfo++) - { - keyinfo->algorithm= (enum ha_key_alg) *(strpos++); - /* Temporary fix to get spatial index to work */ - if (keyinfo->algorithm == HA_KEY_ALG_RTREE) - keyinfo->flags|= HA_SPATIAL; - } - } - else - { - /* Set key types to BTREE, BAR TODO: how to be with HASH/RBTREE? */ - keyinfo=outparam->key_info; - for (i=0 ; i < keys ; i++, keyinfo++) - keyinfo->algorithm= HA_KEY_ALG_BTREE; - } outparam->reclength = uint2korr((head+16)); if (*(head+26) == 1) outparam->system=1; /* one-record-database */ @@ -280,10 +275,11 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, interval_parts=uint2korr(head+272); int_length=uint2korr(head+274); outparam->null_fields=uint2korr(head+282); + com_length=uint2korr(head+284); outparam->comment=strdup_root(&outparam->mem_root, (char*) head+47); - DBUG_PRINT("info",("i_count: %d i_parts: %d index: %d n_length: %d int_length: %d", interval_count,interval_parts, outparam->keys,n_length,int_length)); + DBUG_PRINT("info",("i_count: %d i_parts: %d index: %d n_length: %d int_length: %d com_length: %d", interval_count,interval_parts, outparam->keys,n_length,int_length, com_length)); if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root, @@ -291,12 +287,12 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, interval_count*sizeof(TYPELIB)+ (outparam->fields+interval_parts+ keys+3)*sizeof(my_string)+ - (n_length+int_length))))) + (n_length+int_length+com_length))))) goto err_not_open; /* purecov: inspected */ outparam->field=field_ptr; - read_length=((uint) (outparam->fields*11)+pos+ - (uint) (n_length+int_length)); + read_length=(uint) (outparam->fields * field_pack_length + + pos+ (uint) (n_length+int_length+com_length)); if (read_string(file,(gptr*) &disk_buff,read_length)) goto err_not_open; /* purecov: inspected */ if (crypted) @@ -312,8 +308,10 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, names= (char*) (int_array+outparam->fields+interval_parts+keys+3); if (!interval_count) outparam->intervals=0; // For better debugging - memcpy((char*) names, strpos+(outparam->fields*11), + memcpy((char*) names, strpos+(outparam->fields*field_pack_length), (uint) (n_length+int_length)); + comment_pos=names+(n_length+int_length); + memcpy(comment_pos, disk_buff+read_length-com_length, com_length); fix_type_pointers(&int_array,&outparam->fieldnames,1,&names); fix_type_pointers(&int_array,outparam->intervals,interval_count, @@ -346,43 +344,55 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, (hash_get_key) get_field_name,0, HASH_CASE_INSENSITIVE); -// BAR: dirty hack while waiting for new FRM -// BAR: take a charset information from table name -{ - const char* csname=strstr(alias,"_cs_"); - if(!csname || - !(outparam->table_charset=get_charset_by_name(csname+4,MYF(MY_WME)))) - outparam->table_charset=default_charset_info; -} - - for (i=0 ; i < outparam->fields; i++, strpos+= 11, field_ptr++) + for (i=0 ; i < outparam->fields; i++, strpos+=field_pack_length, field_ptr++) { uint pack_flag= uint2korr(strpos+6); uint interval_nr= (uint) strpos[10]; + enum_field_types field_type; + CHARSET_INFO *charset; + LEX_STRING comment; + if (new_frm_ver == 2) + { + /* new frm file in 4.1 */ + uint comment_length=uint2korr(strpos+13); + field_type=(enum_field_types) (uint) strpos[11]; + if (!(charset=get_charset((uint) strpos[12], MYF(0)))) + charset=outparam->table_charset; + if (!comment_length) + { + comment.str= (char*) ""; + comment.length=0; + } + else + { + comment.str= (char*) comment_pos; + comment.length= comment_length; + comment_pos+= comment_length; + } + } + else + { + /* old frm file */ + field_type= (enum_field_types) f_packtype(pack_flag); + charset=outparam->table_charset; + bzero((char*) &comment, sizeof(comment)); + } *field_ptr=reg_field= make_field(record+uint2korr(strpos+4), (uint32) strpos[3], // field_length null_pos,null_bit, pack_flag, + field_type, (Field::utype) MTYP_TYPENR((uint) strpos[8]), (interval_nr ? outparam->intervals+interval_nr-1 : (TYPELIB*) 0), outparam->fieldnames.type_names[i], outparam); + reg_field->comment=comment; if (!reg_field->binary()) - { - // BAR: dirty hack while waiting for new FRM - // BAR: take a charset information from field name - - Field_str* str_field=(Field_str*)reg_field; - const char* csname=strstr(str_field->field_name,"_cs_"); - CHARSET_INFO *fcs; - if (!csname || (!(fcs=get_charset_by_name(csname+4,MYF(MY_WME))))) - fcs=outparam->table_charset; - str_field->set_charset(fcs); - } + ((Field_str*) reg_field)->set_charset(charset); if (!(reg_field->flags & NOT_NULL_FLAG)) { if ((null_bit<<=1) == 256) @@ -480,13 +490,13 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, keyinfo->key_length ? UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG); if (i == 0) field->key_start|= ((key_map) 1 << key); - if ((ha_option & HA_HAVE_KEY_READ_ONLY) && - field->key_length() == key_part->length && + if (field->key_length() == key_part->length && field->type() != FIELD_TYPE_BLOB) { - if (field->key_type() != HA_KEYTYPE_TEXT || - (!(ha_option & HA_KEY_READ_WRONG_STR) && - !(keyinfo->flags & HA_FULLTEXT))) + if ((ha_option & HA_HAVE_KEY_READ_ONLY) && + (field->key_type() != HA_KEYTYPE_TEXT || + (!(ha_option & HA_KEY_READ_WRONG_STR) && + !(keyinfo->flags & HA_FULLTEXT)))) field->part_of_key|= ((key_map) 1 << key); if ((field->key_type() != HA_KEYTYPE_TEXT || !(keyinfo->flags & HA_FULLTEXT)) && @@ -956,9 +966,14 @@ ulong next_io_size(register ulong pos) } /* next_io_size */ -void append_unescaped(String *res,const char *pos) + /* Store in String an SQL quoted string */ + +void append_unescaped(String *res,const char *pos, uint length) { - for ( ; *pos ; pos++) + const char *end= pos+length; + res->append('\''); + + for (; pos != end ; pos++) { switch (*pos) { case 0: /* Must be escaped for 'mysql' */ @@ -986,6 +1001,7 @@ void append_unescaped(String *res,const char *pos) break; } } + res->append('\''); } /* Create a .frm file */ @@ -1009,7 +1025,7 @@ File create_frm(register my_string name, uint reclength, uchar *fileinfo, if ((file=my_create(name,CREATE_MODE,O_RDWR | O_TRUNC,MYF(MY_WME))) >= 0) { bzero((char*) fileinfo,64); - fileinfo[0]=(uchar) 254; fileinfo[1]= 1; fileinfo[2]= FRM_VER+1; // Header + fileinfo[0]=(uchar) 254; fileinfo[1]= 1; fileinfo[2]= FRM_VER+2; // Header fileinfo[3]= (uchar) ha_checktype(create_info->db_type); fileinfo[4]=1; int2store(fileinfo+6,IO_SIZE); /* Next block starts here */ @@ -1025,6 +1041,7 @@ File create_frm(register my_string name, uint reclength, uchar *fileinfo, int2store(fileinfo+30,create_info->table_options); fileinfo[32]=0; // No filename anymore int4store(fileinfo+34,create_info->avg_row_length); + fileinfo[38]= create_info->table_charset->number; fileinfo[40]= (uchar) create_info->row_type; fileinfo[41]= (uchar) create_info->raid_type; fileinfo[42]= (uchar) create_info->raid_chunks; @@ -1184,7 +1201,7 @@ db_type get_table_type(const char *name) error=my_read(file,(byte*) head,4,MYF(MY_NABP)); my_close(file,MYF(0)); if (error || head[0] != (uchar) 254 || head[1] != 1 || - (head[2] != FRM_VER && head[2] != FRM_VER+1)) + (head[2] < FRM_VER && head[2] > FRM_VER+2)) DBUG_RETURN(DB_TYPE_UNKNOWN); DBUG_RETURN(ha_checktype((enum db_type) (uint) *(head+3))); } diff --git a/sql/uniques.cc b/sql/uniques.cc index 6b05618bcc7..3a26f610dc5 100644 --- a/sql/uniques.cc +++ b/sql/uniques.cc @@ -55,7 +55,7 @@ Unique::Unique(qsort_cmp2 comp_func, void * comp_func_fixed_arg, my_b_clear(&file); init_tree(&tree, max_in_memory_size / 16, 0, size, comp_func, 0, NULL, comp_func_fixed_arg); /* If the following fail's the next add will also fail */ - init_dynamic_array(&file_ptrs, sizeof(BUFFPEK), 16, 16); + my_init_dynamic_array(&file_ptrs, sizeof(BUFFPEK), 16, 16); max_elements= max_in_memory_size / ALIGN_SIZE(sizeof(TREE_ELEMENT)+size); open_cached_file(&file, mysql_tmpdir,TEMP_PREFIX, DISK_BUFFER_SIZE, MYF(MY_WME)); diff --git a/sql/unireg.cc b/sql/unireg.cc index 16f51658313..863f71d1cce 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -28,7 +28,7 @@ #include "mysql_priv.h" #include <m_ctype.h> -#define FCOMP 11 /* Byte per packat f{lt */ +#define FCOMP 15 /* Bytes for a packed field */ static uchar * pack_screens(List<create_field> &create_fields, uint *info_length, uint *screens, bool small_file); @@ -246,7 +246,7 @@ static uchar * pack_screens(List<create_field> &create_fields, static uint pack_keys(uchar *keybuff,uint key_count,KEY *keyinfo) { uint key_parts,length; - uchar *pos, *keyname_pos, *key_alg_pos; + uchar *pos, *keyname_pos; KEY *key,*end; KEY_PART_INFO *key_part,*key_part_end; DBUG_ENTER("pack_keys"); @@ -255,10 +255,12 @@ static uint pack_keys(uchar *keybuff,uint key_count,KEY *keyinfo) key_parts=0; for (key=keyinfo,end=keyinfo+key_count ; key != end ; key++) { - pos[0]=(uchar) (key->flags ^ HA_NOSAME); - int2store(pos+1,key->key_length); - pos[3]=key->key_parts; - pos+=4; + int2store(pos, (key->flags ^ HA_NOSAME)); + int2store(pos+2,key->key_length); + pos[4]= (uchar) key->key_parts; + pos[5]= (uchar) key->algorithm; + pos[6]=pos[7]=0; // For the future + pos+=8; key_parts+=key->key_parts; DBUG_PRINT("loop",("flags: %d key_parts: %d at %lx", key->flags,key->key_parts, @@ -290,18 +292,11 @@ static uint pack_keys(uchar *keybuff,uint key_count,KEY *keyinfo) } *(pos++)=0; - /* For MySQL 4.0; Store key algoritms last */ - key_alg_pos= pos; - for (key=keyinfo ; key != end ; key++) - { - *(pos++)= (uchar) key->algorithm; - } - keybuff[0]=(uchar) key_count; keybuff[1]=(uchar) key_parts; length=(uint) (keyname_pos-keybuff); int2store(keybuff+2,length); - length=(uint) (key_alg_pos-keyname_pos); + length=(uint) (pos-keyname_pos); int2store(keybuff+4,length); DBUG_RETURN((uint) (pos-keybuff)); } /* pack_keys */ @@ -314,9 +309,9 @@ static bool pack_header(uchar *forminfo, enum db_type table_type, uint info_length, uint screens,uint table_options, handler *file) { - uint length,int_count,int_length,no_empty, int_parts, - time_stamp_pos,null_fields; - ulong reclength,totlength,n_length; + uint length,int_count,int_length,no_empty, int_parts; + uint time_stamp_pos,null_fields; + ulong reclength, totlength, n_length, com_length; DBUG_ENTER("pack_header"); if (create_fields.elements > MAX_FIELDS) @@ -326,7 +321,8 @@ static bool pack_header(uchar *forminfo, enum db_type table_type, } totlength=reclength=0L; - no_empty=int_count=int_parts=int_length=time_stamp_pos=null_fields=0; + no_empty=int_count=int_parts=int_length=time_stamp_pos=null_fields= + com_length=0; n_length=2L; /* Check fields */ @@ -336,6 +332,7 @@ static bool pack_header(uchar *forminfo, enum db_type table_type, while ((field=it++)) { totlength+= field->length; + com_length+= field->comment.length; if (MTYP_TYPENR(field->unireg_check) == Field::NOEMPTY || field->unireg_check & MTYP_NOEMPTY_BIT) { @@ -378,14 +375,15 @@ static bool pack_header(uchar *forminfo, enum db_type table_type, /* Hack to avoid bugs with small static rows in MySQL */ reclength=max(file->min_record_length(table_options),reclength); if (info_length+(ulong) create_fields.elements*FCOMP+288+ - n_length+int_length > 65535L || int_count > 255) + n_length+int_length+com_length > 65535L || int_count > 255) { my_error(ER_TOO_MANY_FIELDS,MYF(0)); DBUG_RETURN(1); } bzero((char*)forminfo,288); - length=info_length+create_fields.elements*FCOMP+288+n_length+int_length; + length=(info_length+create_fields.elements*FCOMP+288+n_length+int_length+ + com_length); int2store(forminfo,length); forminfo[256] = (uint8) screens; int2store(forminfo+258,create_fields.elements); @@ -401,6 +399,7 @@ static bool pack_header(uchar *forminfo, enum db_type table_type, int2store(forminfo+278,80); /* Columns needed */ int2store(forminfo+280,22); /* Rows needed */ int2store(forminfo+282,null_fields); + int2store(forminfo+284,com_length); DBUG_RETURN(0); } /* pack_header */ @@ -438,7 +437,7 @@ static uint get_interval_id(uint *int_count,List<create_field> &create_fields, static bool pack_fields(File file,List<create_field> &create_fields) { reg2 uint i; - uint int_count; + uint int_count, comment_length=0; uchar buff[MAX_FIELD_WIDTH]; create_field *field; DBUG_ENTER("pack_fields"); @@ -459,6 +458,11 @@ static bool pack_fields(File file,List<create_field> &create_fields) int2store(buff+6,field->pack_flag); int2store(buff+8,field->unireg_check); buff[10]= (uchar) field->interval_id; + buff[11]= (uchar) field->sql_type; + buff[12]= (uchar) (field->charset ? field->charset->number : + default_charset_info->number); + int2store(buff+13, field->comment.length); + comment_length+= field->comment.length; set_if_bigger(int_count,field->interval_id); if (my_write(file,(byte*) buff,FCOMP,MYF_RW)) DBUG_RETURN(1); @@ -505,6 +509,18 @@ static bool pack_fields(File file,List<create_field> &create_fields) if (my_write(file,(byte*) tmp.ptr(),tmp.length(),MYF_RW)) DBUG_RETURN(1); } + if (comment_length) + { + it.rewind(); + int_count=0; + while ((field=it++)) + { + if (field->comment.length) + if (my_write(file, (byte*) field->comment.str, field->comment.length, + MYF_RW)) + DBUG_RETURN(1); + } + } DBUG_RETURN(0); } @@ -557,6 +573,7 @@ static bool make_empty_rec(File file,enum db_type table_type, null_pos+null_count/8, 1 << (null_count & 7), field->pack_flag, + field->sql_type, field->unireg_check, field->interval, field->field_name, diff --git a/sql/unireg.h b/sql/unireg.h index c4d2052d1da..5a61f4a6c12 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -122,6 +122,13 @@ bfill((A)->null_flags,(A)->null_bytes,255);\ #define TE_INFO_LENGTH 3 #define MTYP_NOEMPTY_BIT 128 +/* + * Minimum length pattern before Turbo Boyer-Moore is used + * for SELECT "text" LIKE "%pattern%", excluding the two + * wildcards in class Item_func_like. + */ +#define MIN_TURBOBM_PATTERN_LEN 3 + /* Include prototypes for unireg */ #include "mysqld_error.h" |