summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <serg@sergbook.mysql.com>2002-06-24 22:22:23 +0200
committerunknown <serg@sergbook.mysql.com>2002-06-24 22:22:23 +0200
commit2a32642d8fc8e335016a5c9bc99b82065428645a (patch)
tree7f06ba416159bfa8afd984ae6219679f24a657f3
parent1a64790587b8a6080c2a051cae220c4176229823 (diff)
parentbb016624066bab60edf07feeaf855dab1353e6e4 (diff)
downloadmariadb-git-2a32642d8fc8e335016a5c9bc99b82065428645a.tar.gz
post-merge fix
-rw-r--r--Docs/manual.texi9
-rw-r--r--configure.in2
-rw-r--r--include/Makefile.am6
-rw-r--r--include/getopt.h151
-rw-r--r--myisam/myisamchk.c6
-rw-r--r--mysql-test/r/type_decimal.result40
-rw-r--r--mysql-test/t/type_decimal.test8
-rw-r--r--mysys/sha1.c20
-rw-r--r--sql/field.cc443
-rw-r--r--sql/item_strfunc.cc2
-rw-r--r--sql/slave.cc1
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)