summaryrefslogtreecommitdiff
path: root/mysys
diff options
context:
space:
mode:
authorunknown <serg@sergbook.mysql.com>2007-04-16 10:37:50 +0200
committerunknown <serg@sergbook.mysql.com>2007-04-16 10:37:50 +0200
commit7cb8a33b1af33dcd8806ec6021655a39f375d904 (patch)
treedf4c92bcf5668ec88685604378ad6dc60bfcf269 /mysys
parent2e73a53e033741b09a652646d9cfa0e76c33e6a1 (diff)
parentadd378761542ade65340b9477ed298e9a1677b10 (diff)
downloadmariadb-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.c62
-rw-r--r--mysys/hash.c17
-rw-r--r--mysys/my_getopt.c66
-rw-r--r--mysys/typelib.c55
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