diff options
author | unknown <serg@sergbook.mysql.com> | 2007-04-16 10:37:50 +0200 |
---|---|---|
committer | unknown <serg@sergbook.mysql.com> | 2007-04-16 10:37:50 +0200 |
commit | 7cb8a33b1af33dcd8806ec6021655a39f375d904 (patch) | |
tree | df4c92bcf5668ec88685604378ad6dc60bfcf269 /mysys | |
parent | 2e73a53e033741b09a652646d9cfa0e76c33e6a1 (diff) | |
parent | add378761542ade65340b9477ed298e9a1677b10 (diff) | |
download | mariadb-git-7cb8a33b1af33dcd8806ec6021655a39f375d904.tar.gz |
Merge bk-internal.mysql.com:/home/bk/mysql-5.1
into sergbook.mysql.com:/usr/home/serg/Abk/mysql-5.1-wl2936
client/mysql.cc:
Auto merged
include/my_global.h:
Auto merged
include/my_sys.h:
Auto merged
include/mysql.h:
Auto merged
mysql-test/r/im_utils.result:
Auto merged
mysql-test/r/variables.result:
Auto merged
mysql-test/t/ndb_dd_basic.test:
Auto merged
mysql-test/t/partition_innodb.test:
Auto merged
mysql-test/t/variables.test:
Auto merged
mysys/array.c:
Auto merged
mysys/typelib.c:
Auto merged
sql/event_queue.cc:
Auto merged
sql/ha_partition.cc:
Auto merged
sql/ha_partition.h:
Auto merged
sql/handler.cc:
Auto merged
sql/handler.h:
Auto merged
sql/item_func.cc:
Auto merged
sql/item_sum.cc:
Auto merged
sql/log.cc:
Auto merged
sql/mysql_priv.h:
Auto merged
sql/set_var.h:
Auto merged
sql/sql_base.cc:
Auto merged
sql/sql_cache.cc:
Auto merged
sql/sql_class.h:
Auto merged
sql/sql_delete.cc:
Auto merged
sql/sql_insert.cc:
Auto merged
sql/sql_lex.cc:
Auto merged
sql/sql_lex.h:
Auto merged
sql/sql_parse.cc:
Auto merged
sql/sql_partition.cc:
Auto merged
sql/sql_plugin.cc:
Auto merged
sql/sql_repl.cc:
Auto merged
sql/sql_select.cc:
Auto merged
sql/sql_show.cc:
Auto merged
sql/sql_table.cc:
Auto merged
sql/table.cc:
Auto merged
sql/table.h:
Auto merged
storage/example/ha_example.cc:
Auto merged
storage/federated/ha_federated.cc:
Auto merged
storage/heap/ha_heap.cc:
Auto merged
storage/innobase/include/trx0trx.h:
Auto merged
storage/myisam/ha_myisam.cc:
Auto merged
storage/myisammrg/ha_myisammrg.cc:
Auto merged
storage/ndb/src/mgmsrv/InitConfigFileParser.cpp:
Auto merged
include/typelib.h:
merged
mysql-test/mysql-test-run.pl:
merged
mysql-test/r/flush2.result:
merged
mysql-test/r/ndb_dd_basic.result:
merged
mysql-test/r/partition_innodb.result:
merged
mysql-test/r/ps_1general.result:
merged
mysql-test/t/ps_1general.test:
merged
sql/ha_ndbcluster.cc:
merged
sql/item_create.cc:
merged
sql/mysqld.cc:
merged
sql/rpl_utility.h:
merged
sql/set_var.cc:
merged
sql/sql_class.cc:
merged
sql/sql_yacc.yy:
merged
storage/innobase/handler/ha_innodb.cc:
merged
storage/innobase/handler/ha_innodb.h:
merged
Diffstat (limited to 'mysys')
-rw-r--r-- | mysys/array.c | 62 | ||||
-rw-r--r-- | mysys/hash.c | 17 | ||||
-rw-r--r-- | mysys/my_getopt.c | 66 | ||||
-rw-r--r-- | mysys/typelib.c | 55 |
4 files changed, 185 insertions, 15 deletions
diff --git a/mysys/array.c b/mysys/array.c index 60f5b255e18..130a8f358de 100644 --- a/mysys/array.c +++ b/mysys/array.c @@ -22,9 +22,10 @@ Initiate dynamic array SYNOPSIS - init_dynamic_array() + init_dynamic_array2() array Pointer to an array element_size Size of element + init_buffer Initial buffer pointer init_alloc Number of initial elements alloc_increment Increment for adding new elements @@ -32,14 +33,15 @@ init_dynamic_array() initiates array and allocate space for init_alloc eilements. Array is usable even if space allocation failed. + Static buffers must begin immediately after the array structure. RETURN VALUE TRUE my_malloc_ci() failed FALSE Ok */ -my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size, - uint init_alloc, +my_bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint element_size, + void *init_buffer, uint init_alloc, uint alloc_increment CALLER_INFO_PROTO) { DBUG_ENTER("init_dynamic_array"); @@ -51,11 +53,16 @@ my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size, } if (!init_alloc) + { init_alloc=alloc_increment; + init_buffer= 0; + } array->elements=0; array->max_element=init_alloc; array->alloc_increment=alloc_increment; array->size_of_element=element_size; + if ((array->buffer= init_buffer)) + DBUG_RETURN(FALSE); if (!(array->buffer=(char*) my_malloc_ci(element_size*init_alloc,MYF(MY_WME)))) { array->max_element=0; @@ -64,6 +71,14 @@ my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size, DBUG_RETURN(FALSE); } +my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size, + uint init_alloc, + uint alloc_increment CALLER_INFO_PROTO) +{ + /* placeholder to preserve ABI */ + return my_init_dynamic_array_ci(array, element_size, init_alloc, + alloc_increment); +} /* Insert element at the end of array. Allocate memory if needed. @@ -117,6 +132,21 @@ byte *alloc_dynamic(DYNAMIC_ARRAY *array) if (array->elements == array->max_element) { char *new_ptr; + if (array->buffer == (char *)(array + 1)) + { + /* + In this senerio, the buffer is statically preallocated, + so we have to create an all-new malloc since we overflowed + */ + if (!(new_ptr= (char *) my_malloc((array->max_element+ + array->alloc_increment) * + array->size_of_element, + MYF(MY_WME)))) + return 0; + memcpy(new_ptr, array->buffer, + array->elements * array->size_of_element); + } + else if (!(new_ptr=(char*) my_realloc(array->buffer,(array->max_element+ array->alloc_increment)* array->size_of_element, @@ -176,6 +206,20 @@ my_bool set_dynamic(DYNAMIC_ARRAY *array, gptr element, uint idx) char *new_ptr; size=(idx+array->alloc_increment)/array->alloc_increment; size*= array->alloc_increment; + if (array->buffer == (char *)(array + 1)) + { + /* + In this senerio, the buffer is statically preallocated, + so we have to create an all-new malloc since we overflowed + */ + if (!(new_ptr= (char *) my_malloc(size * + array->size_of_element, + MYF(MY_WME)))) + return 0; + memcpy(new_ptr, array->buffer, + array->elements * array->size_of_element); + } + else if (!(new_ptr=(char*) my_realloc(array->buffer,size* array->size_of_element, MYF(MY_WME | MY_ALLOW_ZERO_PTR)))) @@ -226,6 +270,12 @@ void get_dynamic(DYNAMIC_ARRAY *array, gptr element, uint idx) void delete_dynamic(DYNAMIC_ARRAY *array) { + /* + Just mark as empty if we are using a static buffer + */ + if (array->buffer == (char *)(array + 1)) + array->elements= 0; + else if (array->buffer) { my_free(array->buffer,MYF(MY_WME)); @@ -265,6 +315,12 @@ void freeze_size(DYNAMIC_ARRAY *array) { uint elements=max(array->elements,1); + /* + Do nothing if we are using a static buffer + */ + if (array->buffer == (char *)(array + 1)) + return; + if (array->buffer && array->max_element != elements) { array->buffer=(char*) my_realloc(array->buffer, diff --git a/mysys/hash.c b/mysys/hash.c index 60168e01e20..ab875848989 100644 --- a/mysys/hash.c +++ b/mysys/hash.c @@ -315,6 +315,10 @@ my_bool my_hash_insert(HASH *info,const byte *record) LINT_INIT(gpos); LINT_INIT(gpos2); LINT_INIT(ptr_to_rec); LINT_INIT(ptr_to_rec2); + if (HASH_UNIQUE & info->flags && + hash_search(info, hash_key(info, record, &idx, 1), idx)) + return(TRUE); /* Duplicate entry */ + flag=0; if (!(empty=(HASH_LINK*) alloc_dynamic(&info->array))) return(TRUE); /* No more memory */ @@ -530,6 +534,19 @@ my_bool hash_update(HASH *hash,byte *record,byte *old_key,uint old_key_length) uint idx,new_index,new_pos_index,blength,records,empty; HASH_LINK org_link,*data,*previous,*pos; DBUG_ENTER("hash_update"); + + if (HASH_UNIQUE & hash->flags) + { + HASH_SEARCH_STATE state; + byte *found, *new_key= hash_key(hash, record, &idx, 1); + if ((found= hash_first(hash, new_key, idx, &state))) + do + { + if (found != record) + DBUG_RETURN(1); /* Duplicate entry */ + } + while ((found= hash_next(hash, new_key, idx, &state))); + } data=dynamic_element(&hash->array,0,HASH_LINK*); blength=hash->blength; records=hash->records; diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index aa470282aa4..4573d27555a 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -58,6 +58,13 @@ char *disabled_my_option= (char*) "0"; my_bool my_getopt_print_errors= 1; +/* + This is a flag that can be set in client programs. 1 means that + my_getopt will skip over options it does not know how to handle. +*/ + +my_bool my_getopt_skip_unknown= 0; + static void default_reporter(enum loglevel level, const char *format, ...) { @@ -90,18 +97,18 @@ void my_getopt_register_get_addr(gptr* (*func_addr)(const char *, uint, getopt_get_addr= func_addr; } -int handle_options(int *argc, char ***argv, +int handle_options(int *argc, char ***argv, const struct my_option *longopts, my_get_one_option get_one_option) { - uint opt_found, argvpos= 0, length, i; + uint opt_found, argvpos= 0, length; my_bool end_of_options= 0, must_be_var, set_maximum_value, option_is_loose; char **pos, **pos_end, *optend, *prev_found, *opt_str, key_name[FN_REFLEN]; const struct my_option *optp; gptr *value; - int error; + int error, i; LINT_INIT(opt_found); (*argc)--; /* Skip the program name */ @@ -110,6 +117,7 @@ int handle_options(int *argc, char ***argv, for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++) { + char **first= pos; char *cur_arg= *pos; if (cur_arg[0] == '-' && cur_arg[1] && !end_of_options) /* must be opt */ { @@ -216,12 +224,11 @@ int handle_options(int *argc, char ***argv, /* We were called with a special prefix, we can reuse opt_found */ - opt_str+= (special_opt_prefix_lengths[i] + 1); + opt_str+= special_opt_prefix_lengths[i] + 1; + length-= special_opt_prefix_lengths[i] + 1; if (i == OPT_LOOSE) option_is_loose= 1; - if ((opt_found= findopt(opt_str, length - - (special_opt_prefix_lengths[i] + 1), - &optp, &prev_found))) + if ((opt_found= findopt(opt_str, length, &optp, &prev_found))) { if (opt_found > 1) { @@ -245,7 +252,7 @@ int handle_options(int *argc, char ***argv, break; case OPT_ENABLE: optend= (optend && *optend == '0' && !(*(optend + 1))) ? - disabled_my_option : (char*) "1"; + disabled_my_option : (char*) "1"; break; case OPT_MAXIMUM: set_maximum_value= 1; @@ -254,11 +261,25 @@ int handle_options(int *argc, char ***argv, } break; /* break from the inner loop, main loop continues */ } + i= -1; /* restart the loop */ } } } if (!opt_found) { + if (my_getopt_skip_unknown) + { + /* + preserve all the components of this unknown option, this may + occurr when the user provides options like: "-O foo" or + "--set-variable foo" (note that theres a space in there) + Generally, these kind of options are to be avoided + */ + do { + (*argv)[argvpos++]= *first++; + } while (first <= pos); + continue; + } if (must_be_var) { if (my_getopt_print_errors) @@ -596,6 +617,15 @@ static int setval(const struct my_option *opts, gptr *value, char *argument, if (!(*((char**) result_pos)= my_strdup(argument, MYF(MY_WME)))) return EXIT_OUT_OF_MEMORY; break; + case GET_ENUM: + if (((*(int*)result_pos)= find_type(argument, opts->typelib, 2) - 1) < 0) + return EXIT_ARGUMENT_INVALID; + break; + case GET_SET: + *((ulonglong*)result_pos)= find_typeset(argument, opts->typelib, &err); + if (err) + return EXIT_ARGUMENT_INVALID; + break; default: /* dummy default to avoid compiler warnings */ break; } @@ -788,6 +818,7 @@ static void init_one_value(const struct my_option *option, gptr *variable, *((int*) variable)= (int) value; break; case GET_UINT: + case GET_ENUM: *((uint*) variable)= (uint) value; break; case GET_LONG: @@ -800,6 +831,7 @@ static void init_one_value(const struct my_option *option, gptr *variable, *((longlong*) variable)= (longlong) value; break; case GET_ULL: + case GET_SET: *((ulonglong*) variable)= (ulonglong) value; break; default: /* dummy default to avoid compiler warnings */ @@ -928,7 +960,8 @@ void my_print_help(const struct my_option *options) void my_print_variables(const struct my_option *options) { - uint name_space= 34, length; + uint name_space= 34, length, nr; + ulonglong bit, llvalue; char buff[255]; const struct my_option *optp; @@ -946,6 +979,21 @@ void my_print_variables(const struct my_option *options) for (; length < name_space; length++) putchar(' '); switch ((optp->var_type & GET_TYPE_MASK)) { + case GET_SET: + if (!(llvalue= *(ulonglong*) value)) + printf("%s\n", "(No default value)"); + else + for (nr= 0, bit= 1; llvalue && nr < optp->typelib->count; nr++, bit<<=1) + { + if (!(bit & llvalue)) + continue; + llvalue&= ~bit; + printf( llvalue ? "%s," : "%s\n", get_type(optp->typelib, nr)); + } + break; + case GET_ENUM: + printf("%s\n", get_type(optp->typelib, *(uint*) value)); + break; case GET_STR: case GET_STR_ALLOC: /* fall through */ printf("%s\n", *((char**) value) ? *((char**) value) : diff --git a/mysys/typelib.c b/mysys/typelib.c index dc9f0850bbc..8b0b4eb8740 100644 --- a/mysys/typelib.c +++ b/mysys/typelib.c @@ -20,6 +20,8 @@ #include <m_ctype.h> +static const char field_separator=','; + /* Search after a string in a list of strings. Endspace in x is not compared. @@ -31,6 +33,7 @@ If & 1 accept only whole names If & 2 don't expand if half field If & 4 allow #number# as type + If & 8 use ',' as string terminator NOTES If part, uniq field is found and full_name == 0 then x is expanded @@ -60,16 +63,18 @@ int find_type(char *x, const TYPELIB *typelib, uint full_name) for (pos=0 ; (j=typelib->type_names[pos]) ; pos++) { for (i=x ; - *i && my_toupper(&my_charset_latin1,*i) == + *i && (!(full_name & 8) || *i != field_separator) && + my_toupper(&my_charset_latin1,*i) == my_toupper(&my_charset_latin1,*j) ; i++, j++) ; if (! *j) { while (*i == ' ') i++; /* skip_end_space */ - if (! *i) + if (! *i || ((full_name & 8) && *i == field_separator)) DBUG_RETURN(pos+1); } - if (! *i && (!*j || !(full_name & 1))) + if ((!*i && (!(full_name & 8) || *i != field_separator)) && + (!*j || !(full_name & 1))) { find++; findpos=pos; @@ -121,6 +126,50 @@ const char *get_type(TYPELIB *typelib, uint nr) /* + Create an integer value to represent the supplied comma-seperated + string where each string in the TYPELIB denotes a bit position. + + SYNOPSIS + find_typeset() + x string to decompose + lib TYPELIB (struct of pointer to values + count) + err index (not char position) of string element which was not + found or 0 if there was no error + + RETURN + a integer representation of the supplied string +*/ + +my_ulonglong find_typeset(my_string x, TYPELIB *lib, int *err) +{ + my_ulonglong result; + int find; + my_string i; + DBUG_ENTER("find_set"); + DBUG_PRINT("enter",("x: '%s' lib: 0x%lx", x, (long) lib)); + + if (!lib->count) + { + DBUG_PRINT("exit",("no count")); + DBUG_RETURN(0); + } + result= 0; + *err= 0; + while (*x) + { + (*err)++; + i= x; + while (*x && *x != field_separator) x++; + if ((find= find_type(i, lib, 2 | 8) - 1) < 0) + DBUG_RETURN(0); + result|= (ULL(1) << find); + } + *err= 0; + DBUG_RETURN(result); +} /* find_set */ + + +/* Create a copy of a specified TYPELIB structure. SYNOPSIS |