diff options
author | unknown <serg@sergbook.mysql.com> | 2002-06-24 22:22:23 +0200 |
---|---|---|
committer | unknown <serg@sergbook.mysql.com> | 2002-06-24 22:22:23 +0200 |
commit | 2a32642d8fc8e335016a5c9bc99b82065428645a (patch) | |
tree | 7f06ba416159bfa8afd984ae6219679f24a657f3 | |
parent | 1a64790587b8a6080c2a051cae220c4176229823 (diff) | |
parent | bb016624066bab60edf07feeaf855dab1353e6e4 (diff) | |
download | mariadb-git-2a32642d8fc8e335016a5c9bc99b82065428645a.tar.gz |
post-merge fix
-rw-r--r-- | Docs/manual.texi | 9 | ||||
-rw-r--r-- | configure.in | 2 | ||||
-rw-r--r-- | include/Makefile.am | 6 | ||||
-rw-r--r-- | include/getopt.h | 151 | ||||
-rw-r--r-- | myisam/myisamchk.c | 6 | ||||
-rw-r--r-- | mysql-test/r/type_decimal.result | 40 | ||||
-rw-r--r-- | mysql-test/t/type_decimal.test | 8 | ||||
-rw-r--r-- | mysys/sha1.c | 20 | ||||
-rw-r--r-- | sql/field.cc | 443 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 2 | ||||
-rw-r--r-- | sql/slave.cc | 1 |
11 files changed, 384 insertions, 304 deletions
diff --git a/Docs/manual.texi b/Docs/manual.texi index 0db844a6f9f..d658f20ea67 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -33003,11 +33003,10 @@ As AES is a block level algorithm, padding is used to encode uneven length strings and so the result string length may be calculated as 16*(trunc(string_length/16)+1). -@c FIX arjen 2002-06-21 Peter: this sentence makes no sense at all! -If the string has an incorrect length or contains invalid data for this -key, @code{AES_DECRYPT()} will return @code{NULL}, therefore you can't -rely on this to much, @code{AES_DECRYPT()} has some change to return -a non-@code{NULL} value even for an invalid key. +If @code{AES_DECRYPT()} detects invalid data or incorrect padding, it +will return @code{NULL}. However, it is possible for @code{AES_DECRYPT()} +to return a non-@code{NULL} value (possibly garbage) if the input data or +the key was invalid. You can use the AES functions to store data in an encrypted form by modifying your queries: diff --git a/configure.in b/configure.in index 45e38db7f37..58ce6331209 100644 --- a/configure.in +++ b/configure.in @@ -925,7 +925,7 @@ case $SYSTEM_TYPE in *darwin*) if test "$ac_cv_prog_gcc" = "yes" then - CFLAGS="$CFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ" + CFLAGS="$CFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DHAVE_BROKEN_REALPATH" CXXFLAGS="$CXXFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ" MAX_C_OPTIMIZE="-O" with_named_curses="" diff --git a/include/Makefile.am b/include/Makefile.am index 24d81739af3..0f135c64b53 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -26,9 +26,9 @@ noinst_HEADERS = config-win.h \ nisam.h heap.h merge.h my_bitmap.h\ myisam.h myisampack.h myisammrg.h ft_global.h\ my_dir.h mysys_err.h my_base.h \ - my_nosys.h my_alarm.h queues.h \ - my_tree.h hash.h thr_alarm.h thr_lock.h \ - t_ctype.h violite.h md5.h mysql_version.h.in + my_nosys.h my_alarm.h queues.h rijndael.h sha1.h \ + my_aes.h my_getopt.h my_tree.h hash.h thr_alarm.h \ + thr_lock.h t_ctype.h violite.h md5.h mysql_version.h.in # mysql_version.h are generated SUPERCLEANFILES = mysql_version.h my_config.h diff --git a/include/getopt.h b/include/getopt.h deleted file mode 100644 index 94e73c03ff3..00000000000 --- a/include/getopt.h +++ /dev/null @@ -1,151 +0,0 @@ -/* Copyright (C) 2000 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Declarations for getopt. - Copyright (C) 1989, 90, 91, 92, 93, 94 Free Software Foundation, Inc. - -This file is part of the GNU C Library. Its master source is NOT part of -the C library, however. The master source lives in /gd/gnu/lib. - -The GNU C Library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -The GNU C Library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with the GNU C Library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. */ - -#ifndef _GETOPT_H -#define _GETOPT_H 1 - -#ifdef __cplusplus -extern "C" { -#endif - -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -extern char *optarg; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns EOF, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -extern int optind; - -/* Callers store zero here to inhibit the error message `getopt' prints - for unrecognized options. */ - -extern int opterr; - -/* Set to an option character which was unrecognized. */ - -extern int optopt; - -/* Describe the long-named options requested by the application. - The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector - of `struct option' terminated by an element containing a name which is - zero. - - The field `has_arg' is: - no_argument (or 0) if the option does not take an argument, - required_argument (or 1) if the option requires an argument, - optional_argument (or 2) if the option takes an optional argument. - - If the field `flag' is not NULL, it points to a variable that is set - to the value given in the field `val' when the option is found, but - left unchanged if the option is not found. - - To have a long-named option do something other than set an `int' to - a compiled-in constant, such as set a value from `optarg', set the - option's `flag' field to zero and its `val' field to a nonzero - value (the equivalent single-letter option character, if there is - one). For long options that have a zero `flag' field, `getopt' - returns the contents of the `val' field. */ - -struct option -{ -#if defined (__STDC__) && __STDC__ || defined(__cplusplus) - const char *name; -#else - char *name; -#endif - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; -}; - -/* Names for the values of the `has_arg' field of `struct option'. */ - -#define no_argument 0 -#define required_argument 1 -#define optional_argument 2 - -#if ( defined (__STDC__) && __STDC__ ) || defined(__cplusplus) || defined(MSDOS) -#ifdef __EMX__ -int getopt (int, char **, __const__ char *); -#elif defined( __GNU_LIBRARY__) -/* Many other libraries have conflicting prototypes for getopt, with - differences in the consts, in stdlib.h. To avoid compilation - errors, only prototype getopt for the GNU C library. */ -extern int getopt (int argc, char *const *argv, const char *shortopts); -#else /* not __GNU_LIBRARY__ */ -extern int getopt (int argc, char *const *argv, const char *optstring); -#endif /* __GNU_LIBRARY__ */ -extern int getopt_long (int argc, char *const *argv, const char *shortopts, - const struct option *longopts, int *longind); -extern int getopt_long_only (int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind); - -/* Internal only. Users should not call this directly. */ -extern int _getopt_internal (int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind, - int long_only); -#else /* not __STDC__ */ -extern int getopt (); -extern int getopt_long (); -extern int getopt_long_only (); - -extern int _getopt_internal (); -#endif /* __STDC__ */ - -#ifdef __cplusplus -} -#endif - -#endif /* _GETOPT_H */ diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c index 05939710e89..6f12ce1536b 100644 --- a/myisam/myisamchk.c +++ b/myisam/myisamchk.c @@ -258,7 +258,7 @@ static struct my_option my_long_options[] = "Unpack file packed with myisampack.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"verbose", 'v', - "Print more information. This can be used with --describe and --check. Use many -v for more verbosity!", + "Print more information. This can be used with --description and --check. Use many -v for more verbosity!", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"version", 'V', "Print version and exit.", @@ -331,7 +331,7 @@ static void usage(void) -s, --silent Only print errors. One can use two -s to make\n\ myisamchk very silent\n\ -v, --verbose Print more information. This can be used with\n\ - --describe and --check. Use many -v for more verbosity!\n\ + --description and --check. Use many -v for more verbosity!\n\ -V, --version Print version and exit.\n\ -w, --wait Wait if table is locked.\n"); @@ -384,7 +384,7 @@ static void usage(void) puts("Other actions:\n\ -a, --analyze Analyze distribution of keys. Will make some joins in\n\ MySQL faster. You can check the calculated distribution\n\ - by using '--describe --verbose table_name'.\n\ + by using '--description --verbose table_name'.\n\ -d, --description Prints some information about table.\n\ -A, --set-auto-increment[=value]\n\ Force auto_increment to start at this or higher value\n\ diff --git a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result index f4dfc3c2891..5623482aa7f 100644 --- a/mysql-test/r/type_decimal.result +++ b/mysql-test/r/type_decimal.result @@ -156,6 +156,8 @@ insert into t1 values ("-.1"),("+.1"),(".1"); insert into t1 values ("00000000000001"),("+0000000000001"),("-0000000000001"); insert into t1 values ("+111111111.11"),("111111111.11"),("-11111111.11"); insert into t1 values ("-111111111.11"),("+1111111111.11"),("1111111111.11"); +insert into t1 values ("1e+1000"),("1e-1000"),("-1e+1000"); +insert into t1 values ("123.4e"),("123.4e+2"),("123.4e-2"),("123e1"),("123e+0"); select * from t1; a 0.00 @@ -176,6 +178,14 @@ a -99999999.99 999999999.99 999999999.99 +999999999.99 +0.00 +-99999999.99 +123.40 +12340.00 +1.23 +1230.00 +123.00 drop table t1; create table t1 (a decimal(10,2) unsigned); insert into t1 values ("0.0"),("-0.0"),("+0.0"),("01.0"),("+01.0"),("-01.0"); @@ -183,6 +193,8 @@ insert into t1 values ("-.1"),("+.1"),(".1"); insert into t1 values ("00000000000001"),("+0000000000001"),("-0000000000001"); insert into t1 values ("+111111111.11"),("111111111.11"),("-11111111.11"); insert into t1 values ("-111111111.11"),("+1111111111.11"),("1111111111.11"); +insert into t1 values ("1e+1000"),("1e-1000"),("-1e+1000"); +insert into t1 values ("123.4e"),("123.4e+2"),("123.4e-2"),("123e1"),("123e+0"); select * from t1; a 0.00 @@ -203,6 +215,14 @@ a 0.00 99999999.99 99999999.99 +99999999.99 +0.00 +0.00 +123.40 +12340.00 +1.23 +1230.00 +123.00 drop table t1; create table t1 (a decimal(10,2) zerofill); insert into t1 values ("0.0"),("-0.0"),("+0.0"),("01.0"),("+01.0"),("-01.0"); @@ -210,6 +230,8 @@ insert into t1 values ("-.1"),("+.1"),(".1"); insert into t1 values ("00000000000001"),("+0000000000001"),("-0000000000001"); insert into t1 values ("+111111111.11"),("111111111.11"),("-11111111.11"); insert into t1 values ("-111111111.11"),("+1111111111.11"),("1111111111.11"); +insert into t1 values ("1e+1000"),("1e-1000"),("-1e+1000"); +insert into t1 values ("123.4e"),("123.4e+2"),("123.4e-2"),("123e1"),("123e+0"); select * from t1; a 00000000.00 @@ -230,6 +252,14 @@ a 00000000.00 99999999.99 99999999.99 +99999999.99 +00000000.00 +00000000.00 +00000123.40 +00012340.00 +00000001.23 +00001230.00 +00000123.00 drop table t1; create table t1 (a decimal(10,2)); insert into t1 values (0.0),("-0.0"),(+0.0),(01.0),(+01.0),(-01.0); @@ -237,6 +267,8 @@ insert into t1 values (-.1),(+.1),(.1); insert into t1 values (00000000000001),(+0000000000001),(-0000000000001); insert into t1 values (+111111111.11),(111111111.11),(-11111111.11); insert into t1 values (-111111111.11),(+1111111111.11),(1111111111.11); +insert into t1 values (1e+1000),(1e-1000),(-1e+1000); +insert into t1 values (123.4e0),(123.4e+2),(123.4e-2),(123e1),(123e+0); select * from t1; a 0.00 @@ -257,6 +289,14 @@ a -99999999.99 999999999.99 999999999.99 +999999999.99 +0.00 +-99999999.99 +123.40 +12340.00 +1.23 +1230.00 +123.00 drop table t1; create table t1 (a decimal); insert into t1 values (-99999999999999),(-1),('+1'),('01'),('+00000000000001'),('+12345678901'),(99999999999999); diff --git a/mysql-test/t/type_decimal.test b/mysql-test/t/type_decimal.test index 21e06c0dbe9..683ed7239e6 100644 --- a/mysql-test/t/type_decimal.test +++ b/mysql-test/t/type_decimal.test @@ -160,6 +160,8 @@ insert into t1 values ("-.1"),("+.1"),(".1"); insert into t1 values ("00000000000001"),("+0000000000001"),("-0000000000001"); insert into t1 values ("+111111111.11"),("111111111.11"),("-11111111.11"); insert into t1 values ("-111111111.11"),("+1111111111.11"),("1111111111.11"); +insert into t1 values ("1e+1000"),("1e-1000"),("-1e+1000"); +insert into t1 values ("123.4e"),("123.4e+2"),("123.4e-2"),("123e1"),("123e+0"); select * from t1; drop table t1; @@ -169,6 +171,8 @@ insert into t1 values ("-.1"),("+.1"),(".1"); insert into t1 values ("00000000000001"),("+0000000000001"),("-0000000000001"); insert into t1 values ("+111111111.11"),("111111111.11"),("-11111111.11"); insert into t1 values ("-111111111.11"),("+1111111111.11"),("1111111111.11"); +insert into t1 values ("1e+1000"),("1e-1000"),("-1e+1000"); +insert into t1 values ("123.4e"),("123.4e+2"),("123.4e-2"),("123e1"),("123e+0"); select * from t1; drop table t1; @@ -178,6 +182,8 @@ insert into t1 values ("-.1"),("+.1"),(".1"); insert into t1 values ("00000000000001"),("+0000000000001"),("-0000000000001"); insert into t1 values ("+111111111.11"),("111111111.11"),("-11111111.11"); insert into t1 values ("-111111111.11"),("+1111111111.11"),("1111111111.11"); +insert into t1 values ("1e+1000"),("1e-1000"),("-1e+1000"); +insert into t1 values ("123.4e"),("123.4e+2"),("123.4e-2"),("123e1"),("123e+0"); select * from t1; drop table t1; @@ -189,6 +195,8 @@ insert into t1 values (-.1),(+.1),(.1); insert into t1 values (00000000000001),(+0000000000001),(-0000000000001); insert into t1 values (+111111111.11),(111111111.11),(-11111111.11); insert into t1 values (-111111111.11),(+1111111111.11),(1111111111.11); +insert into t1 values (1e+1000),(1e-1000),(-1e+1000); +insert into t1 values (123.4e0),(123.4e+2),(123.4e-2),(123e1),(123e+0); select * from t1; drop table t1; diff --git a/mysys/sha1.c b/mysys/sha1.c index 3b4bac84d08..5271b369b6c 100644 --- a/mysys/sha1.c +++ b/mysys/sha1.c @@ -155,8 +155,8 @@ int sha1_result(SHA1_CONTEXT *context, } for (i = 0; i < SHA1_HASH_SIZE; i++) - Message_Digest[i] = (context->Intermediate_Hash[i>>2] >> 8 - * ( 3 - ( i & 0x03 ) )); + Message_Digest[i] = (int8)((context->Intermediate_Hash[i>>2] >> 8 + * ( 3 - ( i & 0x03 ) ))); return SHA_SUCCESS; } @@ -379,14 +379,14 @@ void SHA1PadMessage(SHA1_CONTEXT *context) Store the message length as the last 8 octets */ - context->Message_Block[56] = context->Length >> 56; - context->Message_Block[57] = context->Length >> 48; - context->Message_Block[58] = context->Length >> 40; - context->Message_Block[59] = context->Length >> 32; - context->Message_Block[60] = context->Length >> 24; - context->Message_Block[61] = context->Length >> 16; - context->Message_Block[62] = context->Length >> 8; - context->Message_Block[63] = context->Length; + context->Message_Block[56] = (int8) (context->Length >> 56); + context->Message_Block[57] = (int8) (context->Length >> 48); + context->Message_Block[58] = (int8) (context->Length >> 40); + context->Message_Block[59] = (int8) (context->Length >> 32); + context->Message_Block[60] = (int8) (context->Length >> 24); + context->Message_Block[61] = (int8) (context->Length >> 16); + context->Message_Block[62] = (int8) (context->Length >> 8); + context->Message_Block[63] = (int8) (context->Length); SHA1ProcessMessageBlock(context); } diff --git a/sql/field.cc b/sql/field.cc index 3c45d22135a..21b967e60a9 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -42,7 +42,7 @@ #endif /***************************************************************************** -** Instansiate templates and static variables + Instansiate templates and static variables *****************************************************************************/ #ifdef __GNUC__ @@ -50,69 +50,13 @@ template class List<create_field>; template class List_iterator<create_field>; #endif -struct st_decstr { - uint nr_length,nr_dec,sign,extra; - char sign_char; -}; - uchar Field_null::null[1]={1}; const char field_separator=','; /***************************************************************************** -** Static help functions + Static help functions *****************************************************************************/ - /* - Calculate length of number and its parts - Increment cuted_fields if wrong number - */ - -static bool -number_dec(struct st_decstr *sdec, const char *str, const char *end) -{ - sdec->sign=sdec->extra=0; - if (str == end) - { - current_thd->cuted_fields++; - sdec->nr_length=sdec->nr_dec=sdec->sign=0; - sdec->extra=1; // We must put one 0 before . - return 1; - } - - if (*str == '-' || *str == '+') /* sign */ - { - sdec->sign_char= *str; - sdec->sign=1; - str++; - } - const char *start=str; - while (str != end && isdigit(*str)) - str++; - if (!(sdec->nr_length=(uint) (str-start))) - sdec->extra=1; // We must put one 0 before . - start=str; - if (str != end && *str == '.') - { - str++; - start=str; - while (str != end && isdigit(*str)) - str++; - } - sdec->nr_dec=(uint) (str-start); - if (current_thd->count_cuted_fields) - { - while (str != end && isspace(*str)) - str++; /* purecov: inspected */ - if (str != end) - { - current_thd->cuted_fields++; - return 1; - } - } - return 0; -} - - void Field_num::prepend_zeros(String *value) { int diff; @@ -127,8 +71,8 @@ void Field_num::prepend_zeros(String *value) } /* -** Test if given number is a int (or a fixed format float with .000) -** This is only used to give warnings in ALTER TABLE or LOAD DATA... + Test if given number is a int (or a fixed format float with .000) + This is only used to give warnings in ALTER TABLE or LOAD DATA... */ bool test_if_int(const char *str,int length) @@ -417,99 +361,332 @@ void Field_decimal::overflow(bool negative) void Field_decimal::store(const char *from,uint len) { - reg3 int i; - uint tmp_dec; - char fyllchar; - const char *end=from+len; - struct st_decstr decstr; - bool error; + const char *end= from+len; + /* The pointer where the field value starts (i.e., "where to write") */ + char *to=ptr; + uint tmp_dec, tmp_uint; + /* + The sign of the number : will be 0 (means positive but sign not + specified), '+' or '-' + */ + char sign_char=0; + /* The pointers where prezeros start and stop */ + const char *pre_zeros_from, *pre_zeros_end; + /* The pointers where digits at the left of '.' start and stop */ + const char *int_digits_from, *int_digits_end; + /* The pointers where digits at the right of '.' start and stop */ + const char *frac_digits_from, *frac_digits_end; + /* The sign of the exponent : will be 0 (means no exponent), '+' or '-' */ + char expo_sign_char=0; + uint exponent=0; // value of the exponent + /* + Pointers used when digits move from the left of the '.' to the + right of the '.' (explained below) + */ + const char *int_digits_tail_from; + /* Number of 0 that need to be added at the left of the '.' (1E3: 3 zeros) */ + uint int_digits_added_zeros; + /* + Pointer used when digits move from the right of the '.' to the left + of the '.' + */ + const char *frac_digits_head_end; + /* Number of 0 that need to be added at the right of the '.' (for 1E-3) */ + uint frac_digits_added_zeros; + char *pos,*tmp_left_pos,*tmp_right_pos; + /* Pointers that are used as limits (begin and end of the field buffer) */ + char *left_wall,*right_wall; + char tmp_char; + /* + To remember if current_thd->cuted_fields has already been incremented, + to do that only once + */ + bool is_cuted_fields_incr=0; + + LINT_INIT(int_digits_tail_from); + LINT_INIT(int_digits_added_zeros); + LINT_INIT(frac_digits_head_end); + LINT_INIT(frac_digits_added_zeros); + + /* + There are three steps in this function : + - parse the input string + - modify the position of digits around the decimal dot '.' + according to the exponent value (if specified) + - write the formatted number + */ + + if ((tmp_dec=dec)) + tmp_dec++; - if ((tmp_dec= dec)) - tmp_dec++; // Calculate pos of '.' - while (from != end && isspace(*from)) + for (; from!=end && isspace(*from); from++) ; // Read spaces + if (from == end) + { + current_thd->cuted_fields++; + is_cuted_fields_incr=1; + } + else if (*from == '+' || *from == '-') // Found some sign ? + { + sign_char= *from++; + /* + Unsigned can't have any flag. So we'll just drop "+" + and will overflow on "-" + */ + if (unsigned_flag) + { + if (sign_char=='-') + { + current_thd->cuted_fields++; + Field_decimal::overflow(1); + return; + } + else + sign_char=0; + } + + } + pre_zeros_from= from; + for (; from!=end && *from == '0'; from++) ; // Read prezeros + pre_zeros_end=int_digits_from=from; + /* Read non zero digits at the left of '.'*/ + for (; from!=end && isdigit(*from);from++) ; + int_digits_end=from; + if (from!=end && *from == '.') // Some '.' ? from++; - if (zerofill) + frac_digits_from= from; + /* Read digits at the right of '.' */ + for (;from!=end && isdigit(*from); from++) ; + frac_digits_end=from; + // Some exponentiation symbol ? + if (from != end && (*from == 'e' || *from == 'E')) + { + from++; + if (from != end && (*from == '+' || *from == '-')) // Some exponent sign ? + expo_sign_char= *from++; + else + expo_sign_char= '+'; + /* + Read digits of the exponent and compute its value + 'exponent' overflow (e.g. if 1E10000000000000000) is not a problem + (the value of the field will be overflow anyway, or 0 anyway, + it does not change anything if the exponent is 2^32 or more + */ + for (;from!=end && isdigit(*from); from++) + exponent=10*exponent+(*from-'0'); + } + + /* + We only have to generate warnings if count_cuted_fields is set. + This is to avoid extra checks of the number when they are not needed. + Even if this flag is not set, it's ok to increment warnings, if + it makes the code easer to read. + */ + + if (current_thd->count_cuted_fields) { - fyllchar = '0'; - if (from != end) - while (*from == '0' && from != end-1) // Skip prezero - from++; + for (;from!=end && isspace(*from); from++) ; // Read end spaces + if (from != end) // If still something left, warn + { + current_thd->cuted_fields++; + is_cuted_fields_incr=1; + } } - else - fyllchar=' '; - error=number_dec(&decstr,from,end); - if (decstr.sign) - { - from++; - if (unsigned_flag) // No sign with zerofill + + /* + Now "move" digits around the decimal dot according to the exponent value, + and add necessary zeros. + Examples : + - 1E+3 : needs 3 more zeros at the left of '.' (int_digits_added_zeros=3) + - 1E-3 : '1' moves at the right of '.', and 2 more zeros are needed + between '.' and '1' + - 1234.5E-3 : '234' moves at the right of '.' + These moves are implemented with pointers which point at the begin + and end of each moved segment. Examples : + - 1234.5E-3 : before the code below is executed, the int_digits part is + from '1' to '4' and the frac_digits part from '5' to '5'. After the code + below, the int_digits part is from '1' to '1', the frac_digits_head + part is from '2' to '4', and the frac_digits part from '5' to '5'. + - 1234.5E3 : before the code below is executed, the int_digits part is + from '1' to '4' and the frac_digits part from '5' to '5'. After the code + below, the int_digits part is from '1' to '4', the int_digits_tail + part is from '5' to '5', the frac_digits part is empty, and + int_digits_added_zeros=2 (to make 1234500). + */ + + if (!expo_sign_char) + tmp_uint=tmp_dec+(uint)(int_digits_end-int_digits_from); + else if (expo_sign_char == '-') + { + tmp_uint=min(exponent,(uint)(int_digits_end-int_digits_from)); + frac_digits_added_zeros=exponent-tmp_uint; + int_digits_end -= tmp_uint; + frac_digits_head_end=int_digits_end+tmp_uint; + tmp_uint=tmp_dec+(uint)(int_digits_end-int_digits_from); + } + else // (expo_sign_char=='+') + { + tmp_uint=min(exponent,(uint)(frac_digits_end-frac_digits_from)); + int_digits_added_zeros=exponent-tmp_uint; + int_digits_tail_from=frac_digits_from; + frac_digits_from=frac_digits_from+tmp_uint; + /* + We "eat" the heading zeros of the + int_digits.int_digits_tail.int_digits_added_zeros concatenation + (for example 0.003e3 must become 3 and not 0003) + */ + if (int_digits_from == int_digits_end) { - if (decstr.sign_char == '+') // just remove "+" - decstr.sign= 0; - else + /* + There was nothing in the int_digits part, so continue + eating int_digits_tail zeros + */ + for (; int_digits_tail_from != frac_digits_from && + *int_digits_tail_from == '0'; int_digits_tail_from++) ; + if (int_digits_tail_from == frac_digits_from) { - if (!error) - current_thd->cuted_fields++; - Field_decimal::overflow(1); - return; + // there were only zeros in int_digits_tail too + int_digits_added_zeros=0; } } + tmp_uint=(tmp_dec+(uint)(int_digits_end-int_digits_from) + +(uint)(frac_digits_from-int_digits_tail_from)+ + int_digits_added_zeros); } + /* - ** Remove pre-zeros if too big number + Now write the formated number + + First the digits of the int_% parts. + Do we have enough room to write these digits ? + If the sign is defined and '-', we need one position for it */ - for (i= (int) (decstr.nr_length+decstr.extra -(field_length-tmp_dec)+ - decstr.sign) ; - i > 0 ; - i--) + + if (field_length < tmp_uint + (int) (sign_char == '-')) { - if (*from == '0') - { - from++; - decstr.nr_length--; - continue; - } - if (decstr.sign && decstr.sign_char == '+' && i == 1) - { // Remove pre '+' - decstr.sign=0; - break; - } current_thd->cuted_fields++; // too big number, change to max or min number - Field_decimal::overflow(decstr.sign && decstr.sign_char == '-'); + Field_decimal::overflow(sign_char == '-'); return; } - char *to=ptr; - for (i=(int) (field_length-tmp_dec-decstr.nr_length-decstr.extra - decstr.sign) ; - i-- > 0 ;) - *to++ = fyllchar; - if (decstr.sign) - *to++= decstr.sign_char; - if (decstr.extra) - *to++ = '0'; - for (i=(int) decstr.nr_length ; i-- > 0 ; ) - *to++ = *from++; - if (tmp_dec--) - { - *to++ ='.'; - if (decstr.nr_dec) from++; // Skip '.' - for (i=(int) min(decstr.nr_dec,tmp_dec) ; i-- > 0 ; ) *to++ = *from++; - for (i=(int) (tmp_dec-min(decstr.nr_dec,tmp_dec)) ; i-- > 0 ; ) *to++ = '0'; + + /* + Tmp_left_pos is the position where the leftmost digit of + the int_% parts will be written + */ + tmp_left_pos=pos=to+(uint)(field_length-tmp_uint); + + // Write all digits of the int_% parts + while (int_digits_from != int_digits_end) + *pos++ = *int_digits_from++ ; + + if (expo_sign_char == '+') + { + while (int_digits_tail_from != frac_digits_from) + *pos++= *int_digits_tail_from++; + while (int_digits_added_zeros-- >0) + *pos++= '0'; } + /* + Note the position where the rightmost digit of the int_% parts has been + written (this is to later check if the int_% parts contained nothing, + meaning an extra 0 is needed). + */ + tmp_right_pos=pos; /* - ** Check for incorrect string if in batch mode (ALTER TABLE/LOAD DATA...) + Step back to the position of the leftmost digit of the int_% parts, + to write sign and fill with zeros or blanks or prezeros. */ - if (!error && current_thd->count_cuted_fields && from != end) - { // Check if number was cuted - for (; from != end ; from++) + pos=tmp_left_pos-1; + if (zerofill) + { + left_wall=to-1; + while (pos != left_wall) // Fill with zeros + *pos--='0'; + } + else + { + left_wall=to+(sign_char!=0)-1; + if (!expo_sign_char) // If exponent was specified, ignore prezeros + { + for (;pos != left_wall && pre_zeros_from !=pre_zeros_end; + pre_zeros_from++) + *pos--= '0'; + } + if (pos == tmp_right_pos-1) + *pos--= '0'; // no 0 has ever been written, so write one + left_wall= to-1; + if (sign_char && pos != left_wall) { - if (*from != '0') + /* Write sign if possible (it is if sign is '-') */ + *pos--= sign_char; + } + while (pos != left_wall) + *pos--=' '; //fill with blanks + } + + if (tmp_dec) // This field has decimals + { + /* + Write digits of the frac_% parts ; + Depending on current_thd->count_cutted_fields, we may also want + to know if some non-zero tail of these parts will + be truncated (for example, 0.002->0.00 will generate a warning, + while 0.000->0.00 will not) + (and 0E1000000000 will not, while 1E-1000000000 will) + */ + + pos=to+(uint)(field_length-tmp_dec); // Calculate post to '.' + *pos++='.'; + right_wall=to+field_length; + + if (expo_sign_char == '-') + { + while (frac_digits_added_zeros-- > 0) { - if (!isspace(*from)) // Space is ok - current_thd->cuted_fields++; - break; + if (pos == right_wall) + { + if (current_thd->count_cuted_fields && !is_cuted_fields_incr) + break; // Go on below to see if we lose non zero digits + return; + } + *pos++='0'; + } + while (int_digits_end != frac_digits_head_end) + { + tmp_char= *int_digits_end++; + if (pos == right_wall) + { + if (tmp_char != '0') // Losing a non zero digit ? + { + if (current_thd->count_cuted_fields && !is_cuted_fields_incr) + current_thd->cuted_fields++; + return; + } + continue; + } + *pos++= tmp_char; + } + } + + for (;frac_digits_from!=frac_digits_end;) + { + tmp_char= *frac_digits_from++; + if (pos == right_wall) + { + if (tmp_char != '0') // Losing a non zero digit ? + { + if (!is_cuted_fields_incr) + current_thd->cuted_fields++; + return; + } + continue; } + *pos++= tmp_char; } + + while (pos != right_wall) + *pos++='0'; // Fill with zeros at right of '.' } } @@ -522,6 +699,14 @@ void Field_decimal::store(double nr) current_thd->cuted_fields++; return; } + + if (isinf(nr)) // Handle infinity as special case + { + overflow(nr < 0.0); + current_thd->cuted_fields++; + return; + } + reg4 uint i,length; char fyllchar,*to; char buff[320]; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index dfb53a32910..f692ebc31ed 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -109,7 +109,7 @@ String *Item_func_sha::val_str(String *str) { SHA1_CONTEXT context; /* Context used to generate SHA1 hash */ /* Temporary buffer to store 160bit digest */ - uint8_t digest[SHA1_HASH_SIZE]; + uint8 digest[SHA1_HASH_SIZE]; sha1_reset(&context); /* We do not have to check for error here */ /* No need to check error as the only case would be too long message */ sha1_input(&context,(const unsigned char *) sptr->ptr(), sptr->length()); diff --git a/sql/slave.cc b/sql/slave.cc index 7791e4151ee..6f173ba5cd8 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1194,7 +1194,6 @@ int init_master_info(MASTER_INFO* mi, const char* master_info_fname, int fd,error; MY_STAT stat_area; char fname[FN_REFLEN+128]; - const char *msg; DBUG_ENTER("init_master_info"); if (mi->inited) |